[Lldb-commits] [lldb] r137737 - /lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Greg Clayton
gclayton at apple.com
Tue Aug 16 11:40:23 PDT 2011
Author: gclayton
Date: Tue Aug 16 13:40:23 2011
New Revision: 137737
URL: http://llvm.org/viewvc/llvm-project?rev=137737&view=rev
Log:
Fixed an issue where we could end up creating multiple
C++ methods for a function depending on how the DWARF was
created. Now we parse the class type from the definition,
and all methods that use DW_AT_specification or DW_AT_abstract_origin
attributes to point to the definition, now won't create
duplicate entries. This is in response to how clang++ creates
much different DWARF than gcc.
Modified:
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
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=137737&r1=137736&r2=137737&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Aug 16 13:40:23 2011
@@ -3539,6 +3539,8 @@
bool is_static = false;
bool is_virtual = false;
bool is_explicit = false;
+ dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
+ dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
unsigned type_quals = 0;
clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
@@ -3582,6 +3584,15 @@
}
break;
+ case DW_AT_specification:
+ specification_die_offset = form_value.Reference(dwarf_cu);
+ break;
+
+ case DW_AT_abstract_origin:
+ abstract_origin_die_offset = form_value.Reference(dwarf_cu);
+ break;
+
+
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_address_class:
@@ -3600,13 +3611,11 @@
case DW_AT_recursive:
case DW_AT_return_addr:
case DW_AT_segment:
- case DW_AT_specification:
case DW_AT_start_scope:
case DW_AT_static_link:
case DW_AT_trampoline:
case DW_AT_visibility:
case DW_AT_vtable_elem_location:
- case DW_AT_abstract_origin:
case DW_AT_description:
case DW_AT_sibling:
break;
@@ -3724,35 +3733,56 @@
Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
if (class_type)
{
- clang_type_t class_opaque_type = class_type->GetClangForwardType();
- if (ClangASTContext::IsCXXClassType (class_opaque_type))
+ if (specification_die_offset != DW_INVALID_OFFSET)
{
- // 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!)
- // and clang will get mad if we try and make a function that isn't
- // well formed in the DWARF, so we will just skip it...
- type_handled = true;
- }
- else
+ // If we have a specification, then the function type should have been
+ // made with the specification and not with this die.
+ DWARFCompileUnitSP spec_cu_sp;
+ const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
+ if (m_die_to_decl_ctx[spec_die] == NULL)
+ fprintf (stderr,"warning: 0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n", die->GetOffset(), specification_die_offset);
+ type_handled = true;
+ }
+ else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
+ {
+ DWARFCompileUnitSP abs_cu_sp;
+ const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
+ if (m_die_to_decl_ctx[abs_die] == NULL)
+ fprintf (stderr,"warning: 0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n", die->GetOffset(), abstract_origin_die_offset);
+ type_handled = true;
+ }
+ else
+ {
+ clang_type_t class_opaque_type = class_type->GetClangForwardType();
+ if (ClangASTContext::IsCXXClassType (class_opaque_type))
{
- clang::CXXMethodDecl *cxx_method_decl;
- cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
- type_name_cstr,
- clang_type,
- accessibility,
- is_virtual,
- is_static,
- is_inline,
- is_explicit);
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+ // 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!)
+ // and clang will get mad if we try and make a function that isn't
+ // well formed in the DWARF, so we will just skip it...
+ type_handled = true;
+ }
+ else
+ {
+ clang::CXXMethodDecl *cxx_method_decl;
+ cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
+ type_name_cstr,
+ clang_type,
+ accessibility,
+ is_virtual,
+ is_static,
+ is_inline,
+ is_explicit);
+ LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
- type_handled = cxx_method_decl != NULL;
+ type_handled = cxx_method_decl != NULL;
+ }
}
}
}
More information about the lldb-commits
mailing list