[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