Fixed enum printing for negative enums. There previously was no testing to validate that enum values were being displayed correctly.

Also added C++11 enum test cases to cover enums as int8_t, int16_t int32_t, int64_t, uint8_t, uint16_t, uint32_t, and uint64_t both for DWARF and dSYM cases. The DWARF being emitted by clang is missing the enum integer type, but the code is now ready to accept and deal with the integral type if it is supplied.

llvm-svn: 176548
This commit is contained in:
Greg Clayton 2013-03-06 06:23:54 +00:00
parent 95d2eb95c3
commit 5d14fc061f
8 changed files with 281 additions and 22 deletions

View File

@ -6049,9 +6049,18 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
clang_type = m_forward_decl_die_to_clang_type.lookup (die);
if (clang_type == NULL)
{
enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
DW_ATE_signed,
byte_size * 8);
if (encoding_uid != DW_INVALID_OFFSET)
{
Type *enumerator_type = ResolveTypeUID(encoding_uid);
if (enumerator_type)
enumerator_clang_type = enumerator_type->GetClangFullType();
}
if (enumerator_clang_type == NULL)
enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
DW_ATE_signed,
byte_size * 8);
clang_type = ast.CreateEnumerationType (type_name_cstr,
GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
decl,
@ -6060,7 +6069,6 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
else
{
enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
assert (enumerator_clang_type != NULL);
}
LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
@ -6081,7 +6089,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
{
SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
bool is_signed = false;
ast.IsIntegerType(clang_type, is_signed);
ast.IsIntegerType(enumerator_clang_type, is_signed);
ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
}
ast.CompleteTagDeclarationDefinition (clang_type);

View File

@ -1037,20 +1037,38 @@ ClangASTType::DumpTypeValue (clang::ASTContext *ast_context,
const clang::EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
lldb::offset_t offset = byte_offset;
const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
if (is_signed)
{
if (enum_pos->getInitVal() == enum_value)
const int64_t enum_svalue = data.GetMaxS64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
s->PutCString (enum_pos->getNameAsString().c_str());
return true;
if (enum_pos->getInitVal().getSExtValue() == enum_svalue)
{
s->PutCString (enum_pos->getNameAsString().c_str());
return true;
}
}
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
s->Printf("%" PRIi64, enum_svalue);
}
else
{
const uint64_t enum_uvalue = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
if (enum_pos->getInitVal().getZExtValue() == enum_uvalue)
{
s->PutCString (enum_pos->getNameAsString().c_str());
return true;
}
}
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
s->Printf("%" PRIu64, enum_uvalue);
}
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
s->Printf("%" PRIi64, enum_value);
return true;
}
// format was not enum, just fall through and dump the value as requested....

View File

@ -13,7 +13,7 @@ class EnumTypesTestCase(TestBase):
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym(self):
"""Test 'image lookup -t days' and check for correct display."""
"""Test 'image lookup -t days' and check for correct display and enum value printing."""
self.buildDsym()
self.image_lookup_for_enum_type()
@ -21,7 +21,7 @@ class EnumTypesTestCase(TestBase):
# 'image lookup -t days' returns nothing with dwarf debug format.
@dwarf_test
def test_with_dwarf(self):
"""Test 'image lookup -t days' and check for correct display."""
"""Test 'image lookup -t days' and check for correct display and enum value printing."""
self.buildDwarf()
self.image_lookup_for_enum_type()
@ -37,7 +37,7 @@ class EnumTypesTestCase(TestBase):
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Break inside the main.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
@ -54,17 +54,32 @@ class EnumTypesTestCase(TestBase):
# Check for correct display.
self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY,
substrs = ['enum days {',
'Monday,',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday,',
'Sunday',
'kNumDays',
'}'])
enum_values = [ '-4',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
'kNumDays',
'5'];
bkpt = self.target().FindBreakpointByID(bkpt_id)
for enum_value in enum_values:
self.expect("frame variable day", 'check for valid enumeration value',
substrs = [enum_value])
lldbutil.continue_to_breakpoint (self.process(), bkpt)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()

View File

@ -11,7 +11,7 @@
int main (int argc, char const *argv[])
{
enum days {
Monday = 10,
Monday = -3,
Tuesday,
Wednesday,
Thursday,

View File

@ -0,0 +1,9 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
clean: OBJECTS+=$(wildcard main.d.*)
include $(LEVEL)/Makefile.rules
CXXFLAGS += -std=c++11

View File

@ -0,0 +1,176 @@
"""Look up enum type information and check for correct display."""
import os, time
import unittest2
import lldb
from lldbtest import *
import lldbutil
class CPP11EnumTypesTestCase(TestBase):
mydir = os.path.join("lang", "cpp", "enum_types")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_int8_t(self):
"""Test C++11 enumeration class types as int8_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int8_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_int16_t(self):
"""Test C++11 enumeration class types as int16_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int16_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_int32_t(self):
"""Test C++11 enumeration class types as int32_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int32_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_int64_t(self):
"""Test C++11 enumeration class types as int64_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int64_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_uint8_t(self):
"""Test C++11 enumeration class types as uint8_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint8_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_uint16_t(self):
"""Test C++11 enumeration class types as uint16_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint16_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_uint32_t(self):
"""Test C++11 enumeration class types as uint32_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint32_t"'})
self.image_lookup_for_enum_type()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_uint64_t(self):
"""Test C++11 enumeration class types as uint64_t types."""
self.buildDsym(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint64_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_int8_t(self):
"""Test C++11 enumeration class types as int8_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int8_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_int16_t(self):
"""Test C++11 enumeration class types as int16_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int16_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_int32_t(self):
"""Test C++11 enumeration class types as int32_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int32_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_int64_t(self):
"""Test C++11 enumeration class types as int64_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=int64_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_uint8_t(self):
"""Test C++11 enumeration class types as uint8_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint8_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_uint16_t(self):
"""Test C++11 enumeration class types as uint16_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint16_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_uint32_t(self):
"""Test C++11 enumeration class types as uint32_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint32_t"'})
self.image_lookup_for_enum_type()
@dwarf_test
def test_with_dwarf_uint64_t(self):
"""Test C++11 enumeration class types as uint64_t types."""
self.buildDwarf(dictionary={'CFLAGS_EXTRAS': '"-DTEST_BLOCK_CAPTURED_VARS=uint64_t"'})
self.image_lookup_for_enum_type()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.cpp', '// Set break point at this line.')
def image_lookup_for_enum_type(self):
"""Test C++11 enumeration class types."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Break inside the main.
bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped',
'stop reason = breakpoint'])
# The breakpoint should have a hit count of 1.
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs = [' resolved, hit count = 1'])
# Look up information about the 'DayType' enum type.
# Check for correct display.
self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY,
substrs = ['enum DayType {',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
'kNumDays',
'}'])
enum_values = [ '-4',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
'kNumDays',
'5'];
bkpt = self.target().FindBreakpointByID(bkpt_id)
for enum_value in enum_values:
self.expect("frame variable day", 'check for valid enumeration value',
substrs = [enum_value])
lldbutil.continue_to_breakpoint (self.process(), bkpt)
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,33 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <stdint.h>
int main (int argc, char const *argv[])
{
typedef int16_t enum_integer_t;
enum class DayType : enum_integer_t {
Monday = -3,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
kNumDays
};
enum_integer_t day_value;
for (day_value = (enum_integer_t)DayType::Monday - 1; day_value <= (enum_integer_t)DayType::kNumDays + 1; ++day_value)
{
DayType day = (DayType)day_value;
printf("day as int is %i\n", (int)day); // Set break point at this line.
}
return 0;
}

View File

@ -2,6 +2,6 @@ LEVEL = ../../../make
CXX_SOURCES := main.cpp
CXXFLAGS = -std=c++11
include $(LEVEL)/Makefile.rules
CXXFLAGS += -std=c++11