[Lldb-commits] [lldb] r176548 - Fixed enum printing for negative enums. There previously was no testing to validate that enum values were being displayed correctly.

Greg Clayton gclayton at apple.com
Tue Mar 5 22:23:55 PST 2013


Author: gclayton
Date: Wed Mar  6 00:23:54 2013
New Revision: 176548

URL: http://llvm.org/viewvc/llvm-project?rev=176548&view=rev
Log:
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.


Added:
    lldb/trunk/test/lang/cpp/enum_types/
    lldb/trunk/test/lang/cpp/enum_types/Makefile
    lldb/trunk/test/lang/cpp/enum_types/TestCPP11EnumTypes.py
    lldb/trunk/test/lang/cpp/enum_types/main.cpp
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTType.cpp
    lldb/trunk/test/lang/c/enum_types/TestEnumTypes.py
    lldb/trunk/test/lang/c/enum_types/main.c
    lldb/trunk/test/lang/cpp/rvalue-references/Makefile

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=176548&r1=176547&r2=176548&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Mar  6 00:23:54 2013
@@ -6049,9 +6049,18 @@ SymbolFileDWARF::ParseType (const Symbol
                         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 Symbol
                         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 Symbol
                         {
                             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);

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=176548&r1=176547&r2=176548&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Wed Mar  6 00:23:54 2013
@@ -1037,20 +1037,38 @@ ClangASTType::DumpTypeValue (clang::ASTC
                 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....

Modified: lldb/trunk/test/lang/c/enum_types/TestEnumTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/enum_types/TestEnumTypes.py?rev=176548&r1=176547&r2=176548&view=diff
==============================================================================
--- lldb/trunk/test/lang/c/enum_types/TestEnumTypes.py (original)
+++ lldb/trunk/test/lang/c/enum_types/TestEnumTypes.py Wed Mar  6 00:23:54 2013
@@ -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()

Modified: lldb/trunk/test/lang/c/enum_types/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/enum_types/main.c?rev=176548&r1=176547&r2=176548&view=diff
==============================================================================
--- lldb/trunk/test/lang/c/enum_types/main.c (original)
+++ lldb/trunk/test/lang/c/enum_types/main.c Wed Mar  6 00:23:54 2013
@@ -11,7 +11,7 @@
 int main (int argc, char const *argv[])
 {
     enum days {
-        Monday = 10,
+        Monday = -3,
         Tuesday,
         Wednesday,
         Thursday,

Added: lldb/trunk/test/lang/cpp/enum_types/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/enum_types/Makefile?rev=176548&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/enum_types/Makefile (added)
+++ lldb/trunk/test/lang/cpp/enum_types/Makefile Wed Mar  6 00:23:54 2013
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+clean: OBJECTS+=$(wildcard main.d.*)
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -std=c++11

Added: lldb/trunk/test/lang/cpp/enum_types/TestCPP11EnumTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/enum_types/TestCPP11EnumTypes.py?rev=176548&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/enum_types/TestCPP11EnumTypes.py (added)
+++ lldb/trunk/test/lang/cpp/enum_types/TestCPP11EnumTypes.py Wed Mar  6 00:23:54 2013
@@ -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()

Added: lldb/trunk/test/lang/cpp/enum_types/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/enum_types/main.cpp?rev=176548&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/enum_types/main.cpp (added)
+++ lldb/trunk/test/lang/cpp/enum_types/main.cpp Wed Mar  6 00:23:54 2013
@@ -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;
+}

Modified: lldb/trunk/test/lang/cpp/rvalue-references/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/rvalue-references/Makefile?rev=176548&r1=176547&r2=176548&view=diff
==============================================================================
--- lldb/trunk/test/lang/cpp/rvalue-references/Makefile (original)
+++ lldb/trunk/test/lang/cpp/rvalue-references/Makefile Wed Mar  6 00:23:54 2013
@@ -2,6 +2,6 @@ LEVEL = ../../../make
 
 CXX_SOURCES := main.cpp
 
-CXXFLAGS = -std=c++11
-
 include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -std=c++11





More information about the lldb-commits mailing list