[Lldb-commits] [lldb] r136733 - in /lldb/trunk: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h test/lang/cpp/static_methods/ test/lang/cpp/static_methods/Makefile test/lang/cpp/static_methods/TestCPPStaticMethods.py test/lang/cpp/static_methods/main.cpp

Sean Callanan scallanan at apple.com
Tue Aug 2 15:21:50 PDT 2011


Author: spyffe
Date: Tue Aug  2 17:21:50 2011
New Revision: 136733

URL: http://llvm.org/viewvc/llvm-project?rev=136733&view=rev
Log:
Fixed a bug in which the DWARF reader did not distinguish
appropriately between C++ static methods and non-static
methods.  This bug made it impossible to call most static
methods, either because Clang did not recognize that a
method could be called without providing a "this"
parameter, or because Clang did not properly mangle the
name of the method when searching for it in the target.

Also added a testcase.

Added:
    lldb/trunk/test/lang/cpp/static_methods/
    lldb/trunk/test/lang/cpp/static_methods/Makefile
    lldb/trunk/test/lang/cpp/static_methods/TestCPPStaticMethods.py
    lldb/trunk/test/lang/cpp/static_methods/main.cpp
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

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=136733&r1=136732&r2=136733&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Aug  2 17:21:50 2011
@@ -2396,6 +2396,7 @@
     DWARFCompileUnit* dwarf_cu,
     const DWARFDebugInfoEntry *parent_die,
     bool skip_artificial,
+    bool &is_static,
     TypeList* type_list,
     std::vector<clang_type_t>& function_param_types,
     std::vector<clang::ParmVarDecl*>& function_param_decls,
@@ -2481,7 +2482,7 @@
                                 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
                                 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type || 
                                                         grandparent_die->Tag() == DW_TAG_class_type))
-                                {
+                                {                                    
                                     LanguageType language = sc.comp_unit->GetLanguage();
                                     if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
                                     {
@@ -2492,10 +2493,12 @@
                                         {
                                             Type *this_type = ResolveTypeUID (param_type_die_offset);
                                             if (this_type)
-                                            {
+                                            {                              
                                                 uint32_t encoding_mask = this_type->GetEncodingMask();
                                                 if (encoding_mask & Type::eEncodingIsPointerUID)
                                                 {
+                                                    is_static = false;
+                                                    
                                                     if (encoding_mask & (1u << Type::eEncodingIsConstUID))
                                                         type_quals |= clang::Qualifiers::Const;
                                                     if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
@@ -3567,6 +3570,12 @@
                     std::vector<clang::ParmVarDecl*> function_param_decls;
 
                     // Parse the function children for the parameters
+                    
+                    const DWARFDebugInfoEntry *class_die = die->GetParent();
+                    if (class_die && (class_die->Tag() == DW_TAG_structure_type || 
+                                      class_die->Tag() == DW_TAG_class_type))
+                        is_static = true;
+                    
                     if (die->HasChildren())
                     {
                         bool skip_artificial = true;
@@ -3574,7 +3583,8 @@
                                               type_sp, 
                                               dwarf_cu, 
                                               die, 
-                                              skip_artificial, 
+                                              skip_artificial,
+                                              is_static,
                                               type_list, 
                                               function_param_types, 
                                               function_param_decls,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=136733&r1=136732&r2=136733&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Aug  2 17:21:50 2011
@@ -275,6 +275,7 @@
                                 DWARFCompileUnit* dwarf_cu,
                                 const DWARFDebugInfoEntry *parent_die,
                                 bool skip_artificial,
+                                bool &is_static,
                                 lldb_private::TypeList* type_list,
                                 std::vector<lldb::clang_type_t>& function_args,
                                 std::vector<clang::ParmVarDecl*>& function_param_decls,

Added: lldb/trunk/test/lang/cpp/static_methods/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/static_methods/Makefile?rev=136733&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/static_methods/Makefile (added)
+++ lldb/trunk/test/lang/cpp/static_methods/Makefile Tue Aug  2 17:21:50 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/cpp/static_methods/TestCPPStaticMethods.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/static_methods/TestCPPStaticMethods.py?rev=136733&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/static_methods/TestCPPStaticMethods.py (added)
+++ lldb/trunk/test/lang/cpp/static_methods/TestCPPStaticMethods.py Tue Aug  2 17:21:50 2011
@@ -0,0 +1,51 @@
+"""
+Tests expressions that distinguish between static and non-static methods.
+"""
+
+from lldbtest import *
+
+class CPPStaticMethodsTestCase(TestBase):
+    
+    mydir = os.path.join("lang", "cpp", "static_methods")
+    
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_with_dsym_and_run_command(self):
+        """Test that static methods are properly distinguished from regular methods"""
+        self.buildDsym()
+        self.static_method_commands()
+
+    def test_with_dwarf_and_run_command(self):
+        """Test that static methods are properly distinguished from regular methods"""
+        self.buildDwarf()
+        self.static_method_commands()
+
+    def setUp(self):
+        TestBase.setUp(self)
+        self.line = line_number('main.cpp', '// Break at this line')
+    
+    def static_method_commands(self):
+        """Test that static methods are properly distinguished from regular methods"""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+                    startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" % self.line)
+
+        self.runCmd("process launch", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list",
+                    STOPPED_DUE_TO_BREAKPOINT,
+                    substrs = ['stopped', 'stop reason = breakpoint'])
+
+        self.expect("expression -- A::getStaticValue()",
+                    startstr = "(int) $0 = 5")
+
+        self.expect("expression -- my_a.getMemberValue()",
+                    startstr = "(int) $1 = 3")
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()
\ No newline at end of file

Added: lldb/trunk/test/lang/cpp/static_methods/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/static_methods/main.cpp?rev=136733&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/static_methods/main.cpp (added)
+++ lldb/trunk/test/lang/cpp/static_methods/main.cpp Tue Aug  2 17:21:50 2011
@@ -0,0 +1,38 @@
+//===-- main.cpp ------------------------------------------------*- 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>
+
+class A
+{
+public:
+  static int getStaticValue();
+  int getMemberValue();
+  int a;
+};
+
+int A::getStaticValue()
+{
+  return 5;
+} 
+
+int A::getMemberValue()
+{
+  return a;
+}
+
+int main()
+{
+  A my_a;
+
+  my_a.a = 3;
+
+  printf("%d\n", A::getStaticValue()); // Break at this line
+  printf("%d\n", my_a.getMemberValue());
+}





More information about the lldb-commits mailing list