summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp140
1 files changed, 119 insertions, 21 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ed916cc78ea..04571023670 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -32,6 +32,7 @@
#include "lldb/Core/Value.h"
#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -118,13 +119,6 @@ SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
return new SymbolFileDWARF(obj_file);
}
-
-ClangASTContext &
-SymbolFileDWARF::GetClangASTContext()
-{
- return GetTypeList()->GetClangASTContext();
-}
-
TypeList *
SymbolFileDWARF::GetTypeList ()
{
@@ -183,13 +177,61 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
m_global_index(),
m_type_index(),
m_namespace_index(),
- m_indexed(false),
+ m_indexed (false),
+ m_is_external_ast_source (false),
m_ranges()
{
}
SymbolFileDWARF::~SymbolFileDWARF()
{
+ if (m_is_external_ast_source)
+ m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
+}
+
+static const ConstString &
+GetDWARFMachOSegmentName ()
+{
+ static ConstString g_dwarf_section_name ("__DWARF");
+ return g_dwarf_section_name;
+}
+
+ClangASTContext &
+SymbolFileDWARF::GetClangASTContext ()
+{
+ if (m_debug_map_symfile)
+ return m_debug_map_symfile->GetClangASTContext ();
+
+ ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
+ if (!m_is_external_ast_source)
+ {
+ m_is_external_ast_source = true;
+ llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
+ new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
+ SymbolFileDWARF::CompleteObjCInterfaceDecl,
+ this));
+
+ ast.SetExternalSource (ast_source_ap);
+ }
+ return ast;
+}
+
+void
+SymbolFileDWARF::InitializeObject()
+{
+ // Install our external AST source callbacks so we can complete Clang types.
+ Module *module = m_obj_file->GetModule();
+ if (module)
+ {
+ const SectionList *section_list = m_obj_file->GetSectionList();
+
+ const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
+
+ // Memory map the DWARF mach-o segment so we have everything mmap'ed
+ // to keep our heap memory usage down.
+ if (section)
+ section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
+ }
}
bool
@@ -221,15 +263,10 @@ SymbolFileDWARF::GetAbilities ()
uint64_t debug_ranges_file_size = 0;
uint64_t debug_str_file_size = 0;
- static ConstString g_dwarf_section_name ("__DWARF");
-
- section = section_list->FindSectionByName(g_dwarf_section_name).get();
+ section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
if (section)
- {
- section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
section_list = &section->GetChildren ();
- }
section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
if (section != NULL)
@@ -1079,6 +1116,7 @@ SymbolFileDWARF::ParseChildMembers
size_t count = 0;
const DWARFDebugInfoEntry *die;
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+ uint32_t member_idx = 0;
for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
{
@@ -1155,6 +1193,17 @@ SymbolFileDWARF::ParseChildMembers
if (class_language == eLanguageTypeObjC ||
class_language == eLanguageTypeObjC_plus_plus)
accessibility = eAccessNone;
+
+ if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
+ {
+ // Not all compilers will mark the vtable pointer
+ // member as artificial (llvm-gcc). We can't have
+ // the virtual members in our classes otherwise it
+ // throws off all child offsets since we end up
+ // having and extra pointer sized member in our
+ // class layouts.
+ is_artificial = true;
+ }
if (is_artificial == false)
{
@@ -1171,6 +1220,7 @@ SymbolFileDWARF::ParseChildMembers
bit_size);
}
}
+ ++member_idx;
}
break;
@@ -1319,13 +1369,32 @@ SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
return NULL;
}
+// This function is used when SymbolFileDWARFDebugMap owns a bunch of
+// SymbolFileDWARF objects to detect if this DWARF file is the one that
+// can resolve a clang_type.
+bool
+SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
+{
+ clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
+ const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+ return die != NULL;
+}
+
+
lldb::clang_type_t
SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
{
// We have a struct/union/class/enum that needs to be fully resolved.
- const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
+ clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
+ const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
if (die == NULL)
{
+// if (m_debug_map_symfile)
+// {
+// Type *type = m_die_to_type[die];
+// if (type && type->GetSymbolFile() != this)
+// return type->GetClangType();
+// }
// We have already resolved this type...
return clang_type;
}
@@ -1333,7 +1402,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
// map in case anyone child members or other types require this type to get resolved.
// The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
// are done.
- m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
+ m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
DWARFDebugInfo* debug_info = DebugInfo();
@@ -2743,7 +2812,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA
if (namespace_name)
{
Declaration decl; // TODO: fill in the decl object
- clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
+ clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die));
if (namespace_decl)
{
//printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
@@ -2775,7 +2844,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA
}
clang::DeclContext *decl_ctx;
- dw_offset_t die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
+ dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
if (die_offset != DW_INVALID_OFFSET)
{
//printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
@@ -2784,7 +2853,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA
return decl_ctx;
}
- die_offset = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
+ die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
if (die_offset != DW_INVALID_OFFSET)
{
//printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
@@ -3182,6 +3251,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
// When the definition needs to be defined.
m_forward_decl_die_to_clang_type[die] = clang_type;
m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
+ ClangASTContext::SetHasExternalStorage (clang_type, true);
}
}
@@ -3244,7 +3314,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
DW_ATE_signed,
byte_size * 8);
clang_type = ast.CreateEnumerationType (type_name_cstr,
- GetClangDeclContextForDIE (dwarf_cu, die->GetParent()),
+ GetClangDeclContextForDIE (dwarf_cu, die),
decl,
enumerator_clang_type);
}
@@ -3268,6 +3338,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
m_die_to_type[die] = type_sp.get();
+#if LEAVE_ENUMS_FORWARD_DECLARED
// Leave this as a forward declaration until we need
// to know the details of the type. lldb_private::Type
// will automatically call the SymbolFile virtual function
@@ -3275,7 +3346,16 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
// When the definition needs to be defined.
m_forward_decl_die_to_clang_type[die] = clang_type;
m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
-
+ ClangASTContext::SetHasExternalStorage (clang_type, true);
+#else
+ ast.StartTagDeclarationDefinition (clang_type);
+ if (die->HasChildren())
+ {
+ SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
+ ParseChildEnumerators(sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
+ }
+ ast.CompleteTagDeclarationDefinition (clang_type);
+#endif
}
}
break;
@@ -4165,3 +4245,21 @@ SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
return NULL;
}
+void
+SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
+{
+ SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+ clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ if (clang_type)
+ symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
+}
+
+void
+SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
+{
+ SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+ clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+ if (clang_type)
+ symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
+}
+
OpenPOWER on IntegriCloud