summaryrefslogtreecommitdiffstats
path: root/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp5934
1 files changed, 1175 insertions, 4759 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ea8aedc..0ed4d05 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -10,20 +10,6 @@
#include "SymbolFileDWARF.h"
// Other libraries and framework includes
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Basic/Builtins.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Sema/DeclSpec.h"
-
#include "llvm/Support/Casting.h"
#include "lldb/Core/ArchSpec.h"
@@ -39,34 +25,48 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/OptionValueFileSpecList.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Symbol/TypeMap.h"
+
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
+
+#include "lldb/Target/Language.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Utility/TaskPool.h"
+#include "DWARFASTParser.h"
#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
-#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugLine.h"
+#include "DWARFDebugMacro.h"
#include "DWARFDebugPubnames.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
-#include "DWARFLocationList.h"
#include "LogChannelDWARF.h"
+#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDebugMap.h"
#include <map>
@@ -83,8 +83,6 @@
#define DEBUG_PRINTF(fmt, ...)
#endif
-#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
-
using namespace lldb;
using namespace lldb_private;
@@ -105,18 +103,58 @@ using namespace lldb_private;
// return false;
//}
//
-static AccessType
-DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
-{
- switch (dwarf_accessibility)
+
+namespace {
+
+ PropertyDefinition
+ g_properties[] =
+ {
+ { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true, 0 , nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." },
+ { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
+ };
+
+ enum
+ {
+ ePropertySymLinkPaths
+ };
+
+
+ class PluginProperties : public Properties
{
- case DW_ACCESS_public: return eAccessPublic;
- case DW_ACCESS_private: return eAccessPrivate;
- case DW_ACCESS_protected: return eAccessProtected;
- default: break;
+ public:
+ static ConstString
+ GetSettingName()
+ {
+ return SymbolFileDWARF::GetPluginNameStatic();
+ }
+
+ PluginProperties()
+ {
+ m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ FileSpecList&
+ GetSymLinkPaths()
+ {
+ OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
+ assert(option_value);
+ return option_value->GetCurrentValue();
+ }
+
+ };
+
+ typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
+
+ static const SymbolFileDWARFPropertiesSP&
+ GetGlobalPluginProperties()
+ {
+ static const auto g_settings_sp(std::make_shared<PluginProperties>());
+ return g_settings_sp;
}
- return eAccessNone;
-}
+
+} // anonymous namespace end
+
static const char*
removeHostnameFromPathname(const char* path_from_dwarf)
@@ -125,9 +163,15 @@ removeHostnameFromPathname(const char* path_from_dwarf)
{
return path_from_dwarf;
}
-
+
const char *colon_pos = strchr(path_from_dwarf, ':');
- if (!colon_pos)
+ if (nullptr == colon_pos)
+ {
+ return path_from_dwarf;
+ }
+
+ const char *slash_pos = strchr(path_from_dwarf, '/');
+ if (slash_pos && (slash_pos < colon_pos))
{
return path_from_dwarf;
}
@@ -142,89 +186,42 @@ removeHostnameFromPathname(const char* path_from_dwarf)
{
return path_from_dwarf;
}
-
+
return colon_pos + 1;
}
-#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
-
-class DIEStack
+static const char*
+resolveCompDir(const char* path_from_dwarf)
{
-public:
-
- void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
- {
- m_dies.push_back (DIEInfo(cu, die));
- }
+ if (!path_from_dwarf)
+ return nullptr;
-
- void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
- {
- StreamString log_strm;
- const size_t n = m_dies.size();
- log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
- for (size_t i=0; i<n; i++)
- {
- DWARFCompileUnit *cu = m_dies[i].cu;
- const DWARFDebugInfoEntry *die = m_dies[i].die;
- std::string qualified_name;
- die->GetQualifiedName(dwarf, cu, qualified_name);
- log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
- (uint64_t)i,
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- qualified_name.c_str());
- }
- log->PutCString(log_strm.GetData());
- }
- void Pop ()
- {
- m_dies.pop_back();
- }
-
- class ScopedPopper
- {
- public:
- ScopedPopper (DIEStack &die_stack) :
- m_die_stack (die_stack),
- m_valid (false)
- {
- }
-
- void
- Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
- {
- m_valid = true;
- m_die_stack.Push (cu, die);
- }
-
- ~ScopedPopper ()
- {
- if (m_valid)
- m_die_stack.Pop();
- }
-
-
-
- protected:
- DIEStack &m_die_stack;
- bool m_valid;
- };
+ // DWARF2/3 suggests the form hostname:pathname for compilation directory.
+ // Remove the host part if present.
+ const char* local_path = removeHostnameFromPathname(path_from_dwarf);
+ if (!local_path)
+ return nullptr;
+
+ bool is_symlink = false;
+ FileSpec local_path_spec(local_path, false);
+ const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
+ for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
+ is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
+
+ if (!is_symlink)
+ return local_path;
+
+ if (!local_path_spec.IsSymbolicLink())
+ return local_path;
+
+ FileSpec resolved_local_path_spec;
+ const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
+ if (error.Success())
+ return resolved_local_path_spec.GetCString();
+
+ return nullptr;
+}
-protected:
- struct DIEInfo {
- DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
- cu(c),
- die(d)
- {
- }
- DWARFCompileUnit *cu;
- const DWARFDebugInfoEntry *die;
- };
- typedef std::vector<DIEInfo> Stack;
- Stack m_dies;
-};
-#endif
void
SymbolFileDWARF::Initialize()
@@ -232,7 +229,21 @@ SymbolFileDWARF::Initialize()
LogChannelDWARF::Initialize();
PluginManager::RegisterPlugin (GetPluginNameStatic(),
GetPluginDescriptionStatic(),
- CreateInstance);
+ CreateInstance,
+ DebuggerInitialize);
+}
+
+void
+SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
+{
+ if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
+ {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForSymbolFilePlugin(debugger,
+ GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString ("Properties for the dwarf symbol-file plug-in."),
+ is_global_setting);
+ }
}
void
@@ -272,65 +283,61 @@ SymbolFileDWARF::GetTypeList ()
}
void
-SymbolFileDWARF::GetTypes (DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry *die,
+SymbolFileDWARF::GetTypes (const DWARFDIE &die,
dw_offset_t min_die_offset,
dw_offset_t max_die_offset,
uint32_t type_mask,
TypeSet &type_set)
{
- if (cu)
+ if (die)
{
- if (die)
+ const dw_offset_t die_offset = die.GetOffset();
+
+ if (die_offset >= max_die_offset)
+ return;
+
+ if (die_offset >= min_die_offset)
{
- const dw_offset_t die_offset = die->GetOffset();
-
- if (die_offset >= max_die_offset)
- return;
+ const dw_tag_t tag = die.Tag();
- if (die_offset >= min_die_offset)
- {
- const dw_tag_t tag = die->Tag();
-
- bool add_type = false;
+ bool add_type = false;
- switch (tag)
- {
- case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
- case DW_TAG_unspecified_type:
- case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
- case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
- case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
- case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
- case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
- case DW_TAG_subroutine_type:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
- case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
- case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
- case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
- }
+ switch (tag)
+ {
+ case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
+ case DW_TAG_unspecified_type:
+ case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
+ case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
+ case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
+ case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
+ case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
+ case DW_TAG_subroutine_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
+ case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
+ case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
+ case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
+ }
- if (add_type)
+ if (add_type)
+ {
+ const bool assert_not_being_parsed = true;
+ Type *type = ResolveTypeUID (die, assert_not_being_parsed);
+ if (type)
{
- const bool assert_not_being_parsed = true;
- Type *type = ResolveTypeUID (cu, die, assert_not_being_parsed);
- if (type)
- {
- if (type_set.find(type) == type_set.end())
- type_set.insert(type);
- }
+ if (type_set.find(type) == type_set.end())
+ type_set.insert(type);
}
}
-
- for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
- child_die != NULL;
- child_die = child_die->GetSibling())
- {
- GetTypes (cu, child_die, min_die_offset, max_die_offset, type_mask, type_set);
- }
+ }
+
+ for (DWARFDIE child_die = die.GetFirstChild();
+ child_die.IsValid();
+ child_die = child_die.GetSibling())
+ {
+ GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
}
}
}
@@ -353,8 +360,7 @@ SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
dwarf_cu = GetDWARFCompileUnit(comp_unit);
if (dwarf_cu == 0)
return 0;
- GetTypes (dwarf_cu,
- dwarf_cu->DIE(),
+ GetTypes (dwarf_cu->DIE(),
dwarf_cu->GetOffset(),
dwarf_cu->GetNextCompileUnitOffset(),
type_mask,
@@ -371,8 +377,7 @@ SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
if (dwarf_cu)
{
- GetTypes (dwarf_cu,
- dwarf_cu->DIE(),
+ GetTypes (dwarf_cu->DIE(),
0,
UINT32_MAX,
type_mask,
@@ -381,76 +386,15 @@ SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
}
}
}
-// if (m_using_apple_tables)
-// {
-// DWARFMappedHash::MemoryTable *apple_types = m_apple_types_ap.get();
-// if (apple_types)
-// {
-// apple_types->ForEach([this, &type_set, apple_types, type_mask](const DWARFMappedHash::DIEInfoArray &die_info_array) -> bool {
-//
-// for (auto die_info: die_info_array)
-// {
-// bool add_type = TagMatchesTypeMask (type_mask, 0);
-// if (!add_type)
-// {
-// dw_tag_t tag = die_info.tag;
-// if (tag == 0)
-// {
-// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_info.offset, NULL);
-// tag = die->Tag();
-// }
-// add_type = TagMatchesTypeMask (type_mask, tag);
-// }
-// if (add_type)
-// {
-// Type *type = ResolveTypeUID(die_info.offset);
-//
-// if (type_set.find(type) == type_set.end())
-// type_set.insert(type);
-// }
-// }
-// return true; // Keep iterating
-// });
-// }
-// }
-// else
-// {
-// if (!m_indexed)
-// Index ();
-//
-// m_type_index.ForEach([this, &type_set, type_mask](const char *name, uint32_t die_offset) -> bool {
-//
-// bool add_type = TagMatchesTypeMask (type_mask, 0);
-//
-// if (!add_type)
-// {
-// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_offset, NULL);
-// if (die)
-// {
-// const dw_tag_t tag = die->Tag();
-// add_type = TagMatchesTypeMask (type_mask, tag);
-// }
-// }
-//
-// if (add_type)
-// {
-// Type *type = ResolveTypeUID(die_offset);
-//
-// if (type_set.find(type) == type_set.end())
-// type_set.insert(type);
-// }
-// return true; // Keep iterating
-// });
-// }
-
- std::set<ClangASTType> clang_type_set;
+
+ std::set<CompilerType> compiler_type_set;
size_t num_types_added = 0;
for (Type *type : type_set)
{
- ClangASTType clang_type = type->GetClangForwardType();
- if (clang_type_set.find(clang_type) == clang_type_set.end())
+ CompilerType compiler_type = type->GetForwardCompilerType ();
+ if (compiler_type_set.find(compiler_type) == compiler_type_set.end())
{
- clang_type_set.insert(clang_type);
+ compiler_type_set.insert(compiler_type);
type_list.Insert (type->shared_from_this());
++num_types_added;
}
@@ -463,13 +407,13 @@ SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
// Gets the first parent that is a lexical block, function or inlined
// subroutine, or compile unit.
//----------------------------------------------------------------------
-static const DWARFDebugInfoEntry *
-GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
+DWARFDIE
+SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
{
- const DWARFDebugInfoEntry *die;
- for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
+ DWARFDIE die;
+ for (die = child_die.GetParent(); die; die = die.GetParent())
{
- dw_tag_t tag = die->Tag();
+ dw_tag_t tag = die.Tag();
switch (tag)
{
@@ -480,7 +424,7 @@ GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
return die;
}
}
- return NULL;
+ return DWARFDIE();
}
@@ -489,13 +433,12 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
m_debug_map_module_wp (),
m_debug_map_symfile (NULL),
- m_clang_tu_decl (NULL),
- m_flags(),
m_data_debug_abbrev (),
m_data_debug_aranges (),
m_data_debug_frame (),
m_data_debug_info (),
m_data_debug_line (),
+ m_data_debug_macro (),
m_data_debug_loc (),
m_data_debug_ranges (),
m_data_debug_str (),
@@ -518,7 +461,6 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
m_type_index(),
m_namespace_index(),
m_indexed (false),
- m_is_external_ast_source (false),
m_using_apple_tables (false),
m_fetched_external_modules (false),
m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
@@ -529,12 +471,6 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
SymbolFileDWARF::~SymbolFileDWARF()
{
- if (m_is_external_ast_source)
- {
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
- module_sp->GetClangASTContext().RemoveExternalSource ();
- }
}
static const ConstString &
@@ -552,36 +488,31 @@ SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
return m_unique_ast_type_map;
}
-ClangASTContext &
-SymbolFileDWARF::GetClangASTContext ()
+TypeSystem *
+SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
{
- if (GetDebugMapSymfile ())
- return m_debug_map_symfile->GetClangASTContext ();
-
- ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
- if (!m_is_external_ast_source)
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ TypeSystem *type_system;
+ if (debug_map_symfile)
{
- m_is_external_ast_source = true;
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
- new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
- SymbolFileDWARF::CompleteObjCInterfaceDecl,
- SymbolFileDWARF::FindExternalVisibleDeclsByName,
- SymbolFileDWARF::LayoutRecordType,
- this));
- ast.SetExternalSource (ast_source_ap);
+ type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
}
- return ast;
+ else
+ {
+ type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ }
+ return type_system;
}
void
SymbolFileDWARF::InitializeObject()
{
- // Install our external AST source callbacks so we can complete Clang types.
ModuleSP module_sp (m_obj_file->GetModule());
if (module_sp)
{
const SectionList *section_list = module_sp->GetSectionList();
-
const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
// Memory map the DWARF mach-o segment so we have everything mmap'ed
@@ -589,19 +520,24 @@ SymbolFileDWARF::InitializeObject()
if (section)
m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
}
+
get_apple_names_data();
- if (m_data_apple_names.GetByteSize() > 0)
+ if (m_data_apple_names.m_data.GetByteSize() > 0)
{
- m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
+ m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data,
+ get_debug_str_data(),
+ ".apple_names"));
if (m_apple_names_ap->IsValid())
m_using_apple_tables = true;
else
m_apple_names_ap.reset();
}
get_apple_types_data();
- if (m_data_apple_types.GetByteSize() > 0)
+ if (m_data_apple_types.m_data.GetByteSize() > 0)
{
- m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
+ m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data,
+ get_debug_str_data(),
+ ".apple_types"));
if (m_apple_types_ap->IsValid())
m_using_apple_tables = true;
else
@@ -609,9 +545,11 @@ SymbolFileDWARF::InitializeObject()
}
get_apple_namespaces_data();
- if (m_data_apple_namespaces.GetByteSize() > 0)
+ if (m_data_apple_namespaces.m_data.GetByteSize() > 0)
{
- m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
+ m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data,
+ get_debug_str_data(),
+ ".apple_namespaces"));
if (m_apple_namespaces_ap->IsValid())
m_using_apple_tables = true;
else
@@ -619,9 +557,11 @@ SymbolFileDWARF::InitializeObject()
}
get_apple_objc_data();
- if (m_data_apple_objc.GetByteSize() > 0)
+ if (m_data_apple_objc.m_data.GetByteSize() > 0)
{
- m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
+ m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data,
+ get_debug_str_data(),
+ ".apple_objc"));
if (m_apple_objc_ap->IsValid())
m_using_apple_tables = true;
else
@@ -663,46 +603,10 @@ SymbolFileDWARF::CalculateAbilities ()
section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
if (section)
debug_abbrev_file_size = section->GetFileSize();
- else
- m_flags.Set (flagsGotDebugAbbrevData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugArangesData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugFrameData);
section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
if (section)
debug_line_file_size = section->GetFileSize();
- else
- m_flags.Set (flagsGotDebugLineData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugLocData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugMacInfoData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugPubNamesData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugPubTypesData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugRangesData);
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
- if (!section)
- m_flags.Set (flagsGotDebugStrData);
}
else
{
@@ -737,104 +641,128 @@ SymbolFileDWARF::CalculateAbilities ()
}
const DWARFDataExtractor&
-SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
+SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment)
{
- if (m_flags.IsClear (got_flag))
+ std::call_once(data_segment.m_flag,
+ &SymbolFileDWARF::LoadSectionData,
+ this,
+ sect_type,
+ std::ref(data_segment.m_data));
+ return data_segment.m_data;
+}
+
+void
+SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
+{
+ ModuleSP module_sp (m_obj_file->GetModule());
+ const SectionList *section_list = module_sp->GetSectionList();
+ if (section_list)
{
- ModuleSP module_sp (m_obj_file->GetModule());
- m_flags.Set (got_flag);
- const SectionList *section_list = module_sp->GetSectionList();
- if (section_list)
+ SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
+ if (section_sp)
{
- SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
- if (section_sp)
+ // See if we memory mapped the DWARF segment?
+ if (m_dwarf_data.GetByteSize())
{
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize())
- {
- data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
- }
- else
- {
- if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
- data.Clear();
- }
+ data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
+ }
+ else
+ {
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
+ data.Clear();
}
}
}
- return data;
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_abbrev_data()
{
- return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
+ return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
+}
+
+const DWARFDataExtractor&
+SymbolFileDWARF::get_debug_addr_data()
+{
+ return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_aranges_data()
{
- return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
+ return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_frame_data()
{
- return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
+ return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_info_data()
{
- return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
+ return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_line_data()
{
- return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
+ return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line);
+}
+
+const DWARFDataExtractor&
+SymbolFileDWARF::get_debug_macro_data()
+{
+ return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_loc_data()
{
- return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
+ return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_ranges_data()
{
- return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
+ return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_debug_str_data()
{
- return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
+ return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str);
+}
+
+const DWARFDataExtractor&
+SymbolFileDWARF::get_debug_str_offsets_data()
+{
+ return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_apple_names_data()
{
- return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
+ return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_apple_types_data()
{
- return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
+ return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_apple_namespaces_data()
{
- return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
+ return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
}
const DWARFDataExtractor&
SymbolFileDWARF::get_apple_objc_data()
{
- return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
+ return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc);
}
@@ -889,6 +817,9 @@ SymbolFileDWARF::DebugInfo() const
DWARFCompileUnit*
SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
{
+ if (!comp_unit)
+ return nullptr;
+
DWARFDebugInfo* info = DebugInfo();
if (info)
{
@@ -900,7 +831,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
// TODO: modify to support LTO .o files where each .o file might
// have multiple DW_TAG_compile_unit tags.
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0);
if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
dwarf_cu->SetUserData(comp_unit);
return dwarf_cu;
@@ -910,7 +841,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
// Just a normal DWARF file whose user ID for the compile unit is
// the DWARF offset itself
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
dwarf_cu->SetUserData(comp_unit);
return dwarf_cu;
@@ -958,7 +889,11 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
}
else
{
- if (GetDebugMapSymfile ())
+ if (dwarf_cu->GetSymbolFileDWARF() != this)
+ {
+ return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
+ }
+ else if (GetDebugMapSymfile ())
{
// Let the debug map create the compile unit
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
@@ -969,20 +904,18 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
ModuleSP module_sp (m_obj_file->GetModule());
if (module_sp)
{
- const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
if (cu_die)
{
- FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false};
+ FileSpec cu_file_spec{cu_die.GetName(), false};
if (cu_file_spec)
{
// If we have a full path to the compile unit, we don't need to resolve
// the file. This can be expensive e.g. when the source files are NFS mounted.
if (cu_file_spec.IsRelative())
{
- // DWARF2/3 suggests the form hostname:pathname for compilation directory.
- // Remove the host part if present.
- const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)};
- cu_file_spec.PrependPathComponent(removeHostnameFromPathname(cu_comp_dir));
+ const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
+ cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
}
std::string remapped_file;
@@ -990,13 +923,15 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
cu_file_spec.SetFile(remapped_file, false);
}
- LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
+ LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
+ bool is_optimized = dwarf_cu->GetIsOptimized ();
cu_sp.reset(new CompileUnit (module_sp,
dwarf_cu,
cu_file_spec,
- MakeUserID(dwarf_cu->GetOffset()),
- cu_language));
+ dwarf_cu->GetID(),
+ cu_language,
+ is_optimized));
if (cu_sp)
{
// If we just created a compile unit with an invalid file spec, try and get the
@@ -1053,137 +988,20 @@ SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
}
Function *
-SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
+SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
{
- DWARFDebugRanges::RangeList func_ranges;
- const char *name = NULL;
- const char *mangled = NULL;
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- DWARFExpression frame_base;
-
- assert (die->Tag() == DW_TAG_subprogram);
-
- if (die->Tag() != DW_TAG_subprogram)
- return NULL;
-
- if (die->GetDIENamesAndRanges (this,
- dwarf_cu,
- name,
- mangled,
- func_ranges,
- decl_file,
- decl_line,
- decl_column,
- call_file,
- call_line,
- call_column,
- &frame_base))
+ if (die.IsValid())
{
- // Union of all ranges in the function DIE (if the function is discontiguous)
- AddressRange func_range;
- lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
- lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
- if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
- {
- ModuleSP module_sp (m_obj_file->GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
- if (func_range.GetBaseAddress().IsValid())
- func_range.SetByteSize(highest_func_addr - lowest_func_addr);
- }
+ TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
- if (func_range.GetBaseAddress().IsValid())
+ if (type_system)
{
- Mangled func_name;
- if (mangled)
- func_name.SetValue(ConstString(mangled), true);
- else if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
- LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) &&
- name && strcmp(name, "main") != 0)
- {
- // If the mangled name is not present in the DWARF, generate the demangled name
- // using the decl context. We skip if the function is "main" as its name is
- // never mangled.
- bool is_static = false;
- bool is_variadic = false;
- unsigned type_quals = 0;
- std::vector<ClangASTType> param_types;
- std::vector<clang::ParmVarDecl*> param_decls;
- const DWARFDebugInfoEntry *decl_ctx_die = NULL;
- DWARFDeclContext decl_ctx;
- StreamString sstr;
-
- die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
- sstr << decl_ctx.GetQualifiedName();
-
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu,
- die,
- &decl_ctx_die);
- ParseChildParameters(sc,
- containing_decl_ctx,
- dwarf_cu,
- die,
- true,
- is_static,
- is_variadic,
- param_types,
- param_decls,
- type_quals);
- sstr << "(";
- for (size_t i = 0; i < param_types.size(); i++)
- {
- if (i > 0)
- sstr << ", ";
- sstr << param_types[i].GetTypeName();
- }
- if (is_variadic)
- sstr << ", ...";
- sstr << ")";
- if (type_quals & clang::Qualifiers::Const)
- sstr << " const";
-
- func_name.SetValue(ConstString(sstr.GetData()), false);
- }
- else
- func_name.SetValue(ConstString(name), false);
-
- FunctionSP func_sp;
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line,
- decl_column));
-
- // Supply the type _only_ if it has already been parsed
- Type *func_type = m_die_to_type.lookup (die);
-
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
-
- if (FixupAddress (func_range.GetBaseAddress()))
- {
- const user_id_t func_user_id = MakeUserID(die->GetOffset());
- func_sp.reset(new Function (sc.comp_unit,
- MakeUserID(func_user_id), // UserID is the DIE offset
- MakeUserID(func_user_id),
- func_name,
- func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
- }
- }
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->ParseFunctionFromDWARF(sc, die);
}
}
- return NULL;
+ return nullptr;
}
bool
@@ -1203,12 +1021,9 @@ SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
assert (sc.comp_unit);
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
- {
- const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
- if (die)
- return DWARFCompileUnit::LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
- }
- return eLanguageTypeUnknown;
+ return dwarf_cu->GetLanguageType();
+ else
+ return eLanguageTypeUnknown;
}
size_t
@@ -1224,10 +1039,10 @@ SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
size_t func_idx;
for (func_idx = 0; func_idx < num_functions; ++func_idx)
{
- const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
- if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
+ DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
+ if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
{
- if (ParseCompileUnitFunction(sc, dwarf_cu, die))
+ if (ParseCompileUnitFunction(sc, die))
++functions_added;
}
}
@@ -1243,17 +1058,13 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
- const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
if (cu_die)
{
- const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
-
- // DWARF2/3 suggests the form hostname:pathname for compilation directory.
- // Remove the host part if present.
- cu_comp_dir = removeHostnameFromPathname(cu_comp_dir);
+ const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
- dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+ const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
// All file indexes in DWARF are one based and a file of index zero is
// supposed to be the compile unit itself.
@@ -1275,9 +1086,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);
}
}
}
@@ -1288,6 +1099,7 @@ struct ParseDWARFLineTableCallbackInfo
{
LineTable* line_table;
std::unique_ptr<LineSequence> sequence_ap;
+ lldb::addr_t addr_mask;
};
//----------------------------------------------------------------------
@@ -1317,7 +1129,7 @@ ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta
assert(info->sequence_ap.get());
}
line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
- state.address,
+ state.address & info->addr_mask,
state.line,
state.column,
state.file,
@@ -1346,10 +1158,10 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
- const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
if (dwarf_cu_die)
{
- const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+ const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
if (cu_line_offset != DW_INVALID_OFFSET)
{
std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
@@ -1357,6 +1169,28 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
{
ParseDWARFLineTableCallbackInfo info;
info.line_table = line_table_ap.get();
+
+ /*
+ * MIPS:
+ * The SymbolContext may not have a valid target, thus we may not be able
+ * to call Address::GetOpcodeLoadAddress() which would clear the bit #0
+ * for MIPS. Use ArchSpec to clear the bit #0.
+ */
+ ArchSpec arch;
+ GetObjectFile()->GetArchitecture(arch);
+ switch (arch.GetMachine())
+ {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ info.addr_mask = ~((lldb::addr_t)1);
+ break;
+ default:
+ info.addr_mask = ~((lldb::addr_t)0);
+ break;
+ }
+
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
if (m_debug_map_symfile)
@@ -1379,21 +1213,63 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
return false;
}
+lldb_private::DebugMacrosSP
+SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset)
+{
+ auto iter = m_debug_macros_map.find(*offset);
+ if (iter != m_debug_macros_map.end())
+ return iter->second;
+
+ const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
+ if (debug_macro_data.GetByteSize() == 0)
+ return DebugMacrosSP();
+
+ lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
+ m_debug_macros_map[*offset] = debug_macros_sp;
+
+ const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
+ DWARFDebugMacroEntry::ReadMacroEntries(
+ debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp);
+
+ return debug_macros_sp;
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc)
+{
+ assert (sc.comp_unit);
+
+ DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu == nullptr)
+ return false;
+
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (!dwarf_cu_die)
+ return false;
+
+ lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ return false;
+
+ sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
+
+ return true;
+}
+
size_t
-SymbolFileDWARF::ParseFunctionBlocks
-(
- const SymbolContext& sc,
- Block *parent_block,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *die,
- addr_t subprogram_low_pc,
- uint32_t depth
-)
+SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
+ Block *parent_block,
+ const DWARFDIE &orig_die,
+ addr_t subprogram_low_pc,
+ uint32_t depth)
{
size_t blocks_added = 0;
- while (die != NULL)
+ DWARFDIE die = orig_die;
+ while (die)
{
- dw_tag_t tag = die->Tag();
+ dw_tag_t tag = die.Tag();
switch (tag)
{
@@ -1415,11 +1291,11 @@ SymbolFileDWARF::ParseFunctionBlocks
}
else
{
- BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
+ BlockSP block_sp(new Block (die.GetID()));
parent_block->AddChild(block_sp);
block = block_sp.get();
}
- DWARFDebugRanges::RangeList ranges;
+ DWARFRangeList ranges;
const char *name = NULL;
const char *mangled_name = NULL;
@@ -1429,13 +1305,11 @@ SymbolFileDWARF::ParseFunctionBlocks
int call_file = 0;
int call_line = 0;
int call_column = 0;
- if (die->GetDIENamesAndRanges (this,
- dwarf_cu,
- name,
- mangled_name,
- ranges,
- decl_file, decl_line, decl_column,
- call_file, call_line, call_column))
+ if (die.GetDIENamesAndRanges (name,
+ mangled_name,
+ ranges,
+ decl_file, decl_line, decl_column,
+ call_file, call_line, call_column, nullptr))
{
if (tag == DW_TAG_subprogram)
{
@@ -1461,7 +1335,7 @@ SymbolFileDWARF::ParseFunctionBlocks
const size_t num_ranges = ranges.GetSize();
for (size_t i = 0; i<num_ranges; ++i)
{
- const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
const addr_t range_base = range.GetRangeBase();
if (range_base >= subprogram_low_pc)
block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
@@ -1493,12 +1367,11 @@ SymbolFileDWARF::ParseFunctionBlocks
++blocks_added;
- if (die->HasChildren())
+ if (die.HasChildren())
{
blocks_added += ParseFunctionBlocks (sc,
block,
- dwarf_cu,
- die->GetFirstChild(),
+ die.GetFirstChild(),
subprogram_low_pc,
depth + 1);
}
@@ -1514,278 +1387,21 @@ SymbolFileDWARF::ParseFunctionBlocks
// DW_TAG_subprogram DIE
if (depth == 0)
- die = NULL;
+ die.Clear();
else
- die = die->GetSibling();
+ die = die.GetSibling();
}
return blocks_added;
}
bool
-SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *die,
- ClangASTContext::TemplateParameterInfos &template_param_infos)
-{
- const dw_tag_t tag = die->Tag();
-
- switch (tag)
- {
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- {
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
-
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_attributes = die->GetAttributes (this,
- dwarf_cu,
- fixed_form_sizes,
- attributes);
- const char *name = NULL;
- Type *lldb_type = NULL;
- ClangASTType clang_type;
- uint64_t uval64 = 0;
- bool uval64_valid = false;
- if (num_attributes > 0)
- {
- DWARFFormValue form_value;
- for (size_t i=0; i<num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
-
- switch (attr)
- {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- name = form_value.AsCString(&get_debug_str_data());
- break;
-
- case DW_AT_type:
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- const dw_offset_t type_die_offset = form_value.Reference();
- lldb_type = ResolveTypeUID(type_die_offset);
- if (lldb_type)
- clang_type = lldb_type->GetClangForwardType();
- }
- break;
-
- case DW_AT_const_value:
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- uval64_valid = true;
- uval64 = form_value.Unsigned();
- }
- break;
- default:
- break;
- }
- }
-
- clang::ASTContext *ast = GetClangASTContext().getASTContext();
- if (!clang_type)
- clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);
-
- if (clang_type)
- {
- bool is_signed = false;
- if (name && name[0])
- template_param_infos.names.push_back(name);
- else
- template_param_infos.names.push_back(NULL);
-
- if (tag == DW_TAG_template_value_parameter &&
- lldb_type != NULL &&
- clang_type.IsIntegerType (is_signed) &&
- uval64_valid)
- {
- llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
- template_param_infos.args.push_back (clang::TemplateArgument (*ast,
- llvm::APSInt(apint),
- clang_type.GetQualType()));
- }
- else
- {
- template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
- }
- }
- else
- {
- return false;
- }
-
- }
- }
- return true;
-
- default:
- break;
- }
- return false;
-}
-
-bool
-SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die,
- ClangASTContext::TemplateParameterInfos &template_param_infos)
-{
-
- if (parent_die == NULL)
- return false;
-
- Args template_parameter_names;
- for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
- die != NULL;
- die = die->GetSibling())
- {
- const dw_tag_t tag = die->Tag();
-
- switch (tag)
- {
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- ParseTemplateDIE (dwarf_cu, die, template_param_infos);
- break;
-
- default:
- break;
- }
- }
- if (template_param_infos.args.empty())
- return false;
- return template_param_infos.args.size() == template_param_infos.names.size();
-}
-
-clang::ClassTemplateDecl *
-SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
- lldb::AccessType access_type,
- const char *parent_name,
- int tag_decl_kind,
- const ClangASTContext::TemplateParameterInfos &template_param_infos)
-{
- if (template_param_infos.IsValid())
- {
- std::string template_basename(parent_name);
- template_basename.erase (template_basename.find('<'));
- ClangASTContext &ast = GetClangASTContext();
-
- return ast.CreateClassTemplateDecl (decl_ctx,
- access_type,
- template_basename.c_str(),
- tag_decl_kind,
- template_param_infos);
- }
- return NULL;
-}
-
-class SymbolFileDWARF::DelayedAddObjCClassProperty
-{
-public:
- DelayedAddObjCClassProperty
- (
- const ClangASTType &class_opaque_type,
- const char *property_name,
- const ClangASTType &property_opaque_type, // The property type is only required if you don't have an ivar decl
- clang::ObjCIvarDecl *ivar_decl,
- const char *property_setter_name,
- const char *property_getter_name,
- uint32_t property_attributes,
- const ClangASTMetadata *metadata
- ) :
- m_class_opaque_type (class_opaque_type),
- m_property_name (property_name),
- m_property_opaque_type (property_opaque_type),
- m_ivar_decl (ivar_decl),
- m_property_setter_name (property_setter_name),
- m_property_getter_name (property_getter_name),
- m_property_attributes (property_attributes)
- {
- if (metadata != NULL)
- {
- m_metadata_ap.reset(new ClangASTMetadata());
- *m_metadata_ap = *metadata;
- }
- }
-
- DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
- {
- *this = rhs;
- }
-
- DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
- {
- m_class_opaque_type = rhs.m_class_opaque_type;
- m_property_name = rhs.m_property_name;
- m_property_opaque_type = rhs.m_property_opaque_type;
- m_ivar_decl = rhs.m_ivar_decl;
- m_property_setter_name = rhs.m_property_setter_name;
- m_property_getter_name = rhs.m_property_getter_name;
- m_property_attributes = rhs.m_property_attributes;
-
- if (rhs.m_metadata_ap.get())
- {
- m_metadata_ap.reset (new ClangASTMetadata());
- *m_metadata_ap = *rhs.m_metadata_ap;
- }
- return *this;
- }
-
- bool
- Finalize()
- {
- return m_class_opaque_type.AddObjCClassProperty (m_property_name,
- m_property_opaque_type,
- m_ivar_decl,
- m_property_setter_name,
- m_property_getter_name,
- m_property_attributes,
- m_metadata_ap.get());
- }
-private:
- ClangASTType m_class_opaque_type;
- const char *m_property_name;
- ClangASTType m_property_opaque_type;
- clang::ObjCIvarDecl *m_ivar_decl;
- const char *m_property_setter_name;
- const char *m_property_getter_name;
- uint32_t m_property_attributes;
- std::unique_ptr<ClangASTMetadata> m_metadata_ap;
-};
-
-struct BitfieldInfo
-{
- uint64_t bit_size;
- uint64_t bit_offset;
-
- BitfieldInfo () :
- bit_size (LLDB_INVALID_ADDRESS),
- bit_offset (LLDB_INVALID_ADDRESS)
- {
- }
-
- void
- Clear()
- {
- bit_size = LLDB_INVALID_ADDRESS;
- bit_offset = LLDB_INVALID_ADDRESS;
- }
-
- bool IsValid ()
- {
- return (bit_size != LLDB_INVALID_ADDRESS) &&
- (bit_offset != LLDB_INVALID_ADDRESS);
- }
-};
-
-
-bool
-SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die)
+SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
{
if (parent_die)
{
- for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+ for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
{
- dw_tag_t tag = die->Tag();
+ dw_tag_t tag = die.Tag();
bool check_virtuality = false;
switch (tag)
{
@@ -1798,7 +1414,7 @@ SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
}
if (check_virtuality)
{
- if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
+ if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
return true;
}
}
@@ -1806,602 +1422,79 @@ SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
return false;
}
-size_t
-SymbolFileDWARF::ParseChildMembers
-(
- const SymbolContext& sc,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die,
- ClangASTType &class_clang_type,
- const LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *>& base_classes,
- std::vector<int>& member_accessibilities,
- DWARFDIECollection& member_function_dies,
- DelayedPropertyList& delayed_properties,
- AccessType& default_accessibility,
- bool &is_a_class,
- LayoutInfo &layout_info
-)
+void
+SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
{
- if (parent_die == NULL)
- return 0;
+ TypeSystem *type_system = decl_ctx.GetTypeSystem();
+ DWARFASTParser *ast_parser = type_system->GetDWARFParser();
+ std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
- size_t count = 0;
- const DWARFDebugInfoEntry *die;
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
- uint32_t member_idx = 0;
- BitfieldInfo last_field_info;
- ModuleSP module = GetObjectFile()->GetModule();
+ for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
+ for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
+ ast_parser->GetDeclForUIDFromDWARF(decl);
+}
- for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+CompilerDecl
+SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
+{
+ if (UserIDMatches(type_uid))
{
- dw_tag_t tag = die->Tag();
-
- switch (tag)
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
{
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- {
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_attributes = die->GetAttributes (this,
- dwarf_cu,
- fixed_form_sizes,
- attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- //DWARFExpression location;
- const char *name = NULL;
- const char *prop_name = NULL;
- const char *prop_getter_name = NULL;
- const char *prop_setter_name = NULL;
- uint32_t prop_attributes = 0;
-
-
- bool is_artificial = false;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
- AccessType accessibility = eAccessNone;
- uint32_t member_byte_offset = UINT32_MAX;
- size_t byte_size = 0;
- size_t bit_offset = 0;
- size_t bit_size = 0;
- bool is_external = false; // On DW_TAG_members, this means the member is static
- uint32_t i;
- for (i=0; i<num_attributes && !is_artificial; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_type: encoding_uid = form_value.Reference(); break;
- case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
- case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
- case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
- case DW_AT_data_member_location:
- if (form_value.BlockData())
- {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
- NULL, // RegisterContext *
- module,
- debug_info_data,
- block_offset,
- block_length,
- eRegisterKindDWARF,
- &initialValue,
- memberOffset,
- NULL))
- {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
- }
- }
- else
- {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
- break;
-
- case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
- case DW_AT_external: is_external = form_value.Boolean(); break;
-
- default:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_mutable:
- case DW_AT_visibility:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- if (prop_name)
- {
- ConstString fixed_getter;
- ConstString fixed_setter;
-
- // Check if the property getter/setter were provided as full
- // names. We want basenames, so we extract them.
-
- if (prop_getter_name && prop_getter_name[0] == '-')
- {
- ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
- prop_getter_name = prop_getter_method.GetSelector().GetCString();
- }
-
- if (prop_setter_name && prop_setter_name[0] == '-')
- {
- ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
- prop_setter_name = prop_setter_method.GetSelector().GetCString();
- }
-
- // If the names haven't been provided, they need to be
- // filled in.
-
- if (!prop_getter_name)
- {
- prop_getter_name = prop_name;
- }
- if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
- {
- StreamString ss;
-
- ss.Printf("set%c%s:",
- toupper(prop_name[0]),
- &prop_name[1]);
-
- fixed_setter.SetCString(ss.GetData());
- prop_setter_name = fixed_setter.GetCString();
- }
- }
-
- // Clang has a DWARF generation bug where sometimes it
- // represents fields that are references with bad byte size
- // and bit size/offset information such as:
- //
- // DW_AT_byte_size( 0x00 )
- // DW_AT_bit_size( 0x40 )
- // DW_AT_bit_offset( 0xffffffffffffffc0 )
- //
- // So check the bit offset to make sure it is sane, and if
- // the values are not sane, remove them. If we don't do this
- // then we will end up with a crash if we try to use this
- // type in an expression when clang becomes unhappy with its
- // recycled debug info.
-
- if (bit_offset > 128)
- {
- bit_size = 0;
- bit_offset = 0;
- }
-
- // FIXME: Make Clang ignore Objective-C accessibility for expressions
- 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;
- }
-
- // Handle static members
- if (is_external && member_byte_offset == UINT32_MAX)
- {
- Type *var_type = ResolveTypeUID(encoding_uid);
-
- if (var_type)
- {
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
- class_clang_type.AddVariableToRecordType (name,
- var_type->GetClangLayoutType(),
- accessibility);
- }
- break;
- }
-
- if (is_artificial == false)
- {
- Type *member_type = ResolveTypeUID(encoding_uid);
-
- clang::FieldDecl *field_decl = NULL;
- if (tag == DW_TAG_member)
- {
- if (member_type)
- {
- if (accessibility == eAccessNone)
- accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
-
- uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
- if (bit_size > 0)
- {
-
- BitfieldInfo this_field_info;
- this_field_info.bit_offset = field_bit_offset;
- this_field_info.bit_size = bit_size;
-
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- if (byte_size == 0)
- byte_size = member_type->GetByteSize();
-
- if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
- {
- this_field_info.bit_offset += byte_size * 8;
- this_field_info.bit_offset -= (bit_offset + bit_size);
- }
- else
- {
- this_field_info.bit_offset += bit_offset;
- }
-
- // Update the field bit offset we will report for layout
- field_bit_offset = this_field_info.bit_offset;
-
- // If the member to be emitted did not start on a character boundary and there is
- // empty space between the last field and this one, then we need to emit an
- // anonymous member filling up the space up to its start. There are three cases
- // here:
- //
- // 1 If the previous member ended on a character boundary, then we can emit an
- // anonymous member starting at the most recent character boundary.
- //
- // 2 If the previous member did not end on a character boundary and the distance
- // from the end of the previous member to the current member is less than a
- // word width, then we can emit an anonymous member starting right after the
- // previous member and right before this member.
- //
- // 3 If the previous member did not end on a character boundary and the distance
- // from the end of the previous member to the current member is greater than
- // or equal a word width, then we act as in Case 1.
-
- const uint64_t character_width = 8;
- const uint64_t word_width = 32;
-
- // Objective-C has invalid DW_AT_bit_offset values in older versions
- // of clang, so we have to be careful and only insert unnamed bitfields
- // if we have a new enough clang.
- bool detect_unnamed_bitfields = true;
-
- if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
- detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
-
- if (detect_unnamed_bitfields)
- {
- BitfieldInfo anon_field_info;
-
- if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
- {
- uint64_t last_field_end = 0;
-
- if (last_field_info.IsValid())
- last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
-
- if (this_field_info.bit_offset != last_field_end)
- {
- if (((last_field_end % character_width) == 0) || // case 1
- (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
- {
- anon_field_info.bit_size = this_field_info.bit_offset % character_width;
- anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
- }
- else // case 2
- {
- anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
- anon_field_info.bit_offset = last_field_end;
- }
- }
- }
-
- if (anon_field_info.IsValid())
- {
- clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
- GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
- accessibility,
- anon_field_info.bit_size);
-
- layout_info.field_offsets.insert(
- std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
- }
- }
- last_field_info = this_field_info;
- }
- else
- {
- last_field_info.Clear();
- }
-
- ClangASTType member_clang_type = member_type->GetClangLayoutType();
-
- {
- // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
- // If the current field is at the end of the structure, then there is definitely no room for extra
- // elements and we override the type to array[0].
-
- ClangASTType member_array_element_type;
- uint64_t member_array_size;
- bool member_array_is_incomplete;
-
- if (member_clang_type.IsArrayType(&member_array_element_type,
- &member_array_size,
- &member_array_is_incomplete) &&
- !member_array_is_incomplete)
- {
- uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
-
- if (member_byte_offset >= parent_byte_size)
- {
- if (member_array_size != 1)
- {
- GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
- MakeUserID(die->GetOffset()),
- name,
- encoding_uid,
- MakeUserID(parent_die->GetOffset()));
- }
-
- member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
- }
- }
- }
-
- field_decl = class_clang_type.AddFieldToRecordType (name,
- member_clang_type,
- accessibility,
- bit_size);
-
- GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
-
- layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
- }
- else
- {
- if (name)
- GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
- MakeUserID(die->GetOffset()),
- name,
- encoding_uid);
- else
- GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
- MakeUserID(die->GetOffset()),
- encoding_uid);
- }
- }
-
- if (prop_name != NULL && member_type)
- {
- clang::ObjCIvarDecl *ivar_decl = NULL;
-
- if (field_decl)
- {
- ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
- assert (ivar_decl != NULL);
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID (MakeUserID(die->GetOffset()));
- delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
- prop_name,
- member_type->GetClangLayoutType(),
- ivar_decl,
- prop_setter_name,
- prop_getter_name,
- prop_attributes,
- &metadata));
-
- if (ivar_decl)
- GetClangASTContext().SetMetadataAsUserID (ivar_decl, MakeUserID(die->GetOffset()));
- }
- }
- }
- ++member_idx;
- }
- break;
-
- case DW_TAG_subprogram:
- // Let the type parsing code handle this one for us.
- member_function_dies.Append (die);
- break;
-
- case DW_TAG_inheritance:
+ DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
+ if (die)
{
- is_a_class = true;
- if (default_accessibility == eAccessNone)
- default_accessibility = eAccessPrivate;
- // TODO: implement DW_TAG_inheritance type parsing
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_attributes = die->GetAttributes (this,
- dwarf_cu,
- fixed_form_sizes,
- attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- DWARFExpression location;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
- AccessType accessibility = default_accessibility;
- bool is_virtual = false;
- bool is_base_of_class = true;
- off_t member_byte_offset = 0;
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_type: encoding_uid = form_value.Reference(); break;
- case DW_AT_data_member_location:
- if (form_value.BlockData())
- {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate (NULL,
- NULL,
- NULL,
- NULL,
- module,
- debug_info_data,
- block_offset,
- block_length,
- eRegisterKindDWARF,
- &initialValue,
- memberOffset,
- NULL))
- {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
- }
- }
- else
- {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
- break;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_virtuality:
- is_virtual = form_value.Boolean();
- break;
-
- case DW_AT_sibling:
- break;
-
- default:
- break;
- }
- }
- }
-
- Type *base_class_type = ResolveTypeUID(encoding_uid);
- if (base_class_type == NULL)
- {
- GetObjectFile()->GetModule()->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
- die->GetOffset(),
- encoding_uid,
- parent_die->GetOffset());
- break;
- }
-
- ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
- assert (base_class_clang_type);
- if (class_language == eLanguageTypeObjC)
- {
- class_clang_type.SetObjCSuperClass(base_class_clang_type);
- }
- else
- {
- base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
- is_virtual,
- is_base_of_class));
-
- if (is_virtual)
- {
- // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
- // give us a constant offset, but gives us a DWARF expressions that requires an actual object
- // in memory. the DW_AT_data_member_location for a virtual base class looks like:
- // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
- // Given this, there is really no valid response we can give to clang for virtual base
- // class offsets, and this should eventually be removed from LayoutRecordType() in the external
- // AST source in clang.
- }
- else
- {
- layout_info.base_offsets.insert(
- std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(),
- clang::CharUnits::fromQuantity(member_byte_offset)));
- }
- }
- }
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclForUIDFromDWARF(die);
}
- break;
-
- default:
- break;
}
}
-
- return count;
+ return CompilerDecl();
}
-
-clang::DeclContext*
-SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
+CompilerDeclContext
+SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
{
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info && UserIDMatches(type_uid))
+ if (UserIDMatches(type_uid))
{
- DWARFCompileUnitSP cu_sp;
- const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
- if (die)
- return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
+ {
+ DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
+ if (die)
+ {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
+ }
+ }
}
- return NULL;
+ return CompilerDeclContext();
}
-clang::DeclContext*
-SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
+CompilerDeclContext
+SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
{
if (UserIDMatches(type_uid))
- return GetClangDeclContextForDIEOffset (sc, type_uid);
- return NULL;
+ {
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
+ {
+ DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
+ if (die)
+ {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ }
+ }
+ }
+ return CompilerDeclContext();
}
+
Type*
SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
{
@@ -2410,418 +1503,143 @@ SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
DWARFDebugInfo* debug_info = DebugInfo();
if (debug_info)
{
- DWARFCompileUnitSP cu_sp;
- const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
- const bool assert_not_being_parsed = true;
- return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
+ DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
+ if (type_die)
+ {
+ const bool assert_not_being_parsed = true;
+ return ResolveTypeUID (type_die, assert_not_being_parsed);
+ }
}
}
return NULL;
}
Type*
-SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
+SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
{
- if (die != NULL)
+ if (die)
{
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, cu));
+ die.GetOffset(),
+ die.GetTagAsCString(),
+ die.GetName());
// We might be coming in in the middle of a type tree (a class
// withing a class, an enum within a class), so parse any needed
// parent DIEs before we get to this one...
- const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
- switch (decl_ctx_die->Tag())
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
+ if (decl_ctx_die)
{
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
+ if (log)
{
- // Get the type, which could be a forward declaration
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, cu),
- decl_ctx_die->GetOffset());
-//
-// Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
-// if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
-// {
-// if (log)
-// GetObjectFile()->GetModule()->LogMessage (log,
-// "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function",
-// die->GetOffset(),
-// DW_TAG_value_to_name(die->Tag()),
-// die->GetName(this, cu),
-// decl_ctx_die->GetOffset());
-// // Ask the type to complete itself if it already hasn't since if we
-// // want a function (method or static) from a class, the class must
-// // create itself and add it's own methods and class functions.
-// if (parent_type)
-// parent_type->GetClangFullType();
-// }
- }
- break;
+ switch (decl_ctx_die.Tag())
+ {
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ {
+ // Get the type, which could be a forward declaration
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log,
+ "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
+ die.GetOffset(),
+ die.GetTagAsCString(),
+ die.GetName(),
+ decl_ctx_die.GetOffset());
+ }
+ break;
- default:
- break;
+ default:
+ break;
+ }
+ }
}
- return ResolveType (cu, die);
+ return ResolveType (die);
}
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.
+// can resolve a compiler_type.
bool
-SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
+SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
{
- ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
- const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
- return die != NULL;
+ CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ 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::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
+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.
- ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
- const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
- if (die == NULL)
+ CompilerType compiler_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(compiler_type);
+ auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (die_it == GetForwardDeclClangTypeToDie().end())
{
// We have already resolved this type...
return true;
}
+
+ DWARFDebugInfo* debug_info = DebugInfo();
+ DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
+
+ assert(UserIDMatches(die_it->getSecond().GetUID()) && "CompleteType called on the wrong SymbolFile");
+
// Once we start resolving this type, remove it from the forward declaration
// 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 (clang_type_no_qualifiers.GetOpaqueQualType());
-
- // Disable external storage for this type so we don't get anymore
- // clang::ExternalASTSource queries for this type.
- clang_type.SetHasExternalStorage (false);
-
- DWARFDebugInfo* debug_info = DebugInfo();
+ GetForwardDeclClangTypeToDie().erase (die_it);
- DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
- Type *type = m_die_to_type.lookup (die);
-
- const dw_tag_t tag = die->Tag();
+ Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
if (log)
GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
"0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- MakeUserID(die->GetOffset()),
- DW_TAG_value_to_name(tag),
+ dwarf_die.GetID(),
+ dwarf_die.GetTagAsCString(),
type->GetName().AsCString());
- assert (clang_type);
- DWARFDebugInfoEntry::Attributes attributes;
-
- switch (tag)
- {
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- LayoutInfo layout_info;
-
- {
- if (die->HasChildren())
- {
- LanguageType class_language = eLanguageTypeUnknown;
- if (clang_type.IsObjCObjectOrInterfaceType())
- {
- class_language = eLanguageTypeObjC;
- // For objective C we don't start the definition when
- // the class is created.
- clang_type.StartTagDeclarationDefinition ();
- }
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type)
- {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_union_type)
- {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_class_type)
- {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
-
- SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
- std::vector<clang::CXXBaseSpecifier *> base_classes;
- std::vector<int> member_accessibilities;
- bool is_a_class = false;
- // Parse members and base classes first
- DWARFDIECollection member_function_dies;
-
- DelayedPropertyList delayed_properties;
- ParseChildMembers (sc,
- dwarf_cu,
- 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();
- if (num_functions > 0)
- {
- for (size_t i=0; i<num_functions; ++i)
- {
- ResolveType(dwarf_cu, member_function_dies.GetDIEPtrAtIndex(i));
- }
- }
-
- if (class_language == eLanguageTypeObjC)
- {
- ConstString class_name (clang_type.GetTypeName());
- if (class_name)
- {
- DIEArray method_die_offsets;
- if (m_using_apple_tables)
- {
- if (m_apple_objc_ap.get())
- m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_objc_class_selectors_index.Find (class_name, method_die_offsets);
- }
-
- if (!method_die_offsets.empty())
- {
- DWARFDebugInfo* debug_info = DebugInfo();
-
- DWARFCompileUnit* method_cu = NULL;
- const size_t num_matches = method_die_offsets.size();
- for (size_t i=0; i<num_matches; ++i)
- {
- const dw_offset_t die_offset = method_die_offsets[i];
- DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
-
- if (method_die)
- ResolveType (method_cu, method_die);
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
- die_offset, class_name.GetCString());
- }
- }
- }
- }
-
- for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
- pi != pe;
- ++pi)
- pi->Finalize();
- }
- }
-
- // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
- // need to tell the clang type it is actually a class.
- if (class_language != eLanguageTypeObjC)
- {
- if (is_a_class && tag_decl_kind != clang::TTK_Class)
- clang_type.SetTagTypeKind (clang::TTK_Class);
- }
-
- // Since DW_TAG_structure_type gets used for both classes
- // and structures, we may need to set any DW_TAG_member
- // fields to have a "private" access if none was specified.
- // When we parsed the child members we tracked that actual
- // accessibility value for each DW_TAG_member in the
- // "member_accessibilities" array. If the value for the
- // member is zero, then it was set to the "default_accessibility"
- // which for structs was "public". Below we correct this
- // by setting any fields to "private" that weren't correctly
- // set.
- if (is_a_class && !member_accessibilities.empty())
- {
- // This is a class and all members that didn't have
- // their access specified are private.
- clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
- &member_accessibilities.front(),
- member_accessibilities.size());
- }
-
- if (!base_classes.empty())
- {
- // Make sure all base classes refer to complete types and not
- // forward declarations. If we don't do this, clang will crash
- // with an assertion in the call to clang_type.SetBaseClassesForClassType()
- bool base_class_error = false;
- for (auto &base_class : base_classes)
- {
- clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
- if (type_source_info)
- {
- ClangASTType base_class_type (GetClangASTContext().getASTContext(), type_source_info->getType());
- if (base_class_type.GetCompleteType() == false)
- {
- if (!base_class_error)
- {
- GetObjectFile()->GetModule()->ReportError ("DWARF DIE at 0x%8.8x for class '%s' has a base class '%s' that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
- die->GetOffset(),
- die->GetName(this, dwarf_cu),
- base_class_type.GetTypeName().GetCString(),
- sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
- }
- // 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.
- base_class_type.StartTagDeclarationDefinition ();
- base_class_type.CompleteTagDeclarationDefinition ();
- }
- }
- }
- clang_type.SetBaseClassesForClassType (&base_classes.front(),
- base_classes.size());
-
- // Clang will copy each CXXBaseSpecifier in "base_classes"
- // so we have to free them all.
- ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
- base_classes.size());
- }
- }
- }
-
- clang_type.BuildIndirectFields ();
- clang_type.CompleteTagDeclarationDefinition ();
-
- if (!layout_info.field_offsets.empty() ||
- !layout_info.base_offsets.empty() ||
- !layout_info.vbase_offsets.empty() )
- {
- if (type)
- layout_info.bit_size = type->GetByteSize() * 8;
- if (layout_info.bit_size == 0)
- layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
-
- clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
- if (record_decl)
- {
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
- static_cast<void*>(clang_type.GetOpaqueQualType()),
- static_cast<void*>(record_decl),
- layout_info.bit_size,
- layout_info.alignment,
- static_cast<uint32_t>(layout_info.field_offsets.size()),
- static_cast<uint32_t>(layout_info.base_offsets.size()),
- static_cast<uint32_t>(layout_info.vbase_offsets.size()));
-
- uint32_t idx;
- {
- llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
- end = layout_info.field_offsets.end();
- for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
- {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = "
- "{ bit_offset=%u, name='%s' }",
- static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
- static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str());
- }
- }
-
- {
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
- base_end = layout_info.base_offsets.end();
- for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end;
- ++base_pos, ++idx)
- {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] "
- "= { byte_offset=%u, name='%s' }",
- clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
- base_pos->first->getNameAsString().c_str());
- }
- }
- {
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
- vbase_end = layout_info.vbase_offsets.end();
- for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end;
- ++vbase_pos, ++idx)
- {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) "
- "vbase[%u] = { byte_offset=%u, name='%s' }",
- static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
- static_cast<uint32_t>(vbase_pos->second.getQuantity()),
- vbase_pos->first->getNameAsString().c_str());
- }
- }
- }
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
- }
- }
- }
-
- return (bool)clang_type;
-
- case DW_TAG_enumeration_type:
- clang_type.StartTagDeclarationDefinition ();
- if (die->HasChildren())
- {
- SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
- bool is_signed = false;
- clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
- }
- clang_type.CompleteTagDeclarationDefinition ();
- return (bool)clang_type;
-
- default:
- assert(false && "not a forward clang type decl!");
- break;
- }
+ assert (compiler_type);
+ DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
return false;
}
Type*
-SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
+SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
{
- if (type_die != NULL)
+ if (die)
{
- Type *type = m_die_to_type.lookup (type_die);
+ Type *type = GetDIEToType().lookup (die.GetDIE());
if (type == NULL)
- type = GetTypeForDIE (dwarf_cu, type_die).get();
+ type = GetTypeForDIE (die, resolve_function_context).get();
if (assert_not_being_parsed)
{
@@ -2829,15 +1647,15 @@ SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEn
return type;
GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
- type_die->GetOffset(),
- DW_TAG_value_to_name(type_die->Tag()),
- type_die->GetName(this, dwarf_cu));
+ die.GetOffset(),
+ die.GetTagAsCString(),
+ die.GetName());
}
else
return type;
}
- return NULL;
+ return nullptr;
}
CompileUnit*
@@ -2853,26 +1671,60 @@ SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32
return (CompileUnit*)dwarf_cu->GetUserData();
}
+size_t
+SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
+{
+ method_die_offsets.clear();
+ if (m_using_apple_tables)
+ {
+ if (m_apple_objc_ap.get())
+ m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
+ }
+ else
+ {
+ if (!m_indexed)
+ Index ();
+
+ m_objc_class_selectors_index.Find (class_name, method_die_offsets);
+ }
+ return method_die_offsets.size();
+}
+
bool
-SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
+SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
{
sc.Clear(false);
- // Check if the symbol vendor already knows about this compile unit?
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
- sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, dwarf_cu, func_die);
-
- if (sc.function)
- {
- sc.module_sp = sc.function->CalculateSymbolContextModule();
- return true;
+ if (die)
+ {
+ // Check if the symbol vendor already knows about this compile unit?
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+
+ sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
+ if (sc.function == NULL)
+ sc.function = ParseCompileUnitFunction(sc, die);
+
+ if (sc.function)
+ {
+ sc.module_sp = sc.function->CalculateSymbolContextModule();
+ return true;
+ }
}
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()
{
@@ -2881,47 +1733,33 @@ SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
m_fetched_external_modules = true;
DWARFDebugInfo * debug_info = DebugInfo();
- debug_info->GetNumCompileUnits();
-
+
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
{
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
- if (die && die->HasChildren() == false)
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (die && die.HasChildren() == false)
{
- const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX);
- const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, 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;
}
}
}
@@ -3025,7 +1863,7 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
else
{
uint32_t cu_idx = DW_INVALID_INDEX;
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
+ DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
if (dwarf_cu)
{
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
@@ -3036,22 +1874,16 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
bool force_check_line_table = false;
if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
{
- DWARFDebugInfoEntry *function_die = NULL;
- DWARFDebugInfoEntry *block_die = NULL;
- if (resolve_scope & eSymbolContextBlock)
- {
- dwarf_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
- }
- else
- {
- dwarf_cu->LookupAddress(file_vm_addr, &function_die, NULL);
- }
-
- if (function_die != NULL)
+ DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die)
{
- sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
+ sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
+ sc.function = ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function && (resolve_scope & eSymbolContextBlock))
+ block_die = function_die.LookupDeepestBlock(file_vm_addr);
}
else
{
@@ -3072,10 +1904,10 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
{
Block& block = sc.function->GetBlock (true);
- if (block_die != NULL)
- sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
+ if (block_die)
+ sc.block = block.FindBlockByID (block_die.GetID());
else
- sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
+ sc.block = block.FindBlockByID (function_die.GetID());
if (sc.block)
resolved |= eSymbolContextBlock;
}
@@ -3190,25 +2022,26 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line,
const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
if (file_vm_addr != LLDB_INVALID_ADDRESS)
{
- DWARFDebugInfoEntry *function_die = NULL;
- DWARFDebugInfoEntry *block_die = NULL;
- dwarf_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
-
- if (function_die != NULL)
+ DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die)
{
- sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
+ sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
+ sc.function = ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function && (resolve_scope & eSymbolContextBlock))
+ block_die = function_die.LookupDeepestBlock(file_vm_addr);
}
if (sc.function != NULL)
{
Block& block = sc.function->GetBlock (true);
- if (block_die != NULL)
- sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
- else if (function_die != NULL)
- sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
+ if (block_die)
+ sc.block = block.FindBlockByID (block_die.GetID());
+ else if (function_die)
+ sc.block = block.FindBlockByID (function_die.GetID());
}
}
}
@@ -3255,38 +2088,77 @@ SymbolFileDWARF::Index ()
DWARFDebugInfo* debug_info = DebugInfo();
if (debug_info)
{
- uint32_t cu_idx = 0;
const uint32_t num_compile_units = GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ std::vector<NameToDIE> function_basename_index(num_compile_units);
+ std::vector<NameToDIE> function_fullname_index(num_compile_units);
+ std::vector<NameToDIE> function_method_index(num_compile_units);
+ std::vector<NameToDIE> function_selector_index(num_compile_units);
+ std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
+ std::vector<NameToDIE> global_index(num_compile_units);
+ std::vector<NameToDIE> type_index(num_compile_units);
+ std::vector<NameToDIE> namespace_index(num_compile_units);
+
+ auto parser_fn = [this,
+ debug_info,
+ &function_basename_index,
+ &function_fullname_index,
+ &function_method_index,
+ &function_selector_index,
+ &objc_class_selectors_index,
+ &global_index,
+ &type_index,
+ &namespace_index](uint32_t cu_idx)
{
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded(false) > 1;
+
+ dwarf_cu->Index(function_basename_index[cu_idx],
+ function_fullname_index[cu_idx],
+ function_method_index[cu_idx],
+ function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx],
+ global_index[cu_idx],
+ type_index[cu_idx],
+ namespace_index[cu_idx]);
- bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
-
- dwarf_cu->Index (cu_idx,
- m_function_basename_index,
- m_function_fullname_index,
- m_function_method_index,
- m_function_selector_index,
- m_objc_class_selectors_index,
- m_global_index,
- m_type_index,
- m_namespace_index);
-
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed
if (clear_dies)
- dwarf_cu->ClearDIEs (true);
+ dwarf_cu->ClearDIEs(true);
+
+ return cu_idx;
+ };
+
+ TaskRunner<uint32_t> task_runner;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner.AddTask(parser_fn, cu_idx);
+
+ while (true)
+ {
+ std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ uint32_t cu_idx = f.get();
+
+ m_function_basename_index.Append(function_basename_index[cu_idx]);
+ m_function_fullname_index.Append(function_fullname_index[cu_idx]);
+ m_function_method_index.Append(function_method_index[cu_idx]);
+ m_function_selector_index.Append(function_selector_index[cu_idx]);
+ m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
+ m_global_index.Append(global_index[cu_idx]);
+ m_type_index.Append(type_index[cu_idx]);
+ m_namespace_index.Append(namespace_index[cu_idx]);
}
-
- m_function_basename_index.Finalize();
- m_function_fullname_index.Finalize();
- m_function_method_index.Finalize();
- m_function_selector_index.Finalize();
- m_objc_class_selectors_index.Finalize();
- m_global_index.Finalize();
- m_type_index.Finalize();
- m_namespace_index.Finalize();
+
+ TaskPool::RunTasks(
+ [&]() { m_function_basename_index.Finalize(); },
+ [&]() { m_function_fullname_index.Finalize(); },
+ [&]() { m_function_method_index.Finalize(); },
+ [&]() { m_function_selector_index.Finalize(); },
+ [&]() { m_objc_class_selectors_index.Finalize(); },
+ [&]() { m_global_index.Finalize(); },
+ [&]() { m_type_index.Finalize(); },
+ [&]() { m_namespace_index.Finalize(); });
#if defined (ENABLE_DEBUG_PRINTF)
StreamFile s(stdout, false);
@@ -3299,30 +2171,26 @@ SymbolFileDWARF::Index ()
s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
+ s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
#endif
}
}
bool
-SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
+SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
{
- if (namespace_decl == NULL)
+ if (decl_ctx == nullptr || !decl_ctx->IsValid())
{
// Invalid namespace decl which means we aren't matching only things
// in this symbol file, so return true to indicate it matches this
// symbol file.
return true;
}
-
- clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
-
- if (namespace_ast == NULL)
- return true; // No AST in the "namespace_decl", return true since it
- // could then match any symbol file, including this one
- if (namespace_ast == GetClangASTContext().getASTContext())
- return true; // The ASTs match, return true
+ TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
+ if (decl_ctx_type_system == type_system)
+ return true; // The type systems match, return true
// The namespace AST was valid, and it does not match...
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -3333,66 +2201,19 @@ SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *n
return false;
}
-bool
-SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
- DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry* die)
-{
- // No namespace specified, so the answer is
- if (namespace_decl == NULL)
- return true;
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- const DWARFDebugInfoEntry *decl_ctx_die = NULL;
- clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
- if (decl_ctx_die)
- {
- clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
-
- if (clang_namespace_decl)
- {
- if (decl_ctx_die->Tag() != DW_TAG_namespace)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent is not a namespace");
- return false;
- }
-
- if (clang_namespace_decl == die_clang_decl_ctx)
- return true;
- else
- return false;
- }
- else
- {
- // We have a namespace_decl that was not NULL but it contained
- // a NULL "clang::NamespaceDecl", so this means the global namespace
- // So as long the contained decl context DIE isn't a namespace
- // we should be ok.
- if (decl_ctx_die->Tag() != DW_TAG_namespace)
- return true;
- }
- }
-
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent doesn't exist");
-
- return false;
-}
uint32_t
-SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
+SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
{
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)",
+ "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
name.GetCString(),
- static_cast<const void*>(namespace_decl),
+ static_cast<const void*>(parent_decl_ctx),
append, max_matches);
- if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
DWARFDebugInfo* info = DebugInfo();
@@ -3417,7 +2238,7 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat
llvm::StringRef basename;
llvm::StringRef context;
- if (!CPPLanguageRuntime::ExtractContextAndIdentifier(name_cstr, context, basename))
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
basename = name_cstr;
m_apple_names_ap->FindByName (basename.data(), die_offsets);
@@ -3440,17 +2261,15 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat
assert (sc.module_sp);
DWARFDebugInfo* debug_info = DebugInfo();
- DWARFCompileUnit* dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
bool done = false;
for (size_t i=0; i<num_die_matches && !done; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
if (die)
{
- switch (die->Tag())
+ switch (die.Tag())
{
default:
case DW_TAG_subprogram:
@@ -3461,12 +2280,20 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat
case DW_TAG_variable:
{
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
+ if (parent_decl_ctx)
+ {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
+ {
+ CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
+ if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
+ continue;
+ }
+ }
- ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
if (variables.GetSize() - original_size >= max_matches)
done = true;
@@ -3479,7 +2306,7 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat
if (m_using_apple_tables)
{
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
- die_offset, name.GetCString());
+ die_ref.die_offset, name.GetCString());
}
}
}
@@ -3490,9 +2317,9 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_privat
if (log && num_matches > 0)
{
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
+ "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
name.GetCString(),
- static_cast<const void*>(namespace_decl),
+ static_cast<const void*>(parent_decl_ctx),
append, max_matches,
num_matches);
}
@@ -3525,7 +2352,7 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
const uint32_t original_size = variables.GetSize();
DIEArray die_offsets;
-
+
if (m_using_apple_tables)
{
if (m_apple_names_ap.get())
@@ -3548,22 +2375,20 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
sc.module_sp = m_obj_file->GetModule();
assert (sc.module_sp);
- DWARFCompileUnit* dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
const size_t num_matches = die_offsets.size();
if (num_matches)
{
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
if (die)
{
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
- ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
if (variables.GetSize() - original_size >= max_matches)
break;
@@ -3573,7 +2398,7 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
if (m_using_apple_tables)
{
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
- die_offset, regex.GetText());
+ die_ref.die_offset, regex.GetText());
}
}
}
@@ -3585,53 +2410,59 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append
bool
-SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
- DWARFCompileUnit *&dwarf_cu,
+SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
bool include_inlines,
SymbolContextList& sc_list)
{
- const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
- return ResolveFunction (dwarf_cu, die, include_inlines, sc_list);
+ DWARFDIE die = DebugInfo()->GetDIE (die_ref);
+ return ResolveFunction (die, include_inlines, sc_list);
}
bool
-SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
- const DWARFDebugInfoEntry *die,
+SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
bool include_inlines,
SymbolContextList& sc_list)
{
SymbolContext sc;
- if (die == NULL)
+ if (!orig_die)
return false;
// If we were passed a die that is not a function, just return false...
- if (! (die->Tag() == DW_TAG_subprogram || (include_inlines && die->Tag() == DW_TAG_inlined_subroutine)))
+ if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
return false;
-
- const DWARFDebugInfoEntry* inlined_die = NULL;
- if (die->Tag() == DW_TAG_inlined_subroutine)
+
+ DWARFDIE die = orig_die;
+ DWARFDIE inlined_die;
+ if (die.Tag() == DW_TAG_inlined_subroutine)
{
inlined_die = die;
- while ((die = die->GetParent()) != NULL)
+ while (1)
{
- if (die->Tag() == DW_TAG_subprogram)
+ die = die.GetParent();
+
+ if (die)
+ {
+ if (die.Tag() == DW_TAG_subprogram)
+ break;
+ }
+ else
break;
}
}
- assert (die && die->Tag() == DW_TAG_subprogram);
- if (GetFunction (cu, die, sc))
+ assert (die && die.Tag() == DW_TAG_subprogram);
+ if (GetFunction (die, sc))
{
Address addr;
// Parse all blocks if needed
if (inlined_die)
{
Block &function_block = sc.function->GetBlock (true);
- sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
+ sc.block = function_block.FindBlockByID (inlined_die.GetID());
if (sc.block == NULL)
- sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
+ sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
addr.Clear();
}
@@ -3702,131 +2533,37 @@ SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
const size_t num_matches = die_offsets.size();
if (num_matches)
{
- DWARFCompileUnit* dwarf_cu = NULL;
for (size_t i=0; i<num_matches; ++i)
- {
- const dw_offset_t die_offset = die_offsets[i];
- ResolveFunction (die_offset, dwarf_cu, include_inlines, sc_list);
- }
+ ResolveFunction (die_offsets[i], include_inlines, sc_list);
}
}
bool
-SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
- const DWARFCompileUnit *dwarf_cu,
- uint32_t name_type_mask,
- const char *partial_name,
- const char *base_name_start,
- const char *base_name_end)
+SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
+ const DWARFDIE &die)
{
- // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
- if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
- {
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
- if (!containing_decl_ctx)
- return false;
-
- bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
-
- if (name_type_mask == eFunctionNameTypeMethod)
- {
- if (is_cxx_method == false)
- return false;
- }
-
- if (name_type_mask == eFunctionNameTypeBase)
- {
- if (is_cxx_method == true)
- return false;
- }
- }
+ // If we have no parent decl context to match this DIE matches, and if the parent
+ // decl context isn't valid, we aren't trying to look for any particular decl
+ // context so any die matches.
+ if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ return true;
- // Now we need to check whether the name we got back for this type matches the extra specifications
- // that were in the name we're looking up:
- if (base_name_start != partial_name || *base_name_end != '\0')
+ if (die)
{
- // First see if the stuff to the left matches the full name. To do that let's see if
- // we can pull out the mips linkage name attribute:
-
- Mangled best_name;
- DWARFDebugInfoEntry::Attributes attributes;
- DWARFFormValue form_value;
- die->GetAttributes(this, dwarf_cu, NULL, attributes);
- uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
- if (idx == UINT32_MAX)
- idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
- if (idx != UINT32_MAX)
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
{
- if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
- {
- const char *mangled_name = form_value.AsCString(&get_debug_str_data());
- if (mangled_name)
- best_name.SetValue (ConstString(mangled_name), true);
- }
- }
-
- if (!best_name)
- {
- idx = attributes.FindAttributeIndex(DW_AT_name);
- if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
- {
- const char *name = form_value.AsCString(&get_debug_str_data());
- best_name.SetValue (ConstString(name), false);
- }
- }
-
- const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType();
- if (best_name.GetDemangledName(cu_language))
- {
- const char *demangled = best_name.GetDemangledName(cu_language).GetCString();
- if (demangled)
- {
- std::string name_no_parens(partial_name, base_name_end - partial_name);
- const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str());
- if (partial_in_demangled == NULL)
- return false;
- else
- {
- // Sort out the case where our name is something like "Process::Destroy" and the match is
- // "SBProcess::Destroy" - that shouldn't be a match. We should really always match on
- // namespace boundaries...
-
- if (partial_name[0] == ':' && partial_name[1] == ':')
- {
- // The partial name was already on a namespace boundary so all matches are good.
- return true;
- }
- else if (partial_in_demangled == demangled)
- {
- // They both start the same, so this is an good match.
- return true;
- }
- else
- {
- if (partial_in_demangled - demangled == 1)
- {
- // Only one character difference, can't be a namespace boundary...
- return false;
- }
- else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':')
- {
- // We are on a namespace boundary, so this is also good.
- return true;
- }
- else
- return false;
- }
- }
- }
+ CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
+ if (actual_decl_ctx)
+ return actual_decl_ctx == *decl_ctx;
}
}
-
- return true;
+ return false;
}
uint32_t
-SymbolFileDWARF::FindFunctions (const ConstString &name,
- const lldb_private::ClangNamespaceDecl *namespace_decl,
+SymbolFileDWARF::FindFunctions (const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
uint32_t name_type_mask,
bool include_inlines,
bool append,
@@ -3854,7 +2591,7 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
if (!append)
sc_list.Clear();
- if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
// If name is empty then we won't find anything.
@@ -3872,7 +2609,6 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
if (info == NULL)
return 0;
- DWARFCompileUnit *dwarf_cu = NULL;
std::set<const DWARFDebugInfoEntry *> resolved_dies;
if (m_using_apple_tables)
{
@@ -3891,30 +2627,30 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
for (uint32_t i = 0; i < num_matches; i++)
{
- const dw_offset_t die_offset = die_offsets[i];
- const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE (die_ref);
if (die)
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
-
- if (resolved_dies.find(die) == resolved_dies.end())
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
{
- if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
- resolved_dies.insert(die);
+ if (ResolveFunction (die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
}
}
else
{
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_offset, name_cstr);
+ die_ref.die_offset, name_cstr);
}
}
}
if (name_type_mask & eFunctionNameTypeSelector)
{
- if (namespace_decl && *namespace_decl)
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
return 0; // no selectors in namespaces
num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
@@ -3923,30 +2659,30 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
for (uint32_t i = 0; i < num_matches; i++)
{
- const dw_offset_t die_offset = die_offsets[i];
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE (die_ref);
if (die)
{
- const char *die_name = die->GetName(this, dwarf_cu);
- if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
+ const char *die_name = die.GetName();
+ if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
{
- if (resolved_dies.find(die) == resolved_dies.end())
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
{
- if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
- resolved_dies.insert(die);
+ if (ResolveFunction (die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
}
}
}
else
{
GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_offset, name_cstr);
+ die_ref.die_offset, name_cstr);
}
}
die_offsets.clear();
}
- if (((name_type_mask & eFunctionNameTypeMethod) && !namespace_decl) || name_type_mask & eFunctionNameTypeBase)
+ if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
{
// The apple_names table stores just the "base name" of C++ methods in the table. So we have to
// extract the base name, look that up, and if there is any other information in the name we were
@@ -3957,16 +2693,16 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
for (uint32_t i = 0; i < num_matches; i++)
{
- const dw_offset_t die_offset = die_offsets[i];
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE (die_ref);
if (die)
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
// If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die) == resolved_dies.end())
- if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
{
bool keep_die = true;
if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
@@ -3986,8 +2722,8 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
if (type)
{
- clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID());
- if (decl_ctx->isRecord())
+ CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
+ if (decl_ctx.IsStructUnionOrClass())
{
if (name_type_mask & eFunctionNameTypeBase)
{
@@ -4007,19 +2743,19 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
else
{
GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
- die_offset);
+ die_ref.die_offset);
}
}
}
}
if (keep_die)
- resolved_dies.insert(die);
+ resolved_dies.insert(die.GetDIE());
}
}
else
{
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_offset, name_cstr);
+ die_ref.die_offset, name_cstr);
}
}
die_offsets.clear();
@@ -4046,10 +2782,10 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
// TODO: The arch in the object file isn't correct for MSVC
// binaries on windows, we should find a way to make it
// correct and handle those symbols as well.
- if (sc_list.GetSize() == 0)
+ if (sc_list.GetSize() == original_size)
{
ArchSpec arch;
- if (!namespace_decl &&
+ if (!parent_decl_ctx &&
GetObjectFile()->GetArchitecture(arch) &&
(arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
arch.GetMachine() == llvm::Triple::hexagon))
@@ -4076,24 +2812,22 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
}
}
DIEArray die_offsets;
- DWARFCompileUnit *dwarf_cu = NULL;
-
if (name_type_mask & eFunctionNameTypeBase)
{
uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
for (uint32_t i = 0; i < num_base; i++)
{
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
+ DWARFDIE die = info->GetDIE (die_offsets[i]);
if (die)
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
-
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
// If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die) == resolved_dies.end())
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
{
- if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
- resolved_dies.insert(die);
+ if (ResolveFunction (die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
}
}
}
@@ -4102,21 +2836,21 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
if (name_type_mask & eFunctionNameTypeMethod)
{
- if (namespace_decl && *namespace_decl)
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
return 0; // no methods in namespaces
uint32_t num_base = m_function_method_index.Find(name, die_offsets);
{
for (uint32_t i = 0; i < num_base; i++)
{
- const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
+ DWARFDIE die = info->GetDIE (die_offsets[i]);
if (die)
{
// If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die) == resolved_dies.end())
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
{
- if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
- resolved_dies.insert(die);
+ if (ResolveFunction (die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
}
}
}
@@ -4124,7 +2858,7 @@ SymbolFileDWARF::FindFunctions (const ConstString &name,
die_offsets.clear();
}
- if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
+ if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
{
FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
}
@@ -4196,10 +2930,10 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inli
uint32_t
SymbolFileDWARF::FindTypes (const SymbolContext& sc,
const ConstString &name,
- const lldb_private::ClangNamespaceDecl *namespace_decl,
+ const CompilerDeclContext *parent_decl_ctx,
bool append,
uint32_t max_matches,
- TypeList& types)
+ TypeMap& types)
{
DWARFDebugInfo* info = DebugInfo();
if (info == NULL)
@@ -4209,16 +2943,16 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
if (log)
{
- if (namespace_decl)
+ if (parent_decl_ctx)
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)",
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
name.GetCString(),
- static_cast<void*>(namespace_decl->GetNamespaceDecl()),
- namespace_decl->GetQualifiedName().c_str(),
+ static_cast<const void*>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"),
append, max_matches);
else
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
name.GetCString(), append,
max_matches);
}
@@ -4227,7 +2961,7 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
if (!append)
types.Clear();
- if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
DIEArray die_offsets;
@@ -4253,20 +2987,18 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
if (num_die_matches)
{
const uint32_t initial_types_size = types.GetSize();
- DWARFCompileUnit* dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_die_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
if (die)
{
- if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
- continue;
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
- Type *matching_type = ResolveType (dwarf_cu, die);
+ Type *matching_type = ResolveType (die, true, true);
if (matching_type)
{
// We found a type pointer, now find the shared pointer form our type list
@@ -4280,7 +3012,7 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
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_offset, name.GetCString());
+ die_ref.die_offset, name.GetCString());
}
}
@@ -4288,20 +3020,20 @@ SymbolFileDWARF::FindTypes (const SymbolContext& sc,
const uint32_t num_matches = types.GetSize() - initial_types_size;
if (log && num_matches)
{
- if (namespace_decl)
+ if (parent_decl_ctx)
{
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u",
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
name.GetCString(),
- static_cast<void*>(namespace_decl->GetNamespaceDecl()),
- namespace_decl->GetQualifiedName().c_str(),
+ static_cast<const void*>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"),
append, max_matches,
num_matches);
}
else
{
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
name.GetCString(),
append, max_matches,
num_matches);
@@ -4309,14 +3041,112 @@ 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;
}
-ClangNamespaceDecl
+CompilerDeclContext
SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
const ConstString &name,
- const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
+ const CompilerDeclContext *parent_decl_ctx)
{
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -4326,11 +3156,13 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
"SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
name.GetCString());
}
-
- if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
- return ClangNamespaceDecl();
- ClangNamespaceDecl namespace_decl;
+ CompilerDeclContext namespace_decl_ctx;
+
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return namespace_decl_ctx;
+
+
DWARFDebugInfo* info = DebugInfo();
if (info)
{
@@ -4354,28 +3186,26 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
m_namespace_index.Find (name, die_offsets);
}
- DWARFCompileUnit* dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
const size_t num_matches = die_offsets.size();
if (num_matches)
{
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
-
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
+
if (die)
{
- if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
- continue;
+ if (!DIEInDeclContext (parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
- clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
- if (clang_namespace_decl)
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
{
- namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
- namespace_decl.SetNamespaceDecl (clang_namespace_decl);
- break;
+ namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
+ if (namespace_decl_ctx)
+ break;
}
}
else
@@ -4383,421 +3213,50 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
if (m_using_apple_tables)
{
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
- die_offset, name.GetCString());
+ die_ref.die_offset, name.GetCString());
}
}
}
}
}
- if (log && namespace_decl.GetNamespaceDecl())
+ if (log && namespace_decl_ctx)
{
GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
+ "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
name.GetCString(),
- static_cast<const void*>(namespace_decl.GetNamespaceDecl()),
- namespace_decl.GetQualifiedName().c_str());
- }
-
- return namespace_decl;
-}
-
-uint32_t
-SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
-{
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
- uint32_t original_size = types.GetSize();
-
- const uint32_t num_die_offsets = die_offsets.size();
- // Parse all of the types we found from the pubtypes matches
- uint32_t i;
- uint32_t num_matches = 0;
- for (i = 0; i < num_die_offsets; ++i)
- {
- Type *matching_type = ResolveTypeUID (die_offsets[i]);
- 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;
- if (num_matches >= max_matches)
- break;
- }
- }
-
- // Return the number of variable that were appended to the list
- return types.GetSize() - original_size;
-}
-
-
-size_t
-SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
- clang::DeclContext *containing_decl_ctx,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die,
- bool skip_artificial,
- bool &is_static,
- bool &is_variadic,
- std::vector<ClangASTType>& function_param_types,
- std::vector<clang::ParmVarDecl*>& function_param_decls,
- unsigned &type_quals) // ,
- // ClangASTContext::TemplateParameterInfos &template_param_infos))
-{
- if (parent_die == NULL)
- return 0;
-
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
-
- size_t arg_idx = 0;
- const DWARFDebugInfoEntry *die;
- for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
- {
- dw_tag_t tag = die->Tag();
- switch (tag)
- {
- case DW_TAG_formal_parameter:
- {
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
- if (num_attributes > 0)
- {
- const char *name = NULL;
- Declaration decl;
- dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
- bool is_artificial = false;
- // one of None, Auto, Register, Extern, Static, PrivateExtern
-
- clang::StorageClass storage = clang::SC_None;
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_type: param_type_die_offset = form_value.Reference(); break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_location:
- // if (form_value.BlockData())
- // {
- // const DWARFDataExtractor& debug_info_data = debug_info();
- // uint32_t block_length = form_value.Unsigned();
- // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
- // }
- // else
- // {
- // }
- // break;
- case DW_AT_const_value:
- case DW_AT_default_value:
- case DW_AT_description:
- case DW_AT_endianity:
- case DW_AT_is_optional:
- case DW_AT_segment:
- case DW_AT_variable_parameter:
- default:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- bool skip = false;
- if (skip_artificial)
- {
- if (is_artificial)
- {
- // In order to determine if a C++ member function is
- // "const" we have to look at the const-ness of "this"...
- // Ugly, but that
- if (arg_idx == 0)
- {
- if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
- {
- // Often times compilers omit the "this" name for the
- // specification DIEs, so we can't rely upon the name
- // being in the formal parameter DIE...
- if (name == NULL || ::strcmp(name, "this")==0)
- {
- Type *this_type = ResolveTypeUID (param_type_die_offset);
- if (this_type)
- {
- uint32_t encoding_mask = this_type->GetEncodingMask();
- if (encoding_mask & Type::eEncodingIsPointerUID)
- {
- is_static = false;
-
- if (encoding_mask & (1u << Type::eEncodingIsConstUID))
- type_quals |= clang::Qualifiers::Const;
- if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
- type_quals |= clang::Qualifiers::Volatile;
- }
- }
- }
- }
- }
- skip = true;
- }
- else
- {
-
- // HACK: Objective C formal parameters "self" and "_cmd"
- // are not marked as artificial in the DWARF...
- CompileUnit *comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
- if (comp_unit)
- {
- switch (comp_unit->GetLanguage())
- {
- case eLanguageTypeObjC:
- case eLanguageTypeObjC_plus_plus:
- if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
- skip = true;
- break;
- default:
- break;
- }
- }
- }
- }
-
- if (!skip)
- {
- Type *type = ResolveTypeUID(param_type_die_offset);
- if (type)
- {
- function_param_types.push_back (type->GetClangForwardType());
-
- clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name,
- type->GetClangForwardType(),
- storage);
- assert(param_var_decl);
- function_param_decls.push_back(param_var_decl);
-
- GetClangASTContext().SetMetadataAsUserID (param_var_decl, MakeUserID(die->GetOffset()));
- }
- }
- }
- arg_idx++;
- }
- break;
-
- case DW_TAG_unspecified_parameters:
- is_variadic = true;
- break;
-
- case DW_TAG_template_type_parameter:
- case DW_TAG_template_value_parameter:
- // The one caller of this was never using the template_param_infos,
- // and the local variable was taking up a large amount of stack space
- // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
- // the template params back, we can add them back.
- // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
- break;
-
- default:
- break;
- }
- }
- return arg_idx;
-}
-
-size_t
-SymbolFileDWARF::ParseChildEnumerators
-(
- const SymbolContext& sc,
- lldb_private::ClangASTType &clang_type,
- bool is_signed,
- uint32_t enumerator_byte_size,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die
-)
-{
- if (parent_die == NULL)
- return 0;
-
- size_t enumerators_added = 0;
- const DWARFDebugInfoEntry *die;
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
-
- for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
- {
- const dw_tag_t tag = die->Tag();
- if (tag == DW_TAG_enumerator)
- {
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
- if (num_child_attributes > 0)
- {
- const char *name = NULL;
- bool got_value = false;
- int64_t enum_value = 0;
- Declaration decl;
-
- uint32_t i;
- for (i=0; i<num_child_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_const_value:
- got_value = true;
- if (is_signed)
- enum_value = form_value.Signed();
- else
- enum_value = form_value.Unsigned();
- break;
-
- case DW_AT_name:
- name = form_value.AsCString(&get_debug_str_data());
- break;
-
- case DW_AT_description:
- default:
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- if (name && name[0] && got_value)
- {
- clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
- decl,
- name,
- enum_value,
- enumerator_byte_size * 8);
- ++enumerators_added;
- }
- }
- }
+ static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
+ static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
+ namespace_decl_ctx.GetName().AsCString("<NULL>"));
}
- return enumerators_added;
-}
-
-void
-SymbolFileDWARF::ParseChildArrayInfo
-(
- const SymbolContext& sc,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *parent_die,
- int64_t& first_index,
- std::vector<uint64_t>& element_orders,
- uint32_t& byte_stride,
- uint32_t& bit_stride
-)
-{
- if (parent_die == NULL)
- return;
-
- const DWARFDebugInfoEntry *die;
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
- for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
- {
- const dw_tag_t tag = die->Tag();
- switch (tag)
- {
- case DW_TAG_subrange_type:
- {
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
- if (num_child_attributes > 0)
- {
- uint64_t num_elements = 0;
- uint64_t lower_bound = 0;
- uint64_t upper_bound = 0;
- bool upper_bound_valid = false;
- uint32_t i;
- for (i=0; i<num_child_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_name:
- break;
-
- case DW_AT_count:
- num_elements = form_value.Unsigned();
- break;
-
- case DW_AT_bit_stride:
- bit_stride = form_value.Unsigned();
- break;
-
- case DW_AT_byte_stride:
- byte_stride = form_value.Unsigned();
- break;
-
- case DW_AT_lower_bound:
- lower_bound = form_value.Unsigned();
- break;
-
- case DW_AT_upper_bound:
- upper_bound_valid = true;
- upper_bound = form_value.Unsigned();
- break;
-
- default:
- case DW_AT_abstract_origin:
- case DW_AT_accessibility:
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_sibling:
- case DW_AT_threads_scaled:
- case DW_AT_type:
- case DW_AT_visibility:
- break;
- }
- }
- }
- if (num_elements == 0)
- {
- if (upper_bound_valid && upper_bound >= lower_bound)
- num_elements = upper_bound - lower_bound + 1;
- }
-
- element_orders.push_back (num_elements);
- }
- }
- break;
- }
- }
+ return namespace_decl_ctx;
}
TypeSP
-SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die)
+SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
{
TypeSP type_sp;
- if (die != NULL)
+ if (die)
{
- assert(dwarf_cu != NULL);
- Type *type_ptr = m_die_to_type.lookup (die);
+ Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
if (type_ptr == NULL)
{
- CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
+ CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
assert (lldb_cu);
SymbolContext sc(lldb_cu);
- type_sp = ParseType(sc, dwarf_cu, die, NULL);
+ const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE();
+ while (parent_die != nullptr)
+ {
+ if (parent_die->Tag() == DW_TAG_subprogram)
+ break;
+ parent_die = parent_die->GetParent();
+ }
+ SymbolContext sc_backup = sc;
+ if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
+ sc = sc_backup;
+
+ type_sp = ParseType(sc, die, NULL);
}
else if (type_ptr != DIE_IS_BEING_PARSED)
{
@@ -4809,215 +3268,57 @@ SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfo
return type_sp;
}
-clang::DeclContext *
-SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
-{
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFCompileUnitSP cu_sp;
- const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
- return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
- }
- return NULL;
-}
-
-clang::DeclContext *
-SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
-{
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- DWARFCompileUnitSP cu_sp;
- const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
- if (die)
- return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
- }
- }
- return NULL;
-}
-
-clang::NamespaceDecl *
-SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry *die)
-{
- if (die && die->Tag() == DW_TAG_namespace)
- {
- // See if we already parsed this namespace DIE and associated it with a
- // uniqued namespace declaration
- clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
- if (namespace_decl)
- return namespace_decl;
- else
- {
- const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
- namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- {
- if (namespace_name)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
- static_cast<void*>(GetClangASTContext().getASTContext()),
- MakeUserID(die->GetOffset()),
- namespace_name,
- static_cast<void*>(namespace_decl),
- static_cast<void*>(namespace_decl->getOriginalNamespace()));
- }
- else
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
- static_cast<void*>(GetClangASTContext().getASTContext()),
- MakeUserID(die->GetOffset()),
- static_cast<void*>(namespace_decl),
- static_cast<void*>(namespace_decl->getOriginalNamespace()));
- }
- }
-
- if (namespace_decl)
- LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
- return namespace_decl;
- }
- }
- return NULL;
-}
-
-clang::DeclContext *
-SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
-{
- clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
- if (clang_decl_ctx)
- return clang_decl_ctx;
- // If this DIE has a specification, or an abstract origin, then trace to those.
-
- dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- return GetClangDeclContextForDIEOffset (sc, die_offset);
-
- die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- return GetClangDeclContextForDIEOffset (sc, die_offset);
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log, "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
- // This is the DIE we want. Parse it, then query our map.
- bool assert_not_being_parsed = true;
- ResolveTypeUID (cu, die, assert_not_being_parsed);
-
- clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
-
- return clang_decl_ctx;
-}
-
-clang::DeclContext *
-SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
-{
- if (m_clang_tu_decl == NULL)
- m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
-
- const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
-
- if (decl_ctx_die_copy)
- *decl_ctx_die_copy = decl_ctx_die;
-
- if (decl_ctx_die)
- {
-
- DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
- if (pos != m_die_to_decl_ctx.end())
- return pos->second;
-
- switch (decl_ctx_die->Tag())
- {
- case DW_TAG_compile_unit:
- return m_clang_tu_decl;
-
- case DW_TAG_namespace:
- return ResolveNamespaceDIE (cu, decl_ctx_die);
- break;
-
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- Type* type = ResolveType (cu, decl_ctx_die);
- if (type)
- {
- clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
- if (decl_ctx)
- {
- LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
- if (decl_ctx)
- return decl_ctx;
- }
- }
- }
- break;
-
- default:
- break;
- }
- }
- return m_clang_tu_decl;
-}
-
-const DWARFDebugInfoEntry *
-SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+DWARFDIE
+SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
{
- if (cu && die)
+ if (orig_die)
{
- const DWARFDebugInfoEntry * const decl_die = die;
+ DWARFDIE die = orig_die;
- while (die != NULL)
+ while (die)
{
// If this is the original DIE that we are searching for a declaration
// for, then don't look in the cache as we don't want our own decl
// context to be our decl context...
- if (decl_die != die)
+ if (orig_die != die)
{
- switch (die->Tag())
+ switch (die.Tag())
{
case DW_TAG_compile_unit:
case DW_TAG_namespace:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:
+ case DW_TAG_lexical_block:
+ case DW_TAG_subprogram:
return die;
default:
break;
}
}
-
- dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
+
+ DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
+ if (spec_die)
{
- DWARFCompileUnit *spec_cu = cu;
- const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
- const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
- if (spec_die_decl_ctx_die)
- return spec_die_decl_ctx_die;
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
-
- die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
+
+ DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
+ if (abs_die)
{
- DWARFCompileUnit *abs_cu = cu;
- const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
- const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
- if (abs_die_decl_ctx_die)
- return abs_die_decl_ctx_die;
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
}
-
- die = die->GetParent();
+
+ die = die.GetParent();
}
}
- return NULL;
+ return DWARFDIE();
}
@@ -5075,7 +3376,7 @@ SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP
-SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
+SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
const ConstString &type_name,
bool must_be_implementation)
{
@@ -5105,15 +3406,13 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
const size_t num_matches = die_offsets.size();
- DWARFCompileUnit* type_cu = NULL;
- const DWARFDebugInfoEntry* type_die = NULL;
if (num_matches)
{
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE type_die = debug_info->GetDIE (die_ref);
if (type_die)
{
@@ -5122,7 +3421,7 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
// Don't try and resolve the DIE we are looking for with the DIE itself!
if (type_die != die)
{
- switch (type_die->Tag())
+ switch (type_die.Tag())
{
case DW_TAG_class_type:
case DW_TAG_structure_type:
@@ -5135,22 +3434,22 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
if (try_resolving_type)
{
- if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
- try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
+ if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
+ try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
if (try_resolving_type)
{
- Type *resolved_type = ResolveType (type_cu, type_die, false);
+ Type *resolved_type = ResolveType (type_die, false, true);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
- MakeUserID(die->GetOffset()),
+ die.GetID(),
m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
- MakeUserID(type_die->GetOffset()),
- MakeUserID(type_cu->GetOffset()));
+ type_die.GetID(),
+ type_cu->GetID());
if (die)
- m_die_to_type[die] = resolved_type;
+ GetDIEToType()[die.GetDIE()] = resolved_type;
type_sp = resolved_type->shared_from_this();
break;
}
@@ -5162,7 +3461,7 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
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_offset, type_name.GetCString());
+ die_ref.die_offset, type_name.GetCString());
}
}
@@ -5185,19 +3484,12 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
// when they don't.
//----------------------------------------------------------------------
bool
-SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
- DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
+SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
+ const DWARFDIE &die2)
{
if (die1 == die2)
return true;
-#if defined (LLDB_CONFIGURATION_DEBUG)
- // You can't and shouldn't call this function with a compile unit from
- // two different SymbolFileDWARF instances.
- assert (DebugInfo()->ContainsCompileUnit (cu1));
- assert (DebugInfo()->ContainsCompileUnit (cu2));
-#endif
-
DWARFDIECollection decl_ctx_1;
DWARFDIECollection decl_ctx_2;
//The declaration DIE stack is a stack of the declaration context
@@ -5215,8 +3507,8 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn
// all the way back to the compiler unit.
// First lets grab the decl contexts for both DIEs
- die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
- die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
+ die1.GetDeclContextDIEs (decl_ctx_1);
+ die2.GetDeclContextDIEs (decl_ctx_2);
// Make sure the context arrays have the same size, otherwise
// we are done
const size_t count1 = decl_ctx_1.Size();
@@ -5226,32 +3518,32 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn
// Make sure the DW_TAG values match all the way back up the
// compile unit. If they don't, then we are done.
- const DWARFDebugInfoEntry *decl_ctx_die1;
- const DWARFDebugInfoEntry *decl_ctx_die2;
+ DWARFDIE decl_ctx_die1;
+ DWARFDIE decl_ctx_die2;
size_t i;
for (i=0; i<count1; i++)
{
- decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
- if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
+ if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
return false;
}
#if defined LLDB_CONFIGURATION_DEBUG
// Make sure the top item in the decl context die array is always
// DW_TAG_compile_unit. If it isn't then something went wrong in
- // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
- assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
+ // the DWARFDIE::GetDeclContextDIEs() function...
+ assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
#endif
// Always skip the compile unit when comparing by only iterating up to
// "count - 1". Here we compare the names as we go.
for (i=0; i<count1 - 1; i++)
{
- decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
- const char *name1 = decl_ctx_die1->GetName(this, cu1);
- const char *name2 = decl_ctx_die2->GetName(this, cu2);
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
+ const char *name1 = decl_ctx_die1.GetName();
+ const char *name2 = decl_ctx_die2.GetName();
// If the string was from a DW_FORM_strp, then the pointer will often
// be the same!
if (name1 == name2)
@@ -5338,22 +3630,20 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
const size_t num_matches = die_offsets.size();
- DWARFCompileUnit* type_cu = NULL;
- const DWARFDebugInfoEntry* type_die = NULL;
if (num_matches)
{
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE type_die = debug_info->GetDIE (die_ref);
if (type_die)
{
bool try_resolving_type = false;
// Don't try and resolve the DIE we are looking for with the DIE itself!
- const dw_tag_t type_tag = type_die->Tag();
+ const dw_tag_t type_tag = type_die.Tag();
// Make sure the tags match
if (type_tag == tag)
{
@@ -5386,7 +3676,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
if (try_resolving_type)
{
DWARFDeclContext type_dwarf_decl_ctx;
- type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx);
+ type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
if (log)
{
@@ -5394,14 +3684,14 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(),
- type_die->GetOffset(),
+ type_die.GetOffset(),
type_dwarf_decl_ctx.GetQualifiedName());
}
// Make sure the decl contexts match all the way up
if (dwarf_decl_ctx == type_dwarf_decl_ctx)
{
- Type *resolved_type = ResolveType (type_cu, type_die, false);
+ Type *resolved_type = ResolveType (type_die, false);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
type_sp = resolved_type->shared_from_this();
@@ -5414,12 +3704,12 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
if (log)
{
std::string qualified_name;
- type_die->GetQualifiedName(this, type_cu, qualified_name);
+ type_die.GetQualifiedName(qualified_name);
GetObjectFile()->GetModule()->LogMessage (log,
"SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName(),
- type_die->GetOffset(),
+ type_die.GetOffset(),
qualified_name.c_str());
}
}
@@ -5429,7 +3719,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
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_offset, type_name.GetCString());
+ die_ref.die_offset, type_name.GetCString());
}
}
@@ -5440,1744 +3730,32 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &
return type_sp;
}
-bool
-SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
- Type *class_type,
- DWARFCompileUnit* src_cu,
- const DWARFDebugInfoEntry *src_class_die,
- DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die,
- DWARFDIECollection &failures)
-{
- if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
- return false;
- if (src_class_die->Tag() != dst_class_die->Tag())
- return false;
-
- // We need to complete the class type so we can get all of the method types
- // parsed so we can then unique those types to their equivalent counterparts
- // in "dst_cu" and "dst_class_die"
- class_type->GetClangFullType();
-
- const DWARFDebugInfoEntry *src_die;
- const DWARFDebugInfoEntry *dst_die;
- UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
- UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
- UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
- UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
- for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
- {
- if (src_die->Tag() == DW_TAG_subprogram)
- {
- // Make sure this is a declaration and not a concrete instance by looking
- // for DW_AT_declaration set to 1. Sometimes concrete function instances
- // are placed inside the class definitions and shouldn't be included in
- // the list of things are are tracking here.
- if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
- {
- const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
- if (src_name)
- {
- ConstString src_const_name(src_name);
- if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
- src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
- else
- src_name_to_die.Append(src_const_name.GetCString(), src_die);
- }
- }
- }
- }
- for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
- {
- if (dst_die->Tag() == DW_TAG_subprogram)
- {
- // Make sure this is a declaration and not a concrete instance by looking
- // for DW_AT_declaration set to 1. Sometimes concrete function instances
- // are placed inside the class definitions and shouldn't be included in
- // the list of things are are tracking here.
- if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_declaration, 0) == 1)
- {
- const char *dst_name = dst_die->GetMangledName (this, dst_cu);
- if (dst_name)
- {
- ConstString dst_const_name(dst_name);
- if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
- dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
- else
- dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
- }
- }
- }
- }
- const uint32_t src_size = src_name_to_die.GetSize ();
- const uint32_t dst_size = dst_name_to_die.GetSize ();
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
-
- // Is everything kosher so we can go through the members at top speed?
- bool fast_path = true;
-
- if (src_size != dst_size)
- {
- if (src_size != 0 && dst_size != 0)
- {
- if (log)
- log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_size,
- dst_size);
- }
-
- fast_path = false;
- }
-
- uint32_t idx;
-
- if (fast_path)
- {
- for (idx = 0; idx < src_size; ++idx)
- {
- src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
-
- if (src_die->Tag() != dst_die->Tag())
- {
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_die->GetOffset(),
- DW_TAG_value_to_name(src_die->Tag()),
- dst_die->GetOffset(),
- DW_TAG_value_to_name(src_die->Tag()));
- fast_path = false;
- }
-
- const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
- const char *dst_name = dst_die->GetMangledName (this, dst_cu);
-
- // Make sure the names match
- if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
- continue;
-
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_die->GetOffset(),
- src_name,
- dst_die->GetOffset(),
- dst_name);
-
- fast_path = false;
- }
- }
-
- // Now do the work of linking the DeclContexts and Types.
- if (fast_path)
- {
- // We can do this quickly. Just run across the tables index-for-index since
- // we know each node has matching names and tags.
- for (idx = 0; idx < src_size; ++idx)
- {
- src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
-
- clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die->GetOffset(), dst_die->GetOffset());
- LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
- src_die->GetOffset(), dst_die->GetOffset());
- }
-
- Type *src_child_type = m_die_to_type[src_die];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die->GetOffset(), dst_die->GetOffset());
- m_die_to_type[dst_die] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
- }
- }
- }
- else
- {
- // We must do this slowly. For each member of the destination, look
- // up a member in the source with the same name, check its tag, and
- // unique them if everything matches up. Report failures.
-
- if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
- {
- src_name_to_die.Sort();
-
- for (idx = 0; idx < dst_size; ++idx)
- {
- const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
- dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
- src_die = src_name_to_die.Find(dst_name, NULL);
-
- if (src_die && (src_die->Tag() == dst_die->Tag()))
- {
- clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die->GetOffset(),
- dst_die->GetOffset());
- LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
- }
-
- Type *src_child_type = m_die_to_type[src_die];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die->GetOffset(),
- dst_die->GetOffset());
- m_die_to_type[dst_die] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
- }
- }
- else
- {
- if (log)
- log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
-
- failures.Append(dst_die);
- }
- }
- }
- }
-
- const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
- const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
-
- UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
-
- if (src_size_artificial && dst_size_artificial)
- {
- dst_name_to_die_artificial.Sort();
-
- for (idx = 0; idx < src_size_artificial; ++idx)
- {
- const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
- src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
- dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);
-
- if (dst_die)
- {
- // Both classes have the artificial types, link them
- clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
- if (src_decl_ctx)
- {
- if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_decl_ctx),
- src_die->GetOffset(), dst_die->GetOffset());
- LinkDeclContextToDIE (src_decl_ctx, dst_die);
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
- }
-
- Type *src_child_type = m_die_to_type[src_die];
- if (src_child_type)
- {
- if (log)
- log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
- static_cast<void*>(src_child_type),
- src_child_type->GetID(),
- src_die->GetOffset(), dst_die->GetOffset());
- m_die_to_type[dst_die] = src_child_type;
- }
- else
- {
- if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
- }
- }
- }
- }
-
- if (dst_size_artificial)
- {
- for (idx = 0; idx < dst_size_artificial; ++idx)
- {
- const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
- dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
- if (log)
- log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
-
- failures.Append(dst_die);
- }
- }
-
- return (failures.Size() != 0);
-}
-
TypeSP
-SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
+SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
{
TypeSP type_sp;
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
-
-#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
- static DIEStack g_die_stack;
- DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
-#endif
-
- AccessType accessibility = eAccessNone;
- if (die != NULL)
+ if (die)
{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- {
- const DWARFDebugInfoEntry *context_die;
- clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
-
- GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
- die->GetOffset(),
- static_cast<void*>(context),
- context_die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
-
-#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
- scoped_die_logger.Push (dwarf_cu, die);
- g_die_stack.LogDIEs(log, this);
-#endif
- }
-//
-// Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
-// if (log && dwarf_cu)
-// {
-// StreamString s;
-// die->DumpLocation (this, dwarf_cu, s);
-// GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
-//
-// }
-
- Type *type_ptr = m_die_to_type.lookup (die);
- TypeList* type_list = GetTypeList();
- if (type_ptr == NULL)
- {
- ClangASTContext &ast = GetClangASTContext();
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
-
- const dw_tag_t tag = die->Tag();
-
- bool is_forward_declaration = false;
- DWARFDebugInfoEntry::Attributes attributes;
- const char *type_name_cstr = NULL;
- ConstString type_name_const_str;
- Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- uint64_t byte_size = 0;
- Declaration decl;
-
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- ClangASTType clang_type;
- DWARFFormValue form_value;
-
- dw_attr_t attr;
-
- switch (tag)
- {
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_typedef:
- case DW_TAG_const_type:
- case DW_TAG_restrict_type:
- case DW_TAG_volatile_type:
- case DW_TAG_unspecified_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- m_die_to_type[die] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
- uint32_t encoding = 0;
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
-
- if (num_attributes > 0)
- {
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
-
- type_name_cstr = form_value.AsCString(&get_debug_str_data());
- // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
- // include the "&"...
- if (tag == DW_TAG_reference_type)
- {
- if (strchr (type_name_cstr, '&') == NULL)
- type_name_cstr = NULL;
- }
- if (type_name_cstr)
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
- case DW_AT_encoding: encoding = form_value.Unsigned(); break;
- case DW_AT_type: encoding_uid = form_value.Reference(); break;
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
-
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
-
- switch (tag)
- {
- default:
- break;
-
- case DW_TAG_unspecified_type:
- if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
- strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
- {
- resolve_state = Type::eResolveStateFull;
- clang_type = ast.GetBasicType(eBasicTypeNullPtr);
- break;
- }
- // Fall through to base type below in case we can handle the type there...
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
- encoding,
- byte_size * 8);
- break;
-
- case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
- case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
- case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break;
- case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
- case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
- case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
- case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
- }
-
- if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
- {
- bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
-
- if (translation_unit_is_objc)
- {
- if (type_name_cstr != NULL)
- {
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
-
- if (type_name_const_str == g_objc_type_name_id)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
-
- }
- else if (type_name_const_str == g_objc_type_name_Class)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBasicType(eBasicTypeObjCClass);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
- }
- else if (type_name_const_str == g_objc_type_name_selector)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBasicType(eBasicTypeObjCSel);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
- }
- }
- else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
- {
- // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
-
- DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);
-
- if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
- {
- if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
- {
- if (!strcmp(struct_name, "objc_object"))
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
- }
- }
- }
- }
- }
- }
-
- type_sp.reset( new Type (MakeUserID(die->GetOffset()),
- this,
- type_name_const_str,
- byte_size,
- NULL,
- encoding_uid,
- encoding_data_type,
- &decl,
- clang_type,
- resolve_state));
-
- m_die_to_type[die] = type_sp.get();
-
-// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
-// if (encoding_type != NULL)
-// {
-// if (encoding_type != DIE_IS_BEING_PARSED)
-// type_sp->SetEncodingType(encoding_type);
-// else
-// m_indirect_fixups.push_back(type_sp.get());
-// }
- }
- break;
-
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- m_die_to_type[die] = DIE_IS_BEING_PARSED;
- bool byte_size_valid = false;
-
- LanguageType class_language = eLanguageTypeUnknown;
- bool is_complete_objc_class = false;
- //bool struct_is_class = false;
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
- if (num_attributes > 0)
- {
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file:
- if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
- {
- // llvm-gcc outputs invalid DW_AT_decl_file attributes that always
- // point to the compile unit file, so we clear this invalid value
- // so that we can still unique types efficiently.
- decl.SetFile(FileSpec ("<invalid>", false));
- }
- else
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
- break;
-
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
-
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
-
- case DW_AT_name:
- type_name_cstr = form_value.AsCString(&get_debug_str_data());
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- byte_size_valid = true;
- break;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
-
- case DW_AT_APPLE_runtime_class:
- class_language = (LanguageType)form_value.Signed();
- break;
-
- case DW_AT_APPLE_objc_complete_type:
- is_complete_objc_class = form_value.Signed();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
-
- // UniqueDWARFASTType is large, so don't create a local variables on the
- // stack, put it on the heap. This function is often called recursively
- // and clang isn't good and sharing the stack space for variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
-
- // Only try and unique the type if it has a name.
- if (type_name_const_str &&
- GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
- this,
- dwarf_cu,
- die,
- decl,
- byte_size_valid ? byte_size : -1,
- *unique_ast_entry_ap))
- {
- // We have already parsed this type or from another
- // compile unit. GCC loves to use the "one definition
- // rule" which can result in multiple definitions
- // of the same class over and over in each compile
- // unit.
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- m_die_to_type[die] = type_sp.get();
- return type_sp;
- }
- }
-
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type)
- {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_union_type)
- {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_class_type)
- {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
-
- if (byte_size_valid && byte_size == 0 && type_name_cstr &&
- die->HasChildren() == false &&
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
- {
- // Work around an issue with clang at the moment where
- // forward declarations for objective C classes are emitted
- // as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are
- // no children, and the byte size is zero.
- is_forward_declaration = true;
- }
-
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus)
- {
- if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
- {
- // We have a valid eSymbolTypeObjCClass class symbol whose
- // name matches the current objective C class that we
- // are trying to find and this DIE isn't the complete
- // definition (we checked is_complete_objc_class above and
- // know it is false), so the real definition is in here somewhere
- type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
-
- if (!type_sp && GetDebugMapSymfile ())
- {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
- }
-
- if (type_sp)
- {
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, 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
- m_die_to_type[die] = type_sp.get();
- return type_sp;
- }
- }
- }
-
-
- if (is_forward_declaration)
- {
- // We have a forward declaration to a type and we need
- // to try and find a full declaration. We look in the
- // current type index just in case we have a forward
- // declaration followed by an actual declarations in the
- // DWARF. If this fails, we need to look elsewhere...
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
- static_cast<void*>(this),
- die->GetOffset(),
- DW_TAG_value_to_name(tag),
- type_name_cstr);
- }
-
- DWARFDeclContext die_decl_ctx;
- die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx);
-
- //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
- type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
-
- if (!type_sp && GetDebugMapSymfile ())
- {
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
- }
-
- if (type_sp)
- {
- if (log)
- {
- 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
- m_die_to_type[die] = type_sp.get();
- return type_sp;
- }
- }
- assert (tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
- if (!clang_type)
- {
- const DWARFDebugInfoEntry *decl_ctx_die;
-
- clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
- if (accessibility == eAccessNone && decl_ctx)
- {
- // Check the decl context that contains this class/struct/union.
- // If it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass (containing_decl_kind))
- accessibility = default_accessibility;
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(MakeUserID(die->GetOffset()));
- metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));
-
- if (type_name_cstr && strchr (type_name_cstr, '<'))
- {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
- {
- clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
- accessibility,
- type_name_cstr,
- tag_decl_kind,
- template_param_infos);
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
- class_template_decl,
- tag_decl_kind,
- template_param_infos);
- clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
- clang_type_was_created = true;
-
- GetClangASTContext().SetMetadata (class_template_decl, metadata);
- GetClangASTContext().SetMetadata (class_specialization_decl, metadata);
- }
- }
-
- if (!clang_type_was_created)
- {
- clang_type_was_created = true;
- clang_type = ast.CreateRecordType (decl_ctx,
- accessibility,
- type_name_cstr,
- tag_decl_kind,
- class_language,
- &metadata);
- }
- }
-
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang
- // types for function prototypes.
- LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
- type_sp.reset (new Type (MakeUserID(die->GetOffset()),
- this,
- type_name_const_str,
- byte_size,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateForward));
-
- type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
-
-
- // Add our type to the unique type map so we don't
- // end up creating many copies of the same type over
- // and over in the ASTContext for our module
- unique_ast_entry_ap->m_type_sp = type_sp;
- unique_ast_entry_ap->m_symfile = this;
- unique_ast_entry_ap->m_cu = dwarf_cu;
- unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = decl;
- unique_ast_entry_ap->m_byte_size = byte_size;
- GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
- *unique_ast_entry_ap);
-
- if (is_forward_declaration && die->HasChildren())
- {
- // Check to see if the DIE actually has a definition, some version of GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
- // members, or inheritance, so we can't trust it
- const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
- while (child_die)
- {
- switch (child_die->Tag())
- {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die = NULL;
- is_forward_declaration = false;
- break;
- default:
- child_die = child_die->GetSibling();
- break;
- }
- }
- }
-
- if (!is_forward_declaration)
- {
- // Always start the definition for a class type so that
- // if the class has child classes or types that require
- // the class to be created for use as their decl contexts
- // the class will be ready to accept these child definitions.
- if (die->HasChildren() == false)
- {
- // No children for this struct/union/class, lets finish it
- clang_type.StartTagDeclarationDefinition ();
- clang_type.CompleteTagDeclarationDefinition ();
-
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
-
- if (record_decl)
- m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
- }
- }
- else if (clang_type_was_created)
- {
- // Start the definition if the class is not objective C since
- // the underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++ class/union/structs
- // we want to start the definition in case the class is needed as the
- // declaration context for a contained class or type without the need
- // to complete that type..
-
- if (class_language != eLanguageTypeObjC &&
- class_language != eLanguageTypeObjC_plus_plus)
- clang_type.StartTagDeclarationDefinition ();
-
- // 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
- // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
- // When the definition needs to be defined.
- m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
- m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
- clang_type.SetHasExternalStorage (true);
- }
- }
-
- }
- break;
-
- case DW_TAG_enumeration_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- m_die_to_type[die] = DIE_IS_BEING_PARSED;
-
- lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
-
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
- if (num_attributes > 0)
- {
- uint32_t i;
-
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString(&get_debug_str_data());
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_type: encoding_uid = form_value.Reference(); 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_allocated:
- case DW_AT_associated:
- case DW_AT_bit_stride:
- case DW_AT_byte_stride:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
-
- ClangASTType enumerator_clang_type;
- clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
- if (!clang_type)
- {
- if (encoding_uid != DW_INVALID_OFFSET)
- {
- Type *enumerator_type = ResolveTypeUID(encoding_uid);
- if (enumerator_type)
- enumerator_clang_type = enumerator_type->GetClangFullType();
- }
-
- if (!enumerator_clang_type)
- enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
- DW_ATE_signed,
- byte_size * 8);
-
- clang_type = ast.CreateEnumerationType (type_name_cstr,
- GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
- decl,
- enumerator_clang_type);
- }
- else
- {
- enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
- }
-
- LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
-
- type_sp.reset( new Type (MakeUserID(die->GetOffset()),
- this,
- type_name_const_str,
- byte_size,
- NULL,
- encoding_uid,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateForward));
-
- clang_type.StartTagDeclarationDefinition ();
- if (die->HasChildren())
- {
- SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
- }
- clang_type.CompleteTagDeclarationDefinition ();
- }
- }
- break;
-
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- m_die_to_type[die] = DIE_IS_BEING_PARSED;
-
- //const char *mangled = NULL;
- dw_offset_t type_die_offset = DW_INVALID_OFFSET;
- bool is_variadic = false;
- bool is_inline = false;
- bool is_static = false;
- bool is_virtual = false;
- bool is_explicit = false;
- bool is_artificial = false;
- dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
- dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
- dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
-
- unsigned type_quals = 0;
- clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
-
-
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
- if (num_attributes > 0)
- {
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString(&get_debug_str_data());
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_type: type_die_offset = form_value.Reference(); break;
- case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_inline: is_inline = form_value.Boolean(); break;
- case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
- case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
-
-
- case DW_AT_external:
- if (form_value.Unsigned())
- {
- if (storage == clang::SC_None)
- storage = clang::SC_Extern;
- else
- storage = clang::SC_PrivateExtern;
- }
- break;
-
- case DW_AT_specification:
- specification_die_offset = form_value.Reference();
- break;
-
- case DW_AT_abstract_origin:
- abstract_origin_die_offset = form_value.Reference();
- break;
-
- case DW_AT_object_pointer:
- object_pointer_die_offset = form_value.Reference();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_address_class:
- case DW_AT_calling_convention:
- case DW_AT_data_location:
- case DW_AT_elemental:
- case DW_AT_entry_pc:
- case DW_AT_frame_base:
- case DW_AT_high_pc:
- case DW_AT_low_pc:
- case DW_AT_prototyped:
- case DW_AT_pure:
- case DW_AT_ranges:
- case DW_AT_recursive:
- case DW_AT_return_addr:
- case DW_AT_segment:
- 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_description:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
-
- std::string object_pointer_name;
- if (object_pointer_die_offset != DW_INVALID_OFFSET)
- {
- // Get the name from the object pointer die
- StreamString s;
- if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
- {
- object_pointer_name.assign(s.GetData());
- }
- }
-
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
-
- ClangASTType return_clang_type;
- Type *func_type = NULL;
-
- if (type_die_offset != DW_INVALID_OFFSET)
- func_type = ResolveTypeUID(type_die_offset);
-
- if (func_type)
- return_clang_type = func_type->GetClangForwardType();
- else
- return_clang_type = ast.GetBasicType(eBasicTypeVoid);
-
-
- std::vector<ClangASTType> function_param_types;
- std::vector<clang::ParmVarDecl*> function_param_decls;
-
- // Parse the function children for the parameters
-
- const DWARFDebugInfoEntry *decl_ctx_die = NULL;
- clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
- const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
-
- const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
- // Start off static. This will be set to false in ParseChildParameters(...)
- // if we find a "this" parameters as the first parameter
- if (is_cxx_method)
- is_static = true;
-
- if (die->HasChildren())
- {
- bool skip_artificial = true;
- ParseChildParameters (sc,
- containing_decl_ctx,
- dwarf_cu,
- die,
- skip_artificial,
- is_static,
- is_variadic,
- function_param_types,
- function_param_decls,
- type_quals);
- }
-
- // clang_type will get the function prototype clang type after this call
- clang_type = ast.CreateFunctionType (return_clang_type,
- function_param_types.data(),
- function_param_types.size(),
- is_variadic,
- type_quals);
-
- bool ignore_containing_context = false;
-
- if (type_name_cstr)
- {
- bool type_handled = false;
- if (tag == DW_TAG_subprogram)
- {
- ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
- if (objc_method.IsValid(true))
- {
- ClangASTType class_opaque_type;
- ConstString class_name(objc_method.GetClassName());
- if (class_name)
- {
- TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
-
- if (complete_objc_class_type_sp)
- {
- ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
- if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
- class_opaque_type = type_clang_forward_type;
- }
- }
-
- if (class_opaque_type)
- {
- // If accessibility isn't set to anything valid, assume public for
- // now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
- clang_type,
- accessibility,
- is_artificial);
- type_handled = objc_method_decl != NULL;
- if (type_handled)
- {
- LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
- GetClangASTContext().SetMetadataAsUserID (objc_method_decl, MakeUserID(die->GetOffset()));
- }
- else
- {
- GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
- die->GetOffset(),
- tag,
- DW_TAG_value_to_name(tag));
- }
- }
- }
- else if (is_cxx_method)
- {
- // Look at the parent of this DIE and see if is is
- // a class or struct and see if this is actually a
- // C++ method
- Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
- if (class_type)
- {
- if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
- {
- // 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"...
- SymbolFileDWARF *class_symfile = NULL;
- DWARFCompileUnitSP class_type_cu_sp;
- const DWARFDebugInfoEntry *class_type_die = NULL;
-
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
- class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
- }
- else
- {
- class_symfile = this;
- class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
- }
- if (class_type_die)
- {
- DWARFDIECollection failures;
-
- CopyUniqueClassMethodTypes (class_symfile,
- class_type,
- class_type_cu_sp.get(),
- class_type_die,
- dwarf_cu,
- decl_ctx_die,
- failures);
-
- // FIXME do something with these failures that's smarter than
- // just dropping them on the ground. Unfortunately classes don't
- // like having stuff added to them after their definitions are
- // complete...
-
- type_ptr = m_die_to_type[die];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
- }
- }
-
- if (specification_die_offset != DW_INVALID_OFFSET)
- {
- // We have a specification which we are going to base our function
- // prototype off of, so we need this type to be completed so that the
- // m_die_to_decl_ctx for the method in the specification has a valid
- // clang decl context.
- class_type->GetClangForwardType();
- // 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);
- clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die);
- if (spec_clang_decl_ctx)
- {
- LinkDeclContextToDIE(spec_clang_decl_ctx, die);
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
- MakeUserID(die->GetOffset()),
- specification_die_offset);
- }
- type_handled = true;
- }
- else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
- {
- // We have a specification which we are going to base our function
- // prototype off of, so we need this type to be completed so that the
- // m_die_to_decl_ctx for the method in the abstract origin has a valid
- // clang decl context.
- class_type->GetClangForwardType();
-
- DWARFCompileUnitSP abs_cu_sp;
- const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
- clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die);
- if (abs_clang_decl_ctx)
- {
- LinkDeclContextToDIE (abs_clang_decl_ctx, die);
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x) has no decl\n",
- MakeUserID(die->GetOffset()),
- abstract_origin_die_offset);
- }
- type_handled = true;
- }
- else
- {
- ClangASTType class_opaque_type = class_type->GetClangForwardType();
- if (class_opaque_type.IsCXXClassType ())
- {
- if (class_opaque_type.IsBeingDefined ())
- {
- // 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;
- // 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(),
- MakeUserID(die->GetOffset()),
- m_obj_file->GetFileSpec().GetPath().c_str());
-
- const bool is_attr_used = false;
-
- cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (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(MakeUserID(die->GetOffset()));
-
- 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));
- }
- GetClangASTContext().SetMetadata (cxx_method_decl, metadata);
- }
- else
- {
- ignore_containing_context = true;
- }
- }
- }
- else
- {
- // We were asked to parse the type for a method in a class, yet the
- // class hasn't been asked to complete itself through the
- // clang::ExternalASTSource protocol, so we need to just have the
- // class complete itself and do things the right way, then our
- // DIE should then have an entry in the m_die_to_type map. First
- // we need to modify the m_die_to_type so it doesn't think we are
- // trying to parse this DIE anymore...
- m_die_to_type[die] = NULL;
-
- // Now we get the full type to force our class type to complete itself
- // using the clang::ExternalASTSource protocol which will parse all
- // base classes and all methods (including the method for this DIE).
- class_type->GetClangFullType();
-
- // The type for this DIE should have been filled in the function call above
- type_ptr = m_die_to_type[die];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
-
- // FIXME This is fixing some even uglier behavior but we really need to
- // uniq the methods of each class as well as the class itself.
- // <rdar://problem/11240464>
- type_handled = true;
- }
- }
- }
- }
- }
- }
-
- if (!type_handled)
- {
- // We just have a function that isn't part of a class
- clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (ignore_containing_context ? GetClangASTContext().GetTranslationUnitDecl() : containing_decl_ctx,
- type_name_cstr,
- clang_type,
- storage,
- is_inline);
-
-// if (template_param_infos.GetSize() > 0)
-// {
-// clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
-// function_decl,
-// type_name_cstr,
-// template_param_infos);
-//
-// ast.CreateFunctionTemplateSpecializationInfo (function_decl,
-// func_template_decl,
-// template_param_infos);
-// }
- // Add the decl to our DIE to decl context map
- assert (function_decl);
- LinkDeclContextToDIE(function_decl, die);
- if (!function_param_decls.empty())
- ast.SetFunctionParameters (function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
-
- ClangASTMetadata metadata;
- metadata.SetUserID(MakeUserID(die->GetOffset()));
-
- if (!object_pointer_name.empty())
- {
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf ("Setting object pointer name: %s on function object %p.",
- object_pointer_name.c_str(),
- static_cast<void*>(function_decl));
- }
- GetClangASTContext().SetMetadata (function_decl, metadata);
- }
- }
- type_sp.reset( new Type (MakeUserID(die->GetOffset()),
- this,
- type_name_const_str,
- 0,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateFull));
- assert(type_sp.get());
- }
- break;
-
- case DW_TAG_array_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- m_die_to_type[die] = DIE_IS_BEING_PARSED;
-
- lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
- int64_t first_index = 0;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- bool is_vector = false;
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
-
- if (num_attributes > 0)
- {
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name:
- type_name_cstr = form_value.AsCString(&get_debug_str_data());
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_type: type_die_offset = form_value.Reference(); break;
- case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
- case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
- case DW_AT_GNU_vector: is_vector = form_value.Boolean(); 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_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_ordering:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
-
- Type *element_type = ResolveTypeUID(type_die_offset);
-
- if (element_type)
- {
- std::vector<uint64_t> element_orders;
- ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
- if (byte_stride == 0 && bit_stride == 0)
- byte_stride = element_type->GetByteSize();
- ClangASTType array_element_type = element_type->GetClangForwardType();
- uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
- if (element_orders.size() > 0)
- {
- uint64_t num_elements = 0;
- std::vector<uint64_t>::const_reverse_iterator pos;
- std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
- for (pos = element_orders.rbegin(); pos != end; ++pos)
- {
- num_elements = *pos;
- clang_type = ast.CreateArrayType (array_element_type,
- num_elements,
- is_vector);
- array_element_type = clang_type;
- array_element_bit_stride = num_elements ?
- array_element_bit_stride * num_elements :
- array_element_bit_stride;
- }
- }
- else
- {
- clang_type = ast.CreateArrayType (array_element_type, 0, is_vector);
- }
- ConstString empty_name;
- type_sp.reset( new Type (MakeUserID(die->GetOffset()),
- this,
- empty_name,
- array_element_bit_stride / 8,
- NULL,
- type_die_offset,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateFull));
- type_sp->SetEncodingType (element_type);
- }
- }
- }
- break;
+ TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
- case DW_TAG_ptr_to_member_type:
- {
- dw_offset_t type_die_offset = DW_INVALID_OFFSET;
- dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
-
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i=0; i<num_attributes; ++i)
- {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
- {
- switch (attr)
- {
- case DW_AT_type:
- type_die_offset = form_value.Reference(); break;
- case DW_AT_containing_type:
- containing_type_die_offset = form_value.Reference(); break;
- }
- }
- }
-
- Type *pointee_type = ResolveTypeUID(type_die_offset);
- Type *class_type = ResolveTypeUID(containing_type_die_offset);
-
- ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
- ClangASTType class_clang_type = class_type->GetClangLayoutType();
-
- clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
-
- byte_size = clang_type.GetByteSize(nullptr);
-
- type_sp.reset( new Type (MakeUserID(die->GetOffset()),
- this,
- type_name_const_str,
- byte_size,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- NULL,
- clang_type,
- Type::eResolveStateForward));
- }
-
- break;
- }
- default:
- GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
- die->GetOffset(),
- tag,
- DW_TAG_value_to_name(tag));
- break;
- }
-
- if (type_sp.get())
+ if (type_system)
+ {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast)
{
- const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
-
- SymbolContextScope * symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit)
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
+ if (type_sp)
{
- symbol_context_scope = sc.comp_unit;
+ TypeList* type_list = GetTypeList();
+ if (type_list)
+ type_list->Insert(type_sp);
}
- else if (sc.function != NULL && sc_parent_die)
- {
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- }
-
- if (symbol_context_scope != NULL)
- {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
-
- // We are ready to put this type into the uniqued list up at the module level
- type_list->Insert (type_sp);
-
- m_die_to_type[die] = type_sp.get();
}
}
- else if (type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- }
}
+
return type_sp;
}
@@ -7185,38 +3763,38 @@ size_t
SymbolFileDWARF::ParseTypes
(
const SymbolContext& sc,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *die,
+ const DWARFDIE &orig_die,
bool parse_siblings,
bool parse_children
)
{
size_t types_added = 0;
- while (die != NULL)
+ DWARFDIE die = orig_die;
+ while (die)
{
bool type_is_new = false;
- if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
+ if (ParseType(sc, die, &type_is_new).get())
{
if (type_is_new)
++types_added;
}
- if (parse_children && die->HasChildren())
+ if (parse_children && die.HasChildren())
{
- if (die->Tag() == DW_TAG_subprogram)
+ if (die.Tag() == DW_TAG_subprogram)
{
SymbolContext child_sc(sc);
- child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
- types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
+ child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
+ types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
}
else
- types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
+ types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
}
if (parse_siblings)
- die = die->GetSibling();
+ die = die.GetSibling();
else
- die = NULL;
+ die.Clear();
}
return types_added;
}
@@ -7230,11 +3808,11 @@ SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu)
{
- dw_offset_t function_die_offset = sc.function->GetID();
- const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
+ const dw_offset_t function_die_offset = sc.function->GetID();
+ DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
if (function_die)
{
- ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
+ ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
}
}
@@ -7254,18 +3832,18 @@ SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
if (sc.function)
{
dw_offset_t function_die_offset = sc.function->GetID();
- const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
- if (func_die && func_die->HasChildren())
+ DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
+ if (func_die && func_die.HasChildren())
{
- types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
+ types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
}
}
else
{
- const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
- if (dwarf_cu_die && dwarf_cu_die->HasChildren())
+ DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
+ if (dwarf_cu_die && dwarf_cu_die.HasChildren())
{
- types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
+ types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
}
}
}
@@ -7284,17 +3862,12 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
if (sc.function)
{
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
+ DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
- if (dwarf_cu == NULL)
- return 0;
-
- const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
-
- dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
if (func_lo_pc != LLDB_INVALID_ADDRESS)
{
- const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
+ const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
// Let all blocks know they have parse all their variables
sc.function->GetBlock (false).SetDidParseVariables (true, true);
@@ -7303,7 +3876,7 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
}
else if (sc.comp_unit)
{
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
if (dwarf_cu == NULL)
return 0;
@@ -7316,8 +3889,6 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
variables.reset(new VariableList());
sc.comp_unit->SetVariableList(variables);
- DWARFCompileUnit* match_dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
DIEArray die_offsets;
if (m_using_apple_tables)
{
@@ -7340,7 +3911,6 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
Index ();
m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
die_offsets);
}
@@ -7350,11 +3920,11 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
DWARFDebugInfo* debug_info = DebugInfo();
for (size_t i=0; i<num_matches; ++i)
{
- const dw_offset_t die_offset = die_offsets[i];
- die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
+ const DIERef& die_ref = die_offsets[i];
+ DWARFDIE die = debug_info->GetDIE (die_ref);
if (die)
{
- VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
+ VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
if (var_sp)
{
variables->AddVariableIfUnique (var_sp);
@@ -7365,7 +3935,7 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
{
if (m_using_apple_tables)
{
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
}
}
@@ -7378,37 +3948,43 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
return 0;
}
-
VariableSP
SymbolFileDWARF::ParseVariableDIE
(
const SymbolContext& sc,
- DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *die,
+ const DWARFDIE &die,
const lldb::addr_t func_low_pc
)
{
- VariableSP var_sp (m_die_to_variable_sp[die]);
+ if (die.GetDWARF() != this)
+ return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
+
+ VariableSP var_sp;
+ if (!die)
+ return var_sp;
+
+ var_sp = GetDIEToVariable()[die.GetDIE()];
if (var_sp)
return var_sp; // Already been parsed!
- const dw_tag_t tag = die->Tag();
+ const dw_tag_t tag = die.Tag();
ModuleSP module = GetObjectFile()->GetModule();
if ((tag == DW_TAG_variable) ||
(tag == DW_TAG_constant) ||
(tag == DW_TAG_formal_parameter && sc.function))
{
- DWARFDebugInfoEntry::Attributes attributes;
- const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ DWARFDIE spec_die;
if (num_attributes > 0)
{
const char *name = NULL;
const char *mangled = NULL;
Declaration decl;
uint32_t i;
- lldb::user_id_t type_uid = LLDB_INVALID_UID;
- DWARFExpression location;
+ DWARFFormValue type_die_form;
+ DWARFExpression location(die.GetCU());
bool is_external = false;
bool is_artificial = false;
bool location_is_const_value_data = false;
@@ -7421,17 +3997,17 @@ SymbolFileDWARF::ParseVariableDIE
dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
{
switch (attr)
{
case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
+ case DW_AT_name: name = form_value.AsCString(); break;
case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
- case DW_AT_type: type_uid = form_value.Reference(); break;
+ case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
+ case DW_AT_type: type_die_form = form_value; break;
case DW_AT_external: is_external = form_value.Boolean(); break;
case DW_AT_const_value:
// If we have already found a DW_AT_location attribute, ignore this attribute.
@@ -7450,9 +4026,12 @@ SymbolFileDWARF::ParseVariableDIE
else if (DWARFFormValue::IsDataForm(form_value.Form()))
{
// Retrieve the value as a data expression.
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize (
+ attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
if (data_length == 0)
{
const uint8_t *data_pointer = form_value.BlockData();
@@ -7474,14 +4053,17 @@ SymbolFileDWARF::ParseVariableDIE
// Retrieve the value as a string expression.
if (form_value.Form() == DW_FORM_strp)
{
- const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize (
+ attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
}
else
{
- const char *str = form_value.AsCString(&debug_info_data);
+ const char *str = form_value.AsCString();
uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
uint32_t string_length = strlen(str) + 1;
location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
@@ -7503,10 +4085,10 @@ SymbolFileDWARF::ParseVariableDIE
}
else
{
- const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
+ const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
- size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
+ size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
if (loc_list_length > 0)
{
location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
@@ -7516,7 +4098,13 @@ SymbolFileDWARF::ParseVariableDIE
}
}
break;
-
+ case DW_AT_specification:
+ {
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
+ spec_die = debug_info->GetDIE(DIERef(form_value));
+ break;
+ }
case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
@@ -7528,16 +4116,18 @@ SymbolFileDWARF::ParseVariableDIE
default:
case DW_AT_abstract_origin:
case DW_AT_sibling:
- case DW_AT_specification:
break;
}
}
}
+ const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
+ const dw_tag_t parent_tag = die.GetParent().Tag();
+ bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type);
+
ValueType scope = eValueTypeInvalid;
- const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
- dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
SymbolContextScope * symbol_context_scope = NULL;
if (!mangled)
@@ -7548,12 +4138,12 @@ SymbolFileDWARF::ParseVariableDIE
// B which in turn is contained in a namespace A, the command "frame var j" returns
// "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
// to generate a fully qualified name from the declaration context.
- if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
- LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()))
+ if (parent_tag == DW_TAG_compile_unit &&
+ Language::LanguageIsCPlusPlus(die.GetLanguage()))
{
DWARFDeclContext decl_ctx;
- die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
+ die.GetDWARFDeclContext(decl_ctx);
mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
}
}
@@ -7582,7 +4172,7 @@ SymbolFileDWARF::ParseVariableDIE
{
StreamString strm;
location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
- GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
}
}
@@ -7670,7 +4260,10 @@ SymbolFileDWARF::ParseVariableDIE
}
else
{
- scope = eValueTypeVariableLocal;
+ if (location_is_const_value_data)
+ scope = eValueTypeVariableStatic;
+ else
+ scope = eValueTypeVariableLocal;
}
}
@@ -7683,7 +4276,7 @@ SymbolFileDWARF::ParseVariableDIE
case DW_TAG_lexical_block:
if (sc.function)
{
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
if (symbol_context_scope == NULL)
symbol_context_scope = sc.function;
}
@@ -7697,12 +4290,12 @@ SymbolFileDWARF::ParseVariableDIE
if (symbol_context_scope)
{
- SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
+ SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID()));
if (const_value.Form() && type_sp && type_sp->GetType())
- location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), dwarf_cu->GetAddressByteSize());
+ location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
- var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
+ var_sp.reset (new Variable (die.GetID(),
name,
mangled,
type_sp,
@@ -7711,7 +4304,8 @@ SymbolFileDWARF::ParseVariableDIE
&decl,
location,
is_external,
- is_artificial));
+ is_artificial,
+ is_static_member));
var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
}
@@ -7727,57 +4321,42 @@ SymbolFileDWARF::ParseVariableDIE
// was missing vital information to be able to be displayed in the debugger
// (missing location due to optimization, etc)) so we don't re-parse
// this DIE over and over later...
- m_die_to_variable_sp[die] = var_sp;
+ GetDIEToVariable()[die.GetDIE()] = var_sp;
+ if (spec_die)
+ GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
}
return var_sp;
}
-const DWARFDebugInfoEntry *
-SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
- dw_offset_t spec_block_die_offset,
- DWARFCompileUnit **result_die_cu_handle)
+DWARFDIE
+SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
+ dw_offset_t spec_block_die_offset)
{
// Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- DWARFDebugInfo* info = DebugInfo();
-
- const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
- if (die)
- {
- assert (*result_die_cu_handle);
- return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
- }
- return NULL;
+ return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
}
-const DWARFDebugInfoEntry *
-SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
- const DWARFDebugInfoEntry *die,
- dw_offset_t spec_block_die_offset,
- DWARFCompileUnit **result_die_cu_handle)
+DWARFDIE
+SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
+ dw_offset_t spec_block_die_offset)
{
if (die)
{
- switch (die->Tag())
+ switch (die.Tag())
{
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
{
- if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
- {
- *result_die_cu_handle = dwarf_cu;
+ if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
return die;
- }
- if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
- {
- *result_die_cu_handle = dwarf_cu;
+ if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
return die;
- }
}
break;
}
@@ -7785,49 +4364,42 @@ SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
// Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
{
- const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
- child_die,
- spec_block_die_offset,
- result_die_cu_handle);
+ DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
if (result_die)
return result_die;
}
}
- *result_die_cu_handle = NULL;
- return NULL;
+ return DWARFDIE();
}
size_t
-SymbolFileDWARF::ParseVariables
-(
- const SymbolContext& sc,
- DWARFCompileUnit* dwarf_cu,
- const lldb::addr_t func_low_pc,
- const DWARFDebugInfoEntry *orig_die,
- bool parse_siblings,
- bool parse_children,
- VariableList* cc_variable_list
-)
+SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
+ const DWARFDIE &orig_die,
+ const lldb::addr_t func_low_pc,
+ bool parse_siblings,
+ bool parse_children,
+ VariableList* cc_variable_list)
{
- if (orig_die == NULL)
+ if (!orig_die)
return 0;
VariableListSP variable_list_sp;
size_t vars_added = 0;
- const DWARFDebugInfoEntry *die = orig_die;
- while (die != NULL)
+ DWARFDIE die = orig_die;
+ while (die)
{
- dw_tag_t tag = die->Tag();
+ dw_tag_t tag = die.Tag();
// Check to see if we have already parsed this variable or constant?
- if (m_die_to_variable_sp[die])
+ VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
+ if (var_sp)
{
if (cc_variable_list)
- cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
+ cc_variable_list->AddVariableIfUnique (var_sp);
}
else
{
@@ -7838,8 +4410,8 @@ SymbolFileDWARF::ParseVariables
{
if (variable_list_sp.get() == NULL)
{
- const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
- dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+ DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
+ dw_tag_t parent_tag = sc_parent_die.Tag();
switch (parent_tag)
{
case DW_TAG_compile_unit:
@@ -7855,10 +4427,10 @@ SymbolFileDWARF::ParseVariables
else
{
GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
- MakeUserID(sc_parent_die->GetOffset()),
- DW_TAG_value_to_name (parent_tag),
- MakeUserID(orig_die->GetOffset()),
- DW_TAG_value_to_name (orig_die->Tag()));
+ sc_parent_die.GetID(),
+ sc_parent_die.GetTagAsCString(),
+ orig_die.GetID(),
+ orig_die.GetTagAsCString());
}
break;
@@ -7869,19 +4441,17 @@ SymbolFileDWARF::ParseVariables
{
// Check to see if we already have parsed the variables for the given scope
- Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+ Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
if (block == NULL)
{
// This must be a specification or abstract origin with
// a concrete block counterpart in the current function. We need
// to find the concrete block so we can correctly add the
// variable to it
- DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
- const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
- sc_parent_die->GetOffset(),
- &concrete_block_die_cu);
+ const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
+ sc_parent_die.GetOffset());
if (concrete_block_die)
- block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
+ block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
}
if (block != NULL)
@@ -7899,15 +4469,15 @@ SymbolFileDWARF::ParseVariables
default:
GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
- MakeUserID(orig_die->GetOffset()),
- DW_TAG_value_to_name (orig_die->Tag()));
+ orig_die.GetID(),
+ orig_die.GetTagAsCString());
break;
}
}
if (variable_list_sp)
{
- VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
+ VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
if (var_sp)
{
variable_list_sp->AddVariableIfUnique (var_sp);
@@ -7921,15 +4491,15 @@ SymbolFileDWARF::ParseVariables
bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
- if (!skip_children && parse_children && die->HasChildren())
+ if (!skip_children && parse_children && die.HasChildren())
{
- vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
+ vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
}
if (parse_siblings)
- die = die->GetSibling();
+ die = die.GetSibling();
else
- die = NULL;
+ die.Clear();
}
return vars_added;
}
@@ -7950,24 +4520,6 @@ SymbolFileDWARF::GetPluginVersion()
}
void
-SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
-{
- SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
- ClangASTType 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;
- ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
- if (clang_type)
- symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
-}
-
-void
SymbolFileDWARF::DumpIndexes ()
{
StreamFile s(stdout, false);
@@ -7982,147 +4534,7 @@ SymbolFileDWARF::DumpIndexes ()
s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
-}
-
-void
-SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
- const char *name,
- llvm::SmallVectorImpl <clang::NamedDecl *> *results)
-{
- DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
-
- if (iter == m_decl_ctx_to_die.end())
- return;
-
- for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
- {
- const DWARFDebugInfoEntry *context_die = *pos;
-
- if (!results)
- return;
-
- DWARFDebugInfo* info = DebugInfo();
-
- DIEArray die_offsets;
-
- DWARFCompileUnit* dwarf_cu = NULL;
- const DWARFDebugInfoEntry* die = NULL;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- m_apple_types_ap->FindByName (name, die_offsets);
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (ConstString(name), die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
-
- if (num_matches)
- {
- for (size_t i = 0; i < num_matches; ++i)
- {
- const dw_offset_t die_offset = die_offsets[i];
- die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
-
- if (die->GetParent() != context_die)
- continue;
-
- Type *matching_type = ResolveType (dwarf_cu, die);
-
- clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
-
- if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
- {
- clang::TagDecl *tag_decl = tag_type->getDecl();
- results->push_back(tag_decl);
- }
- else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
- {
- clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
- results->push_back(typedef_decl);
- }
- }
- }
- }
-}
-
-void
-SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
- const clang::DeclContext *decl_context,
- clang::DeclarationName decl_name,
- llvm::SmallVectorImpl <clang::NamedDecl *> *results)
-{
-
- switch (decl_context->getDeclKind())
- {
- case clang::Decl::Namespace:
- case clang::Decl::TranslationUnit:
- {
- SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
- symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
- }
- break;
- default:
- break;
- }
-}
-
-bool
-SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
- uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
-{
- SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
- return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
-}
-
-bool
-SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
- bool success = false;
- base_offsets.clear();
- vbase_offsets.clear();
- if (pos != m_record_decl_to_layout_map.end())
- {
- bit_size = pos->second.bit_size;
- alignment = pos->second.alignment;
- field_offsets.swap(pos->second.field_offsets);
- base_offsets.swap (pos->second.base_offsets);
- vbase_offsets.swap (pos->second.vbase_offsets);
- m_record_decl_to_layout_map.erase(pos);
- success = true;
- }
- else
- {
- bit_size = 0;
- alignment = 0;
- field_offsets.clear();
- }
-
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
- static_cast<const void*>(record_decl),
- bit_size, alignment,
- static_cast<uint32_t>(field_offsets.size()),
- static_cast<uint32_t>(base_offsets.size()),
- static_cast<uint32_t>(vbase_offsets.size()),
- success);
- return success;
+ s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
}
@@ -8142,4 +4554,8 @@ SymbolFileDWARF::GetDebugMapSymfile ()
return m_debug_map_symfile;
}
-
+DWARFExpression::LocationListFormat
+SymbolFileDWARF::GetLocationListFormat() const
+{
+ return DWARFExpression::RegularLocationList;
+}
OpenPOWER on IntegriCloud