[Lldb-commits] [lldb] r249629 - [DWARFASTParserClang] Strengthen incomplete type handling.

Siva Chandra via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 7 15:11:52 PDT 2015


Author: sivachandra
Date: Wed Oct  7 17:11:52 2015
New Revision: 249629

URL: http://llvm.org/viewvc/llvm-project?rev=249629&view=rev
Log:
[DWARFASTParserClang] Strengthen incomplete type handling.

Summary: This change fixes pr24916. As associated test has been added.

Reviewers: clayborg

Subscribers: zturner, lldb-commits

Differential Revision: http://reviews.llvm.org/D13224

Added:
    lldb/trunk/test/lang/cpp/limit-debug-info/
    lldb/trunk/test/lang/cpp/limit-debug-info/Makefile
    lldb/trunk/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py
    lldb/trunk/test/lang/cpp/limit-debug-info/base.cpp
    lldb/trunk/test/lang/cpp/limit-debug-info/base.h
    lldb/trunk/test/lang/cpp/limit-debug-info/derived.cpp
    lldb/trunk/test/lang/cpp/limit-debug-info/derived.h
    lldb/trunk/test/lang/cpp/limit-debug-info/main.cpp
Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/test/make/Makefile.rules

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=249629&r1=249628&r2=249629&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Wed Oct  7 17:11:52 2015
@@ -615,6 +615,10 @@ DWARFASTParserClang::ParseTypeFromDWARF
                             // so lets use it and cache the fact that we found
                             // a complete type for this die
                             dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+                            clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
+                                dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID())));
+                            if (defn_decl_ctx)
+                                LinkDeclContextToDIE(defn_decl_ctx, die);
                             return type_sp;
                         }
                     }
@@ -1101,8 +1105,11 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                 Type *class_type = dwarf->ResolveType (decl_ctx_die);
                                 if (class_type)
                                 {
+                                    bool alternate_defn = false;
                                     if (class_type->GetID() != decl_ctx_die.GetID())
                                     {
+                                        alternate_defn = true;
+
                                         // We uniqued the parent class of this function to another class
                                         // so we now need to associate all dies under "decl_ctx_die" to
                                         // DIEs in the DIE for "class_type"...
@@ -1193,13 +1200,8 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                         CompilerType class_opaque_type = class_type->GetForwardCompilerType ();
                                         if (ClangASTContext::IsCXXClassType(class_opaque_type))
                                         {
-                                            if (class_opaque_type.IsBeingDefined ())
+                                            if (class_opaque_type.IsBeingDefined () || alternate_defn)
                                             {
-                                                // Neither GCC 4.2 nor clang++ currently set a valid accessibility
-                                                // in the DWARF for C++ methods... Default to public for now...
-                                                if (accessibility == eAccessNone)
-                                                    accessibility = eAccessPublic;
-
                                                 if (!is_static && !die.HasChildren())
                                                 {
                                                     // We have a C++ member function with no children (this pointer!)
@@ -1209,52 +1211,87 @@ DWARFASTParserClang::ParseTypeFromDWARF
                                                 }
                                                 else
                                                 {
-                                                    clang::CXXMethodDecl *cxx_method_decl;
-                                                    // REMOVE THE CRASH DESCRIPTION BELOW
-                                                    Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
-                                                                                         type_name_cstr,
-                                                                                         class_type->GetName().GetCString(),
-                                                                                         die.GetID(),
-                                                                                         dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str());
-
-                                                    const bool is_attr_used = false;
-
-                                                    cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(),
-                                                                                                      type_name_cstr,
-                                                                                                      clang_type,
-                                                                                                      accessibility,
-                                                                                                      is_virtual,
-                                                                                                      is_static,
-                                                                                                      is_inline,
-                                                                                                      is_explicit,
-                                                                                                      is_attr_used,
-                                                                                                      is_artificial);
-
-                                                    type_handled = cxx_method_decl != NULL;
-
-                                                    if (type_handled)
+                                                    bool add_method = true;
+                                                    if (alternate_defn)
                                                     {
-                                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
-
-                                                        Host::SetCrashDescription (NULL);
-
-
-                                                        ClangASTMetadata metadata;
-                                                        metadata.SetUserID(die.GetID());
-
-                                                        if (!object_pointer_name.empty())
+                                                        // If an alternate definition for the class exists, then add the method only if an
+                                                        // equivalent is not already present.
+                                                        clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(class_opaque_type.GetOpaqueQualType());
+                                                        if (record_decl)
                                                         {
-                                                            metadata.SetObjectPtrName(object_pointer_name.c_str());
-                                                            if (log)
-                                                                log->Printf ("Setting object pointer name: %s on method object %p.\n",
-                                                                             object_pointer_name.c_str(),
-                                                                             static_cast<void*>(cxx_method_decl));
+                                                            for (auto method_iter = record_decl->method_begin();
+                                                                 method_iter != record_decl->method_end();
+                                                                 method_iter++)
+                                                            {
+                                                                clang::CXXMethodDecl *method_decl = *method_iter;
+                                                                if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr))
+                                                                {
+                                                                    if (method_decl->getType() == ClangASTContext::GetQualType(clang_type))
+                                                                    {
+                                                                        add_method = false;
+                                                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die);
+                                                                        type_handled = true;
+
+                                                                        break;
+                                                                    }
+                                                                }
+                                                            }
                                                         }
-                                                        m_ast.SetMetadata (cxx_method_decl, metadata);
                                                     }
-                                                    else
+
+                                                    if (add_method)
                                                     {
-                                                        ignore_containing_context = true;
+                                                        // REMOVE THE CRASH DESCRIPTION BELOW
+                                                        Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
+                                                                                             type_name_cstr,
+                                                                                             class_type->GetName().GetCString(),
+                                                                                             die.GetID(),
+                                                                                             dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str());
+    
+                                                        const bool is_attr_used = false;
+                                                        // Neither GCC 4.2 nor clang++ currently set a valid accessibility
+                                                        // in the DWARF for C++ methods... Default to public for now...
+                                                        if (accessibility == eAccessNone)
+                                                            accessibility = eAccessPublic;
+    
+                                                        clang::CXXMethodDecl *cxx_method_decl;
+                                                        cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(),
+                                                                                                          type_name_cstr,
+                                                                                                          clang_type,
+                                                                                                          accessibility,
+                                                                                                          is_virtual,
+                                                                                                          is_static,
+                                                                                                          is_inline,
+                                                                                                          is_explicit,
+                                                                                                          is_attr_used,
+                                                                                                          is_artificial);
+    
+                                                        type_handled = cxx_method_decl != NULL;
+    
+                                                        if (type_handled)
+                                                        {
+                                                            LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+    
+                                                            Host::SetCrashDescription (NULL);
+    
+    
+                                                            ClangASTMetadata metadata;
+                                                            metadata.SetUserID(die.GetID());
+    
+                                                            if (!object_pointer_name.empty())
+                                                            {
+                                                                metadata.SetObjectPtrName(object_pointer_name.c_str());
+                                                                if (log)
+                                                                    log->Printf ("Setting object pointer name: %s on method object %p.\n",
+                                                                                 object_pointer_name.c_str(),
+                                                                                 static_cast<void*>(cxx_method_decl));
+                                                            }
+                                                            m_ast.SetMetadata (cxx_method_decl, metadata);
+                                                        }
+                                                        else
+                                                        {
+                                                            ignore_containing_context = true;
+                                                        }
                                                     }
                                                 }
                                             }

Added: lldb/trunk/test/lang/cpp/limit-debug-info/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/Makefile?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/Makefile (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/Makefile Wed Oct  7 17:11:52 2015
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+CXX_SOURCES = main.cpp derived.cpp base.cpp
+
+CFLAGS_EXTRAS += $(LIMIT_DEBUG_INFO_FLAGS)
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py Wed Oct  7 17:11:52 2015
@@ -0,0 +1,48 @@
+import lldb
+from lldbtest import *
+import lldbutil
+
+class TestWithLimitDebugInfo(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @dwarf_test
+    def test_with_dwarf(self):
+        self.buildDwarf()
+
+        cwd = os.getcwd()
+
+        src_file = os.path.join(cwd, "main.cpp")
+        src_file_spec = lldb.SBFileSpec(src_file)
+        self.assertTrue(src_file_spec.IsValid(), "breakpoint file")
+
+        # Get the path of the executable
+        exe_path  = os.path.join(cwd, 'a.out')
+
+        # Load the executable
+        target = self.dbg.CreateTarget(exe_path)
+        self.assertTrue(target.IsValid(), VALID_TARGET)
+
+        # Break on main function
+        breakpoint = target.BreakpointCreateBySourceRegex("break here", src_file_spec)
+        self.assertTrue(breakpoint.IsValid() and breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT)
+
+        # Launch the process
+        process = target.LaunchSimple(None, None, self.get_process_working_directory())
+        self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
+
+        # Get the thread of the process
+        self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
+        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+        thread.StepInto()
+
+        # Get frame for current thread
+        frame = thread.GetSelectedFrame()
+
+        v1 = frame.EvaluateExpression("1")
+        self.assertTrue(v1.IsValid(), "'expr 1' results in a valid SBValue object")
+        self.assertTrue(v1.GetError().Success(), "'expr 1' succeeds without an error.")
+
+        v2 = frame.EvaluateExpression("this")
+        self.assertTrue(v2.IsValid(), "'expr this' results in a valid SBValue object")
+        self.assertTrue(v2.GetError().Success(), "'expr this' succeeds without an error.")

Added: lldb/trunk/test/lang/cpp/limit-debug-info/base.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/base.cpp?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/base.cpp (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/base.cpp Wed Oct  7 17:11:52 2015
@@ -0,0 +1,6 @@
+#include "base.h"
+
+void FooNS::bar() {
+    x = 54321;
+}
+

Added: lldb/trunk/test/lang/cpp/limit-debug-info/base.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/base.h?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/base.h (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/base.h Wed Oct  7 17:11:52 2015
@@ -0,0 +1,10 @@
+class FooNS
+{
+public:
+    virtual void bar();
+    virtual char baz() = 0;
+
+protected:
+    int x;
+};
+

Added: lldb/trunk/test/lang/cpp/limit-debug-info/derived.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/derived.cpp?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/derived.cpp (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/derived.cpp Wed Oct  7 17:11:52 2015
@@ -0,0 +1,6 @@
+#include "derived.h"
+
+char Foo::baz() {
+    return (char)(x&0xff);
+}
+

Added: lldb/trunk/test/lang/cpp/limit-debug-info/derived.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/derived.h?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/derived.h (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/derived.h Wed Oct  7 17:11:52 2015
@@ -0,0 +1,13 @@
+#include "base.h"
+
+class Foo : public FooNS
+{
+public:
+    Foo() {
+        a = 12345;
+    }
+
+    char baz() override;
+    int a;
+};
+

Added: lldb/trunk/test/lang/cpp/limit-debug-info/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/limit-debug-info/main.cpp?rev=249629&view=auto
==============================================================================
--- lldb/trunk/test/lang/cpp/limit-debug-info/main.cpp (added)
+++ lldb/trunk/test/lang/cpp/limit-debug-info/main.cpp Wed Oct  7 17:11:52 2015
@@ -0,0 +1,7 @@
+#include "derived.h"
+
+int main() {
+    Foo f; // break here
+    f.bar();
+    return f.baz();
+}

Modified: lldb/trunk/test/make/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=249629&r1=249628&r2=249629&view=diff
==============================================================================
--- lldb/trunk/test/make/Makefile.rules (original)
+++ lldb/trunk/test/make/Makefile.rules Wed Oct  7 17:11:52 2015
@@ -170,6 +170,11 @@ else
 	endif
 endif
 
+LIMIT_DEBUG_INFO_FLAGS =
+ifneq (,$(findstring clang,$(CC)))
+   LIMIT_DEBUG_INFO_FLAGS += -flimit-debug-info
+endif
+
 CFLAGS ?= -g -O0 -fno-builtin
 ifeq "$(OS)" "Darwin"
 	CFLAGS += $(ARCHFLAG) $(ARCH) $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS) -I$(LLDB_BASE_DIR)include




More information about the lldb-commits mailing list