summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp241
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h20
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp87
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp175
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h15
7 files changed, 491 insertions, 68 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 2fb360440f6..ab20844bfcf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -33,6 +33,18 @@ public:
const DWARFDIE &die) = 0;
virtual bool
+ CanCompleteType (const lldb_private::CompilerType &compiler_type)
+ {
+ return false;
+ }
+
+ virtual bool
+ CompleteType (const lldb_private::CompilerType &compiler_type)
+ {
+ return false;
+ }
+
+ virtual bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) = 0;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index caa8c63f8ad..68a0285b69d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -24,11 +24,14 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
#include "Plugins/Language/ObjC/ObjCLanguage.h"
@@ -114,6 +117,78 @@ struct BitfieldInfo
}
};
+
+ClangASTImporter &
+DWARFASTParserClang::GetClangASTImporter()
+{
+ if (!m_clang_ast_importer_ap)
+ {
+ m_clang_ast_importer_ap.reset (new ClangASTImporter);
+ }
+ return *m_clang_ast_importer_ap;
+}
+
+
+TypeSP
+DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log)
+{
+ ModuleSP dwo_module_sp = die.GetContainingDWOModule();
+ if (dwo_module_sp)
+ {
+ // This type comes from an external DWO module
+ std::vector<CompilerContext> dwo_context;
+ die.GetDWOContext(dwo_context);
+ TypeMap dwo_types;
+ if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types))
+ {
+ const size_t num_dwo_types = dwo_types.GetSize();
+ if (num_dwo_types == 1)
+ {
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
+ if (dwo_type_sp)
+ {
+ lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType();
+
+ lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type);
+
+ //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString());
+ if (type)
+ {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeSP type_sp (new Type (die.GetID(),
+ dwarf,
+ dwo_type_sp->GetName(),
+ dwo_type_sp->GetByteSize(),
+ NULL,
+ LLDB_INVALID_UID,
+ Type::eEncodingInvalid,
+ &dwo_type_sp->GetDeclaration(),
+ type,
+ Type::eResolveStateForward));
+
+ dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
+ if (tag_decl)
+ LinkDeclContextToDIE(tag_decl, die);
+ else
+ {
+ clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ }
+ return type_sp;
+ }
+ }
+ }
+ }
+ }
+ return TypeSP();
+}
+
TypeSP
DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
const DWARFDIE &die,
@@ -487,15 +562,15 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
byte_size_valid ? byte_size : -1,
*unique_ast_entry_ap))
- {
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
{
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
+ type_sp = unique_ast_entry_ap->m_type_sp;
+ if (type_sp)
+ {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
}
}
- }
}
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
@@ -600,6 +675,11 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
type_name_cstr);
}
+ // See if the type comes from a DWO module and if so, track down that type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
DWARFDeclContext die_decl_ctx;
die.GetDWARFDeclContext(die_decl_ctx);
@@ -833,7 +913,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
case DW_AT_type: encoding_form = form_value; break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_declaration: is_forward_declaration = form_value.Boolean(); break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_bit_stride:
@@ -850,6 +930,54 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
}
}
+ if (is_forward_declaration)
+ {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+
+ if (!type_sp)
+ {
+ SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile)
+ {
+ // We weren't able to find a full declaration in
+ // this DWARF, see if we have a declaration anywhere
+ // else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+ }
+ }
+
+ if (type_sp)
+ {
+ if (log)
+ {
+ dwarf->GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void*>(this),
+ die.GetOffset(),
+ DW_TAG_value_to_name(tag),
+ type_name_cstr,
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere
+ // 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;
+ }
+
+ }
DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
CompilerType enumerator_clang_type;
@@ -1130,7 +1258,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
if (class_type)
{
bool alternate_defn = false;
- if (class_type->GetID() != decl_ctx_die.GetID())
+ if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE())
{
alternate_defn = true;
@@ -1798,6 +1926,33 @@ DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die,
}
bool
+DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type)
+{
+ if (m_clang_ast_importer_ap)
+ return ClangASTContext::CanImport(compiler_type, GetClangASTImporter());
+ else
+ return false;
+}
+
+bool
+DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type)
+{
+ if (CanCompleteType(compiler_type))
+ {
+ if (ClangASTContext::Import(compiler_type, GetClangASTImporter()))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+ else
+ {
+ ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false);
+ }
+ }
+ return false;
+}
+
+bool
DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
CompilerType &clang_type)
@@ -1868,25 +2023,17 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
DWARFDIECollection member_function_dies;
DelayedPropertyList delayed_properties;
- if (!ParseChildMembers (sc,
- die,
- clang_type,
- class_language,
- base_classes,
- member_accessibilities,
- member_function_dies,
- delayed_properties,
- default_accessibility,
- is_a_class,
- layout_info))
- {
- auto module = dwarf->GetObjectFile()->GetModule();
- module->ReportError (":: Class %s has members with incomplete type.", die.GetName());
- if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
- module->ReportError(":: Try compiling the source file with -fno-limit-debug-info.");
-
- return false;
- }
+ ParseChildMembers (sc,
+ die,
+ clang_type,
+ class_language,
+ base_classes,
+ member_accessibilities,
+ member_function_dies,
+ delayed_properties,
+ default_accessibility,
+ is_a_class,
+ layout_info);
// Now parse any methods if there were any...
size_t num_functions = member_function_dies.Size();
@@ -1977,7 +2124,14 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
module->ReportError (":: Try compiling the source file with -fno-limit-debug-info.");
- return false;
+ // We have no choice other than to pretend that the base class
+ // is complete. If we don't do this, clang will crash when we
+ // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
+ // below. Since we provide layout assistance, all ivars in this
+ // class and other classes will be fine, this is the best we can do
+ // short of crashing.
+ ClangASTContext::StartTagDeclarationDefinition (base_class_type);
+ ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
}
}
}
@@ -2420,7 +2574,6 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
if (!parent_die)
return 0;
- uint32_t incomplete_member_info_count = 0;
uint32_t member_idx = 0;
BitfieldInfo last_field_info;
@@ -2754,8 +2907,8 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
}
CompilerType member_clang_type = member_type->GetLayoutCompilerType ();
- if (!member_clang_type.IsCompleteType() && !member_clang_type.GetCompleteType())
- incomplete_member_info_count += 1;
+ if (!member_clang_type.IsCompleteType())
+ member_clang_type.GetCompleteType();
{
// Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
@@ -2789,6 +2942,30 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
}
}
+ if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false)
+ {
+ if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang)
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info",
+ parent_die.GetOffset(),
+ parent_die.GetName(),
+ die.GetOffset(),
+ name);
+ else
+ module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
+ parent_die.GetOffset(),
+ parent_die.GetName(),
+ die.GetOffset(),
+ name,
+ sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+ // We have no choice other than to pretend that the member class
+ // is complete. If we don't do this, clang will crash when trying
+ // to layout the class. Since we provide layout assistance, all
+ // ivars in this class and other classes will be fine, this is
+ // the best we can do short of crashing.
+ ClangASTContext::StartTagDeclarationDefinition(member_clang_type);
+ ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type);
+ }
+
field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
name,
member_clang_type,
@@ -2978,7 +3155,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
}
}
- return incomplete_member_info_count == 0;
+ return true;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index e46972e261b..3814758fdd2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -47,6 +47,12 @@ public:
const DWARFDIE &die) override;
bool
+ CanCompleteType (const lldb_private::CompilerType &compiler_type) override;
+
+ bool
+ CompleteType (const lldb_private::CompilerType &compiler_type) override;
+
+ bool
CompleteTypeFromDWARF (const DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
@@ -175,6 +181,19 @@ protected:
void
LinkDeclToDIE (clang::Decl *decl, const DWARFDIE &die);
+ lldb_private::ClangASTImporter &
+ GetClangASTImporter();
+
+ lldb::TypeSP
+ ParseTypeFromDWO (const DWARFDIE &die, lldb_private::Log *log);
+
+ //----------------------------------------------------------------------
+ // Return true if this type is a declaration to a type in an external
+ // module.
+ //----------------------------------------------------------------------
+ lldb::ModuleSP
+ GetModuleForType (const DWARFDIE &die);
+
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
//typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
@@ -188,6 +207,7 @@ protected:
DIEToDeclContextMap m_die_to_decl_ctx;
DeclContextToDIEMap m_decl_ctx_to_die;
RecordDeclToLayoutMap m_record_decl_to_layout_map;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_ap;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 2ca4394b28e..708b88a1fe9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -22,8 +22,11 @@
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.h"
+using namespace lldb_private;
+
DIERef
DWARFDIE::GetDIERef() const
{
@@ -307,6 +310,51 @@ DWARFDIE::GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const
}
}
+void
+DWARFDIE::GetDWOContext (std::vector<CompilerContext> &context) const
+{
+ const dw_tag_t tag = Tag();
+ if (tag == DW_TAG_compile_unit)
+ return;
+ DWARFDIE parent = GetParent();
+ if (parent)
+ parent.GetDWOContext(context);
+ switch (tag)
+ {
+ case DW_TAG_module:
+ context.push_back(CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+ break;
+ case DW_TAG_namespace:
+ context.push_back(CompilerContext(CompilerContextKind::Namespace, ConstString(GetName())));
+ break;
+ case DW_TAG_structure_type:
+ context.push_back(CompilerContext(CompilerContextKind::Structure, ConstString(GetName())));
+ break;
+ case DW_TAG_union_type:
+ context.push_back(CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+ break;
+ case DW_TAG_class_type:
+ context.push_back(CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+ break;
+ case DW_TAG_enumeration_type:
+ context.push_back(CompilerContext(CompilerContextKind::Enumeration, ConstString(GetName())));
+ break;
+ case DW_TAG_subprogram:
+ context.push_back(CompilerContext(CompilerContextKind::Function, ConstString(GetPubname())));
+ break;
+ case DW_TAG_variable:
+ context.push_back(CompilerContext(CompilerContextKind::Variable, ConstString(GetPubname())));
+ break;
+ case DW_TAG_typedef:
+ context.push_back(CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+ break;
+ default:
+ assert(!"remove this prior to checkin");
+ break;
+ }
+}
+
+
DWARFDIE
DWARFDIE::GetParentDeclContextDIE () const
@@ -371,6 +419,45 @@ DWARFDIE::IsStructOrClass () const
return tag == DW_TAG_class_type || tag == DW_TAG_structure_type;
}
+
+DWARFDIE
+DWARFDIE::GetContainingDWOModuleDIE () const
+{
+ if (IsValid())
+ {
+ DWARFDIE top_module_die;
+ // Now make sure this DIE is scoped in a DW_TAG_module tag and return true if so
+ for (DWARFDIE parent = GetParent(); parent.IsValid(); parent = parent.GetParent())
+ {
+ const dw_tag_t tag = parent.Tag();
+ if (tag == DW_TAG_module)
+ top_module_die = parent;
+ else if (tag == DW_TAG_compile_unit)
+ break;
+ }
+
+ return top_module_die;
+ }
+ return DWARFDIE();
+}
+
+lldb::ModuleSP
+DWARFDIE::GetContainingDWOModule () const
+{
+ if (IsValid())
+ {
+ DWARFDIE dwo_module_die = GetContainingDWOModuleDIE();
+
+ if (dwo_module_die)
+ {
+ const char *module_name = dwo_module_die.GetName();
+ if (module_name)
+ return GetDWARF()->GetDWOModule (lldb_private::ConstString(module_name));
+ }
+ }
+ return lldb::ModuleSP();
+}
+
bool
DWARFDIE::HasChildren () const
{
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index f3e72d74d19..db37a45ad01 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -126,6 +126,12 @@ public:
m_die = nullptr;
}
+ lldb::ModuleSP
+ GetContainingDWOModule () const;
+
+ DWARFDIE
+ GetContainingDWOModuleDIE () const;
+
//----------------------------------------------------------------------
// Accessing information about a DIE
//----------------------------------------------------------------------
@@ -217,6 +223,9 @@ public:
void
GetDWARFDeclContext (DWARFDeclContext &dwarf_decl_ctx) const;
+ void
+ GetDWOContext (std::vector<lldb_private::CompilerContext> &context) const;
+
//----------------------------------------------------------------------
// Getting attribute values from the DIE.
//
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 70293384e7f..fd254ad9c29 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1077,9 +1077,9 @@ SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, st
if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
{
UpdateExternalModuleListIfNeeded();
- for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
+ for (const auto &pair : m_external_type_modules)
{
- imported_modules.push_back(external_type_module.second.m_name);
+ imported_modules.push_back(pair.first);
}
}
}
@@ -1515,13 +1515,32 @@ bool
SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
{
CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
- return GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
+ {
+ return true;
+ }
+ TypeSystem *type_system = compiler_type.GetTypeSystem();
+ if (type_system)
+ {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CanCompleteType(compiler_type);
+ }
+ return false;
}
bool
SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
{
+ TypeSystem *type_system = compiler_type.GetTypeSystem();
+ if (type_system)
+ {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast && dwarf_ast->CanCompleteType(compiler_type))
+ return dwarf_ast->CompleteType(compiler_type);
+ }
+
// We have a struct/union/class/enum that needs to be fully resolved.
CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
@@ -1641,6 +1660,17 @@ SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
return false;
}
+lldb::ModuleSP
+SymbolFileDWARF::GetDWOModule (ConstString name)
+{
+ UpdateExternalModuleListIfNeeded();
+ const auto &pos = m_external_type_modules.find(name);
+ if (pos != m_external_type_modules.end())
+ return pos->second;
+ else
+ return lldb::ModuleSP();
+}
+
void
SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
@@ -1658,37 +1688,24 @@ SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
if (die && die.HasChildren() == false)
{
- const uint64_t name_strp = die.GetAttributeValueAsUnsigned (DW_AT_name, UINT64_MAX);
- const uint64_t dwo_path_strp = die.GetAttributeValueAsUnsigned (DW_AT_GNU_dwo_name, UINT64_MAX);
-
- if (name_strp != UINT64_MAX)
+ const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
+
+ if (name)
{
- if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
+ ConstString const_name(name);
+ if (m_external_type_modules.find(const_name) == m_external_type_modules.end())
{
- const char *name = get_debug_str_data().PeekCStr(name_strp);
- const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
- if (name || dwo_path)
+ ModuleSP module_sp;
+ const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
+ if (dwo_path)
{
- ModuleSP module_sp;
- if (dwo_path)
- {
- ModuleSpec dwo_module_spec;
- dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
- dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
- //printf ("Loading dwo = '%s'\n", dwo_path);
- Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
- }
-
- if (dwo_path_strp != LLDB_INVALID_UID)
- {
- m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
- }
- else
- {
- // This hack should be removed promptly once clang emits both.
- m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
- }
+ ModuleSpec dwo_module_spec;
+ dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
+ //printf ("Loading dwo = '%s'\n", dwo_path);
+ Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
}
+ m_external_type_modules[const_name] = module_sp;
}
}
}
@@ -2970,6 +2987,104 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
}
return num_matches;
}
+ else
+ {
+ UpdateExternalModuleListIfNeeded();
+
+ for (const auto &pair : m_external_type_modules)
+ {
+ ModuleSP external_module_sp = pair.second;
+ if (external_module_sp)
+ {
+ SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
+ if (sym_vendor)
+ {
+ const uint32_t num_external_matches = sym_vendor->FindTypes (sc,
+ name,
+ parent_decl_ctx,
+ append,
+ max_matches,
+ types);
+ if (num_external_matches)
+ return num_external_matches;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+size_t
+SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
+ bool append,
+ TypeMap& types)
+{
+ if (!append)
+ types.Clear();
+
+ if (context.empty())
+ return 0;
+
+ DIEArray die_offsets;
+
+ ConstString name = context.back().name;
+
+ if (m_using_apple_tables)
+ {
+ if (m_apple_types_ap.get())
+ {
+ const char *name_cstr = name.GetCString();
+ m_apple_types_ap->FindByName (name_cstr, die_offsets);
+ }
+ }
+ else
+ {
+ if (!m_indexed)
+ Index ();
+
+ m_type_index.Find (name, die_offsets);
+ }
+
+ const size_t num_die_matches = die_offsets.size();
+
+ if (num_die_matches)
+ {
+ size_t num_matches = 0;
+ DWARFDebugInfo* debug_info = DebugInfo();
+ for (size_t i=0; i<num_die_matches; ++i)
+ {
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
+
+ if (die)
+ {
+ std::vector<CompilerContext> die_context;
+ die.GetDWOContext(die_context);
+ if (die_context != context)
+ continue;
+
+ Type *matching_type = ResolveType (die, true, true);
+ if (matching_type)
+ {
+ // We found a type pointer, now find the shared pointer form our type list
+ types.InsertUnique (matching_type->shared_from_this());
+ ++num_matches;
+ }
+ }
+ else
+ {
+ if (m_using_apple_tables)
+ {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
+ }
+
+ }
+ return num_matches;
+ }
return 0;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 818ce68eabb..2bdbc37c51f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -211,6 +211,11 @@ public:
uint32_t max_matches,
lldb_private::TypeMap& types) override;
+ size_t
+ FindTypes (const std::vector<lldb_private::CompilerContext> &context,
+ bool append,
+ lldb_private::TypeMap& types) override;
+
lldb_private::TypeList *
GetTypeList () override;
@@ -306,6 +311,9 @@ public:
virtual lldb_private::DWARFExpression::LocationListFormat
GetLocationListFormat() const;
+ lldb::ModuleSP
+ GetDWOModule (lldb_private::ConstString name);
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
@@ -483,12 +491,7 @@ protected:
typedef std::set<lldb_private::Type *> TypeSet;
- typedef struct {
- lldb_private::ConstString m_name;
- lldb::ModuleSP m_module_sp;
- } ClangModuleInfo;
-
- typedef std::map<uint64_t, ClangModuleInfo> ExternalTypeModuleMap;
+ typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap;
void
GetTypes (const DWARFDIE &die,
OpenPOWER on IntegriCloud