aboutsummaryrefslogtreecommitdiffstats
path: root/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
commitead246455adf1a215ec2715dad6533073a6beb4e (patch)
treef3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Plugins/SymbolFile
parentfdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff)
downloadsrc-ead246455adf1a215ec2715dad6533073a6beb4e.tar.gz
src-ead246455adf1a215ec2715dad6533073a6beb4e.zip
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes: svn path=/vendor/lldb/dist/; revision=353952 svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
Diffstat (limited to 'source/Plugins/SymbolFile')
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp257
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h84
-rw-r--r--source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp1078
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h91
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp20
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp1038
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h227
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp24
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp67
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp959
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h72
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp237
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h50
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td12
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp2
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp29
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h7
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp60
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp143
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h58
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp23
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp2
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp345
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h56
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp38
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h18
48 files changed, 2143 insertions, 3082 deletions
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index d4258274a38c..f84cf0c5368d 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -15,7 +15,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Utility/Log.h"
@@ -126,8 +125,8 @@ SymbolFileBreakpad::LineIterator::operator++() {
llvm::iterator_range<SymbolFileBreakpad::LineIterator>
SymbolFileBreakpad::lines(Record::Kind section_type) {
- return llvm::make_range(LineIterator(*m_obj_file, section_type),
- LineIterator(*m_obj_file));
+ return llvm::make_range(LineIterator(*m_objfile_sp, section_type),
+ LineIterator(*m_objfile_sp));
}
namespace {
@@ -179,15 +178,13 @@ ConstString SymbolFileBreakpad::GetPluginNameStatic() {
}
uint32_t SymbolFileBreakpad::CalculateAbilities() {
- if (!m_obj_file)
- return 0;
- if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
+ if (!m_objfile_sp || !llvm::isa<ObjectFileBreakpad>(*m_objfile_sp))
return 0;
return CompileUnits | Functions | LineTables;
}
-uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
+uint32_t SymbolFileBreakpad::CalculateNumCompileUnits() {
ParseCUData();
return m_cu_data->GetSize();
}
@@ -204,7 +201,8 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
// The FileSpec of the compile unit will be the file corresponding to the
// first LINE record.
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
++It; // Skip FUNC record.
if (It != End) {
@@ -213,12 +211,12 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
spec = (*m_files)[record->FileNum];
}
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(),
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(),
/*user_data*/ nullptr, spec, index,
eLanguageTypeUnknown,
/*is_optimized*/ eLazyBoolNo);
- GetSymbolVendor().SetCompileUnitAtIndex(index, cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -228,6 +226,7 @@ size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.line_table_up)
@@ -239,6 +238,7 @@ bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
if (!data.support_files)
ParseLineTableAndSupportFiles(comp_unit, data);
@@ -251,6 +251,7 @@ uint32_t
SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry)))
return 0;
@@ -260,7 +261,7 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
if (idx == UINT32_MAX)
return 0;
- sc.comp_unit = GetSymbolVendor().GetCompileUnitAtIndex(idx).get();
+ sc.comp_unit = GetCompileUnitAtIndex(idx).get();
SymbolContextItem result = eSymbolContextCompUnit;
if (resolve_scope & eSymbolContextLineEntry) {
if (sc.comp_unit->GetLineTable()->FindLineEntryByAddress(so_addr,
@@ -275,57 +276,43 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
uint32_t SymbolFileBreakpad::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!(resolve_scope & eSymbolContextCompUnit))
return 0;
uint32_t old_size = sc_list.GetSize();
for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
- CompileUnit &cu = *GetSymbolVendor().GetCompileUnitAtIndex(i);
+ CompileUnit &cu = *GetCompileUnitAtIndex(i);
cu.ResolveSymbolContext(file_spec, line, check_inlines,
/*exact*/ false, resolve_scope, sc_list);
}
return sc_list.GetSize() - old_size;
}
-uint32_t SymbolFileBreakpad::FindFunctions(
+void SymbolFileBreakpad::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
// TODO
- if (!append)
- sc_list.Clear();
- return sc_list.GetSize();
}
-uint32_t SymbolFileBreakpad::FindTypes(
+void SymbolFileBreakpad::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {}
-size_t
-SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
- return types.GetSize();
-}
+void SymbolFileBreakpad::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
- Module &module = *m_obj_file->GetModule();
+ Module &module = *m_objfile_sp->GetModule();
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
@@ -347,8 +334,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
return;
}
symbols.try_emplace(
- address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
- eSymbolTypeCode, /*is_global*/ true, /*is_debug*/ false,
+ address, /*symID*/ 0, Mangled(name), eSymbolTypeCode,
+ /*is_global*/ true, /*is_debug*/ false,
/*is_trampoline*/ false, /*is_artificial*/ false,
AddressRange(section_sp, address - section_sp->GetFileAddress(),
size.getValueOr(0)),
@@ -372,6 +359,20 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
symtab.CalculateSymbolSizes();
}
+llvm::Expected<lldb::addr_t>
+SymbolFileBreakpad::GetParameterStackSize(Symbol &symbol) {
+ ParseUnwindData();
+ if (auto *entry = m_unwind_data->win.FindEntryThatContains(
+ symbol.GetAddress().GetFileAddress())) {
+ auto record = StackWinRecord::parse(
+ *LineIterator(*m_objfile_sp, Record::StackWin, entry->data));
+ assert(record.hasValue());
+ return record->ParameterSize;
+ }
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Parameter size unknown.");
+}
+
static llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
GetRule(llvm::StringRef &unwind_rules) {
// Unwind rules are of the form
@@ -418,7 +419,17 @@ ResolveRegisterOrRA(const SymbolFile::RegisterInfoResolver &resolver,
return ResolveRegister(resolver, name);
}
-bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
+llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) {
+ ArchSpec arch = m_objfile_sp->GetArchitecture();
+ StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
+ arch.GetByteOrder());
+ ToDWARF(node, dwarf);
+ uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
+ std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
+ return {saved, dwarf.GetSize()};
+}
+
+bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules,
const RegisterInfoResolver &resolver,
UnwindPlan::Row &row) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
@@ -427,7 +438,7 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
while (auto rule = GetRule(unwind_rules)) {
node_alloc.Reset();
llvm::StringRef lhs = rule->first;
- postfix::Node *rhs = postfix::Parse(rule->second, node_alloc);
+ postfix::Node *rhs = postfix::ParseOneExpression(rule->second, node_alloc);
if (!rhs) {
LLDB_LOG(log, "Could not parse `{0}` as unwind rhs.", rule->second);
return false;
@@ -451,18 +462,12 @@ bool SymbolFileBreakpad::ParseUnwindRow(llvm::StringRef unwind_rules,
return false;
}
- ArchSpec arch = m_obj_file->GetArchitecture();
- StreamString dwarf(Stream::eBinary, arch.GetAddressByteSize(),
- arch.GetByteOrder());
- ToDWARF(*rhs, dwarf);
- uint8_t *saved = m_allocator.Allocate<uint8_t>(dwarf.GetSize());
- std::memcpy(saved, dwarf.GetData(), dwarf.GetSize());
-
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*rhs);
if (lhs == ".cfa") {
- row.GetCFAValue().SetIsDWARFExpression(saved, dwarf.GetSize());
+ row.GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
} else if (const RegisterInfo *info = ResolveRegisterOrRA(resolver, lhs)) {
UnwindPlan::Row::RegisterLocation loc;
- loc.SetIsDWARFExpression(saved, dwarf.GetSize());
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
row.SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
} else
LLDB_LOG(log, "Invalid register `{0}` in unwind rule.", lhs);
@@ -478,31 +483,40 @@ UnwindPlanSP
SymbolFileBreakpad::GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) {
ParseUnwindData();
- const UnwindMap::Entry *entry =
- m_unwind_data->FindEntryThatContains(address.GetFileAddress());
- if (!entry)
- return nullptr;
+ if (auto *entry =
+ m_unwind_data->cfi.FindEntryThatContains(address.GetFileAddress()))
+ return ParseCFIUnwindPlan(entry->data, resolver);
+ if (auto *entry =
+ m_unwind_data->win.FindEntryThatContains(address.GetFileAddress()))
+ return ParseWinUnwindPlan(entry->data, resolver);
+ return nullptr;
+}
+UnwindPlanSP
+SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS)
return nullptr;
- LineIterator It(*m_obj_file, Record::StackCFI, entry->data), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark),
+ End(*m_objfile_sp);
llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It);
- assert(init_record.hasValue());
- assert(init_record->Size.hasValue());
+ assert(init_record.hasValue() && init_record->Size.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
plan_sp->SetSourceName("breakpad STACK CFI");
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
plan_sp->SetPlanValidAddressRange(
AddressRange(base + init_record->Address, *init_record->Size,
- m_obj_file->GetModule()->GetSectionList()));
+ m_objfile_sp->GetModule()->GetSectionList()));
auto row_sp = std::make_shared<UnwindPlan::Row>();
row_sp->SetOffset(0);
- if (!ParseUnwindRow(init_record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(init_record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
for (++It; It != End; ++It) {
@@ -514,19 +528,107 @@ SymbolFileBreakpad::GetUnwindPlan(const Address &address,
row_sp = std::make_shared<UnwindPlan::Row>(*row_sp);
row_sp->SetOffset(record->Address - init_record->Address);
- if (!ParseUnwindRow(record->UnwindRules, resolver, *row_sp))
+ if (!ParseCFIUnwindRow(record->UnwindRules, resolver, *row_sp))
return nullptr;
plan_sp->AppendRow(row_sp);
}
return plan_sp;
}
-SymbolVendor &SymbolFileBreakpad::GetSymbolVendor() {
- return *m_obj_file->GetModule()->GetSymbolVendor();
+UnwindPlanSP
+SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ addr_t base = GetBaseFileAddress();
+ if (base == LLDB_INVALID_ADDRESS)
+ return nullptr;
+
+ LineIterator It(*m_objfile_sp, Record::StackWin, bookmark);
+ llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It);
+ assert(record.hasValue() &&
+ "Record already parsed successfully in ParseUnwindData!");
+
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB);
+ plan_sp->SetSourceName("breakpad STACK WIN");
+ plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+ plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+ plan_sp->SetPlanValidAddressRange(
+ AddressRange(base + record->RVA, record->CodeSize,
+ m_objfile_sp->GetModule()->GetSectionList()));
+
+ auto row_sp = std::make_shared<UnwindPlan::Row>();
+ row_sp->SetOffset(0);
+
+ llvm::BumpPtrAllocator node_alloc;
+ std::vector<std::pair<llvm::StringRef, postfix::Node *>> program =
+ postfix::ParseFPOProgram(record->ProgramString, node_alloc);
+
+ if (program.empty()) {
+ LLDB_LOG(log, "Invalid unwind rule: {0}.", record->ProgramString);
+ return nullptr;
+ }
+ auto it = program.begin();
+ const auto &symbol_resolver =
+ [&](postfix::SymbolNode &symbol) -> postfix::Node * {
+ llvm::StringRef name = symbol.GetName();
+ for (const auto &rule : llvm::make_range(program.begin(), it)) {
+ if (rule.first == name)
+ return rule.second;
+ }
+ if (const RegisterInfo *info = ResolveRegister(resolver, name))
+ return postfix::MakeNode<postfix::RegisterNode>(
+ node_alloc, info->kinds[eRegisterKindLLDB]);
+ return nullptr;
+ };
+
+ // We assume the first value will be the CFA. It is usually called T0, but
+ // clang will use T1, if it needs to realign the stack.
+ auto *symbol = llvm::dyn_cast<postfix::SymbolNode>(it->second);
+ if (symbol && symbol->GetName() == ".raSearch") {
+ row_sp->GetCFAValue().SetRaSearch(record->LocalSize +
+ record->SavedRegisterSize);
+ } else {
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ row_sp->GetCFAValue().SetIsDWARFExpression(saved.data(), saved.size());
+ }
+
+ // Replace the node value with InitialValueNode, so that subsequent
+ // expressions refer to the CFA value instead of recomputing the whole
+ // expression.
+ it->second = postfix::MakeNode<postfix::InitialValueNode>(node_alloc);
+
+
+ // Now process the rest of the assignments.
+ for (++it; it != program.end(); ++it) {
+ const RegisterInfo *info = ResolveRegister(resolver, it->first);
+ // It is not an error if the resolution fails because the program may
+ // contain temporary variables.
+ if (!info)
+ continue;
+ if (!postfix::ResolveSymbols(it->second, symbol_resolver)) {
+ LLDB_LOG(log, "Resolving symbols in `{0}` failed.",
+ record->ProgramString);
+ return nullptr;
+ }
+
+ llvm::ArrayRef<uint8_t> saved = SaveAsDWARF(*it->second);
+ UnwindPlan::Row::RegisterLocation loc;
+ loc.SetIsDWARFExpression(saved.data(), saved.size());
+ row_sp->SetRegisterInfo(info->kinds[eRegisterKindLLDB], loc);
+ }
+
+ plan_sp->AppendRow(row_sp);
+ return plan_sp;
}
addr_t SymbolFileBreakpad::GetBaseFileAddress() {
- return m_obj_file->GetModule()
+ return m_objfile_sp->GetModule()
->GetObjectFile()
->GetBaseAddress()
.GetFileAddress();
@@ -569,8 +671,8 @@ void SymbolFileBreakpad::ParseCUData() {
// We shall create one compile unit for each FUNC record. So, count the number
// of FUNC records, and store them in m_cu_data, together with their ranges.
- for (LineIterator It(*m_obj_file, Record::Func), End(*m_obj_file); It != End;
- ++It) {
+ for (LineIterator It(*m_objfile_sp, Record::Func), End(*m_objfile_sp);
+ It != End; ++It) {
if (auto record = FuncRecord::parse(*It)) {
m_cu_data->Append(CompUnitMap::Entry(base + record->Address, record->Size,
CompUnitData(It.GetBookmark())));
@@ -589,7 +691,7 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
"How did we create compile units without a base address?");
SupportFileMap map;
- data.line_table_up = llvm::make_unique<LineTable>(&cu);
+ data.line_table_up = std::make_unique<LineTable>(&cu);
std::unique_ptr<LineSequence> line_seq_up(
data.line_table_up->CreateLineSequenceContainer());
llvm::Optional<addr_t> next_addr;
@@ -603,7 +705,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
line_seq_up->Clear();
};
- LineIterator It(*m_obj_file, Record::Func, data.bookmark), End(*m_obj_file);
+ LineIterator It(*m_objfile_sp, Record::Func, data.bookmark),
+ End(*m_objfile_sp);
assert(Record::classify(*It) == Record::Func);
for (++It; It != End; ++It) {
auto record = LineRecord::parse(*It);
@@ -631,8 +734,8 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu,
void SymbolFileBreakpad::ParseUnwindData() {
if (m_unwind_data)
return;
-
m_unwind_data.emplace();
+
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
addr_t base = GetBaseFileAddress();
if (base == LLDB_INVALID_ADDRESS) {
@@ -640,14 +743,24 @@ void SymbolFileBreakpad::ParseUnwindData() {
"of object file.");
}
- for (LineIterator It(*m_obj_file, Record::StackCFI), End(*m_obj_file);
+ for (LineIterator It(*m_objfile_sp, Record::StackCFI), End(*m_objfile_sp);
It != End; ++It) {
if (auto record = StackCFIRecord::parse(*It)) {
if (record->Size)
- m_unwind_data->Append(UnwindMap::Entry(
+ m_unwind_data->cfi.Append(UnwindMap::Entry(
base + record->Address, *record->Size, It.GetBookmark()));
} else
LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
}
- m_unwind_data->Sort();
+ m_unwind_data->cfi.Sort();
+
+ for (LineIterator It(*m_objfile_sp, Record::StackWin), End(*m_objfile_sp);
+ It != End; ++It) {
+ if (auto record = StackWinRecord::parse(*It)) {
+ m_unwind_data->win.Append(UnwindMap::Entry(
+ base + record->RVA, record->CodeSize, It.GetBookmark()));
+ } else
+ LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", *It);
+ }
+ m_unwind_data->win.Sort();
}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 8a0b7645fd0a..a10138cdf92f 100644
--- a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -12,6 +12,7 @@
#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -31,12 +32,13 @@ public:
return "Breakpad debug symbol file reader.";
}
- static SymbolFile *CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileBreakpad(obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp) {
+ return new SymbolFileBreakpad(std::move(objfile_sp));
}
// Constructors and Destructors
- SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
+ SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
~SymbolFileBreakpad() override {}
@@ -46,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
return lldb::eLanguageTypeUnknown;
}
@@ -72,12 +70,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override { return 0; }
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override {
- return 0;
- }
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override {}
size_t ParseVariablesForContext(const SymbolContext &sc) override {
return 0;
@@ -99,31 +95,30 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override {
- return 0;
- }
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override {}
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override {
- return nullptr;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override {
+ return llvm::make_error<llvm::StringError>(
+ "SymbolFileBreakpad does not support GetTypeSystemForLanguage",
+ llvm::inconvertibleErrorCode());
}
CompilerDeclContext
@@ -134,6 +129,8 @@ public:
void AddSymbols(Symtab &symtab) override;
+ llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
+
lldb::UnwindPlanSP
GetUnwindPlan(const Address &address,
const RegisterInfoResolver &resolver) override;
@@ -196,15 +193,22 @@ private:
};
- SymbolVendor &GetSymbolVendor();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::addr_t GetBaseFileAddress();
void ParseFileRecords();
void ParseCUData();
void ParseLineTableAndSupportFiles(CompileUnit &cu, CompUnitData &data);
void ParseUnwindData();
- bool ParseUnwindRow(llvm::StringRef unwind_rules,
- const RegisterInfoResolver &resolver,
- UnwindPlan::Row &row);
+ llvm::ArrayRef<uint8_t> SaveAsDWARF(postfix::Node &node);
+ lldb::UnwindPlanSP ParseCFIUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
+ bool ParseCFIUnwindRow(llvm::StringRef unwind_rules,
+ const RegisterInfoResolver &resolver,
+ UnwindPlan::Row &row);
+ lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark,
+ const RegisterInfoResolver &resolver);
using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>;
@@ -212,7 +216,11 @@ private:
llvm::Optional<CompUnitMap> m_cu_data;
using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>;
- llvm::Optional<UnwindMap> m_unwind_data;
+ struct UnwindData {
+ UnwindMap cfi;
+ UnwindMap win;
+ };
+ llvm::Optional<UnwindData> m_unwind_data;
llvm::BumpPtrAllocator m_allocator;
};
diff --git a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 9ae047da1325..0a5073b8cd9e 100644
--- a/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -21,30 +21,30 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
Module &module, DWARFDataExtractor apple_names,
DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
- auto apple_names_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_names, debug_str, ".apple_names");
if (!apple_names_table_up->IsValid())
apple_names_table_up.reset();
auto apple_namespaces_table_up =
- llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ std::make_unique<DWARFMappedHash::MemoryTable>(
apple_namespaces, debug_str, ".apple_namespaces");
if (!apple_namespaces_table_up->IsValid())
apple_namespaces_table_up.reset();
- auto apple_types_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_types, debug_str, ".apple_types");
if (!apple_types_table_up->IsValid())
apple_types_table_up.reset();
- auto apple_objc_table_up = llvm::make_unique<DWARFMappedHash::MemoryTable>(
+ auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
apple_objc, debug_str, ".apple_objc");
if (!apple_objc_table_up->IsValid())
apple_objc_table_up.reset();
if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
apple_objc_table_up)
- return llvm::make_unique<AppleDWARFIndex>(
+ return std::make_unique<AppleDWARFIndex>(
module, std::move(apple_names_table_up),
std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
std::move(apple_objc_table_up));
@@ -110,6 +110,7 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
const bool has_qualified_name_hash =
m_apple_types_up->GetHeader().header_data.ContainsAtom(
DWARFMappedHash::eAtomTypeQualNameHash);
+
const ConstString type_name(context[0].name);
const dw_tag_t tag = context[0].tag;
if (has_tag && has_qualified_name_hash) {
@@ -119,12 +120,32 @@ void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
type_name.GetStringRef(), tag, qualified_name_hash, offsets);
- } else if (has_tag) {
+ return;
+ }
+
+ if (has_tag) {
+ // When searching for a scoped type (for example,
+ // "std::vector<int>::const_iterator") searching for the innermost
+ // name alone ("const_iterator") could yield many false
+ // positives. By searching for the parent type ("vector<int>")
+ // first we can avoid extracting type DIEs from object files that
+ // would fail the filter anyway.
+ if (!has_qualified_name_hash && (context.GetSize() > 1) &&
+ (context[1].tag == DW_TAG_class_type ||
+ context[1].tag == DW_TAG_structure_type)) {
+ DIEArray class_matches;
+ m_apple_types_up->FindByName(context[1].name, class_matches);
+ if (class_matches.empty())
+ return;
+ }
+
if (log)
m_module.LogMessage(log, "FindByNameAndTag()");
m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
- } else
- m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
+ return;
+ }
+
+ m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
}
void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index e7927b31b9c3..7ee4727cde91 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -28,7 +28,6 @@ public:
virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
const DWARFDIE &die,
- lldb_private::Log *log,
bool *type_is_new_ptr) = 0;
virtual lldb_private::Function *
@@ -48,8 +47,8 @@ public:
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) = 0;
- virtual std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
+ virtual void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) = 0;
static llvm::Optional<lldb_private::SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b85ab54a10d3..636e6032b877 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -9,7 +9,6 @@
#include <stdlib.h>
#include "DWARFASTParserClang.h"
-#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
@@ -28,7 +27,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/Language.h"
@@ -144,23 +143,27 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
// If this type comes from a Clang module, look in the DWARF section
// of the pcm file in the module cache. Clang generates DWO skeleton
// units as breadcrumbs to find them.
- std::vector<CompilerContext> decl_context;
+ llvm::SmallVector<CompilerContext, 4> decl_context;
die.GetDeclContext(decl_context);
TypeMap dwo_types;
- if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true,
- dwo_types)) {
+ // The type in the Clang module must have the same language as the current CU.
+ LanguageSet languages;
+ languages.Insert(die.GetCU()->GetLanguageType());
+ dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, dwo_types);
+ if (dwo_types.Empty()) {
if (!IsClangModuleFwdDecl(die))
return TypeSP();
- // Since this this type is defined in one of the Clang modules imported by
- // this symbol file, search all of them.
+ // Since this type is defined in one of the Clang modules imported
+ // by this symbol file, search all of them.
auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
for (const auto &name_module : sym_file.getExternalTypeModules()) {
if (!name_module.second)
continue;
- SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
- if (sym_vendor->FindTypes(decl_context, true, dwo_types))
+ name_module.second->GetSymbolFile()->FindTypes(decl_context,
+ languages, dwo_types);
+ if (dwo_types.GetSize())
break;
}
}
@@ -188,7 +191,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
&dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
- dwarf->GetTypeList()->Insert(type_sp);
+ dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
if (tag_decl)
@@ -228,42 +231,7 @@ static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
}
}
-namespace {
-/// Parsed form of all attributes that are relevant for type reconstruction.
-/// Some attributes are relevant for all kinds of types (declaration), while
-/// others are only meaningful to a specific type (is_virtual)
-struct ParsedTypeAttributes {
- explicit ParsedTypeAttributes(const DWARFDIE &die);
-
- AccessType accessibility = eAccessNone;
- bool is_artificial = false;
- bool is_complete_objc_class = false;
- bool is_explicit = false;
- bool is_forward_declaration = false;
- bool is_inline = false;
- bool is_scoped_enum = false;
- bool is_vector = false;
- bool is_virtual = false;
- clang::StorageClass storage = clang::SC_None;
- const char *mangled_name = nullptr;
- ConstString name;
- Declaration decl;
- DWARFDIE object_pointer;
- DWARFFormValue abstract_origin;
- DWARFFormValue containing_type;
- DWARFFormValue signature;
- DWARFFormValue specification;
- DWARFFormValue type;
- LanguageType class_language = eLanguageTypeUnknown;
- llvm::Optional<uint64_t> byte_size;
- size_t calling_convention = llvm::dwarf::DW_CC_normal;
- uint32_t bit_stride = 0;
- uint32_t byte_stride = 0;
- uint32_t encoding = 0;
-};
-} // namespace
-
-ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die) {
+ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
DWARFAttributes attributes;
size_t num_attributes = die.GetAttributes(attributes);
for (size_t i = 0; i < num_attributes; ++i) {
@@ -390,13 +358,17 @@ static std::string GetUnitName(const DWARFDIE &die) {
}
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die, Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) {
if (type_is_new_ptr)
*type_is_new_ptr = false;
if (!die)
return nullptr;
+
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS));
+
SymbolFileDWARF *dwarf = die.GetDWARF();
if (log) {
DWARFDIE context_die;
@@ -420,11 +392,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// Set a bit that lets us know that we are currently parsing this
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
- ParsedTypeAttributes attrs(die);
+ ParsedDWARFTypeAttributes attrs(die);
if (DWARFDIE signature_die = attrs.signature.Reference()) {
if (TypeSP type_sp =
- ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
+ ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
if (clang::DeclContext *decl_ctx =
GetCachedClangDeclContextForDIE(signature_die))
@@ -434,7 +406,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
return nullptr;
}
- TypeList *type_list = dwarf->GetTypeList();
if (type_is_new_ptr)
*type_is_new_ptr = true;
@@ -562,7 +533,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
bool function_type_is_new_pointer;
TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
- sc, function_type, log, &function_type_is_new_pointer);
+ sc, function_type, &function_type_is_new_pointer);
if (lldb_function_type_sp) {
clang_type = m_ast.CreateBlockPointerType(
@@ -660,370 +631,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type: {
- // 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_up(
- new UniqueDWARFASTType());
-
- ConstString unique_typename(attrs.name);
- Declaration unique_decl(attrs.decl);
-
- if (attrs.name) {
- if (Language::LanguageIsCPlusPlus(cu_language)) {
- // For C++, we rely solely upon the one definition rule that says
- // only one thing can exist at a given decl context. We ignore the
- // file and line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
-
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
- *unique_ast_entry_up)) {
- type_sp = unique_ast_entry_up->m_type_sp;
- if (type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- 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 (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
- !die.HasChildren() && cu_language == 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.
- attrs.is_forward_declaration = true;
- }
-
- if (attrs.class_language == eLanguageTypeObjC ||
- attrs.class_language == eLanguageTypeObjC_plus_plus) {
- if (!attrs.is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // 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 =
- dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, attrs.name, true);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->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), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
- if (attrs.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) {
- dwarf->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), attrs.name.GetCString());
- }
-
- // See if the type comes from a DWO module and if so, track down that
- // type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert(tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, nullptr);
-
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
- attrs.name.GetCString());
-
- if (attrs.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))
- attrs.accessibility = default_accessibility;
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
-
- if (attrs.name.GetStringRef().contains('<')) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos(die, template_param_infos)) {
- clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
- attrs.name.GetCString(),
- tag_decl_kind, template_param_infos);
- if (!class_template_decl) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
- "clang::ClassTemplateDecl failed to return a decl.",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString());
- }
- return TypeSP();
- }
-
- clang::ClassTemplateSpecializationDecl *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType(
- class_specialization_decl);
- clang_type_was_created = true;
-
- m_ast.SetMetadata(class_template_decl, metadata);
- m_ast.SetMetadata(class_specialization_decl, metadata);
- }
- }
-
- if (!clang_type_was_created) {
- clang_type_was_created = true;
- clang_type = m_ast.CreateRecordType(
- decl_ctx, attrs.accessibility, attrs.name.GetCString(),
- tag_decl_kind, attrs.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(m_ast.GetDeclContextForType(clang_type), die);
- type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
- attrs.byte_size, nullptr, LLDB_INVALID_UID,
- Type::eEncodingIsUID, &attrs.decl, clang_type,
- Type::eResolveStateForward);
-
- type_sp->SetIsCompleteObjCClass(attrs.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_up->m_type_sp = type_sp;
- unique_ast_entry_up->m_die = die;
- unique_ast_entry_up->m_declaration = unique_decl;
- unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
- dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
- *unique_ast_entry_up);
-
- if (attrs.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
- DWARFDIE 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.Clear();
- attrs.is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
- }
-
- if (!attrs.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()) {
- // No children for this struct/union/class, lets finish it
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), attrs.name.GetCString());
- }
-
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
-
- if (record_decl) {
- GetClangASTImporter().InsertRecordDecl(
- record_decl, ClangASTImporter::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 (attrs.class_language != eLanguageTypeObjC &&
- attrs.class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
-
- // 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::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
- ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a
- // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
- // binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
- clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
- die.GetID();
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- }
- }
-
- // If we made a clang type, set the trivial abi if applicable: We only
- // do this for pass by value - which implies the Trivial ABI. There
- // isn't a way to assert that something that would normally be pass by
- // value is pass by reference, so we ignore that attribute if set.
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl) {
- record_decl->setHasTrivialSpecialMemberForCall();
- }
- }
-
- if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl)
- record_decl->setArgPassingRestrictions(
- clang::RecordDecl::APK_CannotPassInRegs);
- }
-
- } break;
+ assert((!type_sp && !clang_type) &&
+ "Did not expect partially computed structure-like type");
+ TypeSP struct_like_type_sp = ParseStructureLikeDIE(die, attrs);
+ return UpdateSymbolContextScopeForType(sc, die, struct_like_type_sp);
+ }
case DW_TAG_enumeration_type: {
if (attrs.is_forward_declaration) {
@@ -1395,8 +1007,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
is_attr_used, attrs.is_artificial);
type_handled = cxx_method_decl != NULL;
+ // Artificial methods are always handled even when we
+ // don't create a new declaration for them.
+ type_handled |= attrs.is_artificial;
- if (type_handled) {
+ if (cxx_method_decl) {
LinkDeclContextToDIE(
ClangASTContext::GetAsDeclContext(cxx_method_decl),
die);
@@ -1407,12 +1022,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
m_ast.SetMetadata(cxx_method_decl, metadata);
} else {
@@ -1520,11 +1134,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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));
+ LLDB_LOGF(log,
+ "Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
}
m_ast.SetMetadata(function_decl, metadata);
}
@@ -1651,31 +1265,418 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
break;
}
- if (type_sp.get()) {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ // TODO: We should consider making the switch above exhaustive to simplify
+ // control flow in ParseTypeFromDWARF. Then, we could simply replace this
+ // return statement with a call to llvm_unreachable.
+ return UpdateSymbolContextScopeForType(sc, die, type_sp);
+}
+
+TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
+ const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
+ if (!type_sp)
+ return type_sp;
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ TypeList &type_list = dwarf->GetTypeList();
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = NULL;
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
+ symbol_context_scope = sc.comp_unit;
+ } else if (sc.function != NULL && sc_parent_die) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ } else {
+ symbol_context_scope = sc.module_sp.get();
+ }
+
+ if (symbol_context_scope != NULL)
+ type_sp->SetSymbolContextScope(symbol_context_scope);
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- } else
- symbol_context_scope = sc.module_sp.get();
+ // We are ready to put this type into the uniqued list up at the module
+ // level.
+ type_list.Insert(type_sp);
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+}
+
+TypeSP
+DWARFASTParserClang::ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs) {
+ TypeSP type_sp;
+ CompilerType clang_type;
+ const dw_tag_t tag = die.Tag();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ LanguageType cu_language = die.GetLanguage();
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS);
+
+ // 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 at sharing the stack space for variables in different
+ // blocks.
+ auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
+
+ ConstString unique_typename(attrs.name);
+ Declaration unique_decl(attrs.decl);
+
+ if (attrs.name) {
+ if (Language::LanguageIsCPlusPlus(cu_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
+
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1),
+ *unique_ast_entry_up)) {
+ type_sp = unique_ast_entry_up->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ LinkDeclContextToDIE(
+ GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
+ return type_sp;
+ }
}
+ }
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ 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;
+ }
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == 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.
+ attrs.is_forward_declaration = true;
+ }
+
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // 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 =
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->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), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
+
+ if (attrs.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) {
+ dwarf->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),
+ attrs.name.GetCString());
+ }
+
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ attrs.name.GetCString());
+
+ if (attrs.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))
+ attrs.accessibility = default_accessibility;
+ }
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (attrs.name.GetStringRef().contains('<')) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ if (ParseTemplateParameterInfos(die, template_param_infos)) {
+ clang::ClassTemplateDecl *class_template_decl =
+ m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
+ attrs.name.GetCString(), tag_decl_kind,
+ template_param_infos);
+ if (!class_template_decl) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString());
+ }
+ return TypeSP();
+ }
+
+ clang::ClassTemplateSpecializationDecl *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+ }
+ }
+
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
+ clang_type = m_ast.CreateRecordType(
+ decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind,
+ attrs.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(m_ast.GetDeclContextForType(clang_type), die);
+ type_sp = std::make_shared<Type>(die.GetID(), dwarf, attrs.name,
+ attrs.byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &attrs.decl,
+ clang_type, Type::eResolveStateForward);
+
+ type_sp->SetIsCompleteObjCClass(attrs.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_up->m_type_sp = type_sp;
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0);
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_up);
+
+ if (attrs.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
+ DWARFDIE 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.Clear();
+ attrs.is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
+ }
+ }
+ }
+
+ if (!attrs.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()) {
+ // No children for this struct/union/class, lets finish it
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), attrs.name.GetCString());
+ }
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
+
+ if (record_decl) {
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::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 (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+
+ // 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::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ // Can't assume m_ast.GetSymbolFile() is actually a
+ // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
+ // binaries.
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
+ die.GetID();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
+
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl && record_decl->getDefinition()) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
+
+ if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl)
+ record_decl->setArgPassingRestrictions(
+ clang::RecordDecl::APK_CannotPassInRegs);
}
return type_sp;
}
@@ -2181,14 +2182,16 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
return false;
}
-std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
+void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) {
- std::vector<DWARFDIE> result;
- for (auto it = m_decl_ctx_to_die.find(
- (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
- it != m_decl_ctx_to_die.end(); it++)
- result.push_back(it->second);
- return result;
+ auto opaque_decl_ctx =
+ (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
+ for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
+ it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
+ it = m_decl_ctx_to_die.erase(it))
+ for (DWARFDIE decl = it->second.GetFirstChild(); decl;
+ decl = decl.GetSibling())
+ GetClangDeclForDIE(decl);
}
CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
@@ -2530,9 +2533,11 @@ bool DWARFASTParserClang::ParseChildMembers(
if (DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
nullptr, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ module_sp,
+ DataExtractor(debug_info_data, block_offset,
+ block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
member_byte_offset =
memberOffset.ResolveValue(nullptr).UInt();
}
@@ -2965,11 +2970,12 @@ bool DWARFASTParserClang::ParseChildMembers(
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(nullptr, nullptr, module_sp,
- debug_info_data, die.GetCU(),
- block_offset, block_length,
- eRegisterKindDWARF, &initialValue,
- nullptr, memberOffset, nullptr)) {
+ if (DWARFExpression::Evaluate(
+ nullptr, nullptr, module_sp,
+ DataExtractor(debug_info_data, block_offset,
+ block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
member_byte_offset =
memberOffset.ResolveValue(nullptr).UInt();
}
@@ -3270,6 +3276,8 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
array_info.element_orders.push_back(num_elements);
}
} break;
+ default:
+ break;
}
}
return array_info;
@@ -3672,11 +3680,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
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);
+ LLDB_LOGF(log,
+ "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;
@@ -3690,12 +3698,12 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
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(), src_die.GetTagAsCString(),
- dst_die.GetOffset(), dst_die.GetTagAsCString());
+ LLDB_LOGF(log,
+ "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(), src_die.GetTagAsCString(),
+ dst_die.GetOffset(), dst_die.GetTagAsCString());
fast_path = false;
}
@@ -3706,12 +3714,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
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);
+ LLDB_LOGF(log,
+ "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;
}
@@ -3733,32 +3740,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
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());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->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());
+ LLDB_LOGF(log,
+ "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 =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
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());
+ LLDB_LOGF(log,
+ "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());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = 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());
+ LLDB_LOGF(log,
+ "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 {
@@ -3778,39 +3784,36 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
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());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->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());
+ LLDB_LOGF(log,
+ "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 =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
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());
+ LLDB_LOGF(
+ log,
+ "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());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
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());
+ LLDB_LOGF(log,
+ "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());
+ LLDB_LOGF(log, "warning: couldn't find a match for 0x%8.8x",
+ dst_die.GetOffset());
failures.push_back(dst_die);
}
@@ -3836,32 +3839,31 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
clang::DeclContext *src_decl_ctx =
src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
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());
+ LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x",
+ static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
+ dst_die.GetOffset());
dst_dwarf_ast_parser->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());
+ LLDB_LOGF(log,
+ "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 =
dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
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());
+ LLDB_LOGF(
+ log,
+ "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());
dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = 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());
+ LLDB_LOGF(log,
+ "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());
}
}
}
@@ -3872,10 +3874,10 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
ConstString 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.GetCString());
+ LLDB_LOGF(log,
+ "warning: need to create artificial method for 0x%8.8x for "
+ "method '%s'",
+ dst_die.GetOffset(), dst_name_artificial.GetCString());
failures.push_back(dst_die);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 5b5d83d65932..106f9254a449 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -15,7 +15,10 @@
#include "llvm/ADT/SmallVector.h"
#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
#include "DWARFDefines.h"
+#include "DWARFFormValue.h"
+#include "LogChannelDWARF.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -29,6 +32,8 @@ class CompileUnit;
class DWARFDebugInfoEntry;
class SymbolFileDWARF;
+struct ParsedDWARFTypeAttributes;
+
class DWARFASTParserClang : public DWARFASTParser {
public:
DWARFASTParserClang(lldb_private::ClangASTContext &ast);
@@ -37,7 +42,7 @@ public:
// DWARFASTParser interface.
lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
+ const DWARFDIE &die,
bool *type_is_new_ptr) override;
lldb_private::Function *
@@ -51,8 +56,8 @@ public:
lldb_private::CompilerDecl
GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
- std::vector<DWARFDIE>
- GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) override;
+ void EnsureAllDIEsInDeclContextHaveBeenParsed(
+ lldb_private::CompilerDeclContext decl_context) override;
lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
@@ -63,9 +68,28 @@ public:
lldb_private::ClangASTImporter &GetClangASTImporter();
protected:
+ /// Protected typedefs and members.
+ /// @{
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ DIEToDeclContextMap;
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+ DIEToDeclMap;
+ typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
+
+ lldb_private::ClangASTContext &m_ast;
+ DIEToDeclMap m_die_to_decl;
+ DeclToDIEMap m_decl_to_die;
+ DIEToDeclContextMap m_die_to_decl_ctx;
+ DeclContextToDIEMap m_decl_ctx_to_die;
+ std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+ /// @}
+
clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
@@ -103,6 +127,10 @@ protected:
bool is_signed, uint32_t enumerator_byte_size,
const DWARFDIE &parent_die);
+ /// Parse a structure, class, or union type DIE.
+ lldb::TypeSP ParseStructureLikeDIE(const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
+
lldb_private::Type *GetTypeForDIE(const DWARFDIE &die);
clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
@@ -123,29 +151,52 @@ protected:
void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
+ /// If \p type_sp is valid, calculate and set its symbol context scope, and
+ /// update the type list for its backing symbol file.
+ ///
+ /// Returns \p type_sp.
+ lldb::TypeSP
+ UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die, lldb::TypeSP type_sp);
+
lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
// Return true if this type is a declaration to a type in an external
// module.
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
+};
- typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
- DIEToDeclContextMap;
- // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
- // DeclContextToDIEMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
- DeclContextToDIEMap;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
- DIEToDeclMap;
- typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
-
- lldb_private::ClangASTContext &m_ast;
- DIEToDeclMap m_die_to_decl;
- DeclToDIEMap m_decl_to_die;
- DIEToDeclContextMap m_die_to_decl_ctx;
- DeclContextToDIEMap m_decl_ctx_to_die;
- std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+/// Parsed form of all attributes that are relevant for type reconstruction.
+/// Some attributes are relevant for all kinds of types (declaration), while
+/// others are only meaningful to a specific type (is_virtual)
+struct ParsedDWARFTypeAttributes {
+ explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
+
+ lldb::AccessType accessibility = lldb::eAccessNone;
+ bool is_artificial = false;
+ bool is_complete_objc_class = false;
+ bool is_explicit = false;
+ bool is_forward_declaration = false;
+ bool is_inline = false;
+ bool is_scoped_enum = false;
+ bool is_vector = false;
+ bool is_virtual = false;
+ clang::StorageClass storage = clang::SC_None;
+ const char *mangled_name = nullptr;
+ lldb_private::ConstString name;
+ lldb_private::Declaration decl;
+ DWARFDIE object_pointer;
+ DWARFFormValue abstract_origin;
+ DWARFFormValue containing_type;
+ DWARFFormValue signature;
+ DWARFFormValue specification;
+ DWARFFormValue type;
+ lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
+ llvm::Optional<uint64_t> byte_size;
+ size_t calling_convention = llvm::dwarf::DW_CC_normal;
+ uint32_t bit_stride = 0;
+ uint32_t byte_stride = 0;
+ uint32_t encoding = 0;
};
#endif // SymbolFileDWARF_DWARFASTParserClang_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 6128163a2926..741669b05754 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -18,7 +18,8 @@
using namespace lldb_private;
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
- : m_code(InvalidCode), m_tag(0), m_has_children(0), m_attributes() {}
+ : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
+ m_attributes() {}
DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
uint8_t has_children)
@@ -33,7 +34,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
return DWARFEnumState::Complete;
m_attributes.clear();
- m_tag = data.GetULEB128(offset_ptr);
+ m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr));
if (m_tag == DW_TAG_null)
return llvm::make_error<llvm::object::GenericBinaryError>(
"abbrev decl requires non-null tag.");
@@ -68,7 +69,7 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
}
bool DWARFAbbreviationDeclaration::IsValid() {
- return m_code != 0 && m_tag != 0;
+ return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null;
}
uint32_t
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 96adb72c9532..033105efdc53 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/Log.h"
using namespace lldb_private;
@@ -29,7 +30,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
if (m_die)
return m_die->Tag();
else
- return 0;
+ return llvm::dwarf::DW_TAG_null;
}
const char *DWARFBaseDIE::GetTagAsCString() const {
@@ -102,19 +103,22 @@ SymbolFileDWARF *DWARFBaseDIE::GetDWARF() const {
return nullptr;
}
-lldb_private::TypeSystem *DWARFBaseDIE::GetTypeSystem() const {
- if (m_cu)
- return m_cu->GetTypeSystem();
- else
- return nullptr;
+llvm::Expected<lldb_private::TypeSystem &> DWARFBaseDIE::GetTypeSystem() const {
+ if (!m_cu)
+ return llvm::make_error<llvm::StringError>(
+ "Unable to get TypeSystem, no compilation unit available",
+ llvm::inconvertibleErrorCode());
+ return m_cu->GetTypeSystem();
}
DWARFASTParser *DWARFBaseDIE::GetDWARFParser() const {
- lldb_private::TypeSystem *type_system = GetTypeSystem();
- if (type_system)
- return type_system->GetDWARFParser();
- else
+ auto type_system_or_err = GetTypeSystem();
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DWARFASTParser");
return nullptr;
+ }
+ return type_system_or_err->GetDWARFParser();
}
bool DWARFBaseDIE::HasChildren() const {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 0058043017cd..9652d7946e87 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -12,6 +12,8 @@
#include "lldb/Core/dwarf.h"
#include "lldb/lldb-types.h"
+#include "llvm/Support/Error.h"
+
class DIERef;
class DWARFASTParser;
class DWARFAttributes;
@@ -55,7 +57,7 @@ public:
llvm::Optional<DIERef> GetDIERef() const;
- lldb_private::TypeSystem *GetTypeSystem() const;
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem() const;
DWARFASTParser *GetDWARFParser() const;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 9d97ca15a252..5ee0687995a1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -342,7 +342,8 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
}
}
-void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
+void DWARFDIE::GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const {
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return;
@@ -351,40 +352,33 @@ void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
parent.GetDeclContext(context);
switch (tag) {
case DW_TAG_module:
- context.push_back(
- CompilerContext(CompilerContextKind::Module, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Module, ConstString(GetName())});
break;
case DW_TAG_namespace:
- context.push_back(CompilerContext(CompilerContextKind::Namespace,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Namespace, ConstString(GetName())});
break;
case DW_TAG_structure_type:
- context.push_back(CompilerContext(CompilerContextKind::Structure,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Struct, ConstString(GetName())});
break;
case DW_TAG_union_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Union, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Union, ConstString(GetName())});
break;
case DW_TAG_class_type:
- context.push_back(
- CompilerContext(CompilerContextKind::Class, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Class, ConstString(GetName())});
break;
case DW_TAG_enumeration_type:
- context.push_back(CompilerContext(CompilerContextKind::Enumeration,
- ConstString(GetName())));
+ context.push_back({CompilerContextKind::Enum, ConstString(GetName())});
break;
case DW_TAG_subprogram:
- context.push_back(CompilerContext(CompilerContextKind::Function,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Function, ConstString(GetPubname())});
break;
case DW_TAG_variable:
- context.push_back(CompilerContext(CompilerContextKind::Variable,
- ConstString(GetPubname())));
+ context.push_back(
+ {CompilerContextKind::Variable, ConstString(GetPubname())});
break;
case DW_TAG_typedef:
- context.push_back(
- CompilerContext(CompilerContextKind::Typedef, ConstString(GetName())));
+ context.push_back({CompilerContextKind::Typedef, ConstString(GetName())});
break;
default:
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 7753ec9008cb..a779c589611a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -78,8 +78,8 @@ public:
/// Return this DIE's decl context as it is needed to look up types
/// in Clang's -gmodules debug info format.
- void
- GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const;
+ void GetDeclContext(
+ llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const;
// Getting attribute values from the DIE.
//
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index ccf33e6dc341..c8da2381353e 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -66,8 +66,8 @@ void DWARFDebugAranges::Dump(Log *log) const {
for (size_t i = 0; i < num_entries; ++i) {
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
if (entry)
- log->Printf("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
- entry->GetRangeBase(), entry->GetRangeEnd());
+ LLDB_LOGF(log, "0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data,
+ entry->GetRangeBase(), entry->GetRangeEnd());
}
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 100f35f8c6b0..1e04baca2c58 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -38,7 +38,7 @@ llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
if (m_cu_aranges_up)
return *m_cu_aranges_up;
- m_cu_aranges_up = llvm::make_unique<DWARFDebugAranges>();
+ m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
const DWARFDataExtractor &debug_aranges_data =
m_context.getOrLoadArangesData();
if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 2f55b7d40ed9..8c0fbeb4b717 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -192,7 +192,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
*offset_ptr = offset;
return true;
} else {
- m_tag = 0;
+ m_tag = llvm::dwarf::DW_TAG_null;
m_has_children = false;
return true; // NULL debug tag entry
}
@@ -340,18 +340,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- *frame_base = DWARFExpression(module, data, cu,
- block_offset, block_length);
+ *frame_base = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length), cu);
} else {
- const DWARFDataExtractor &debug_loc_data = dwarf.DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- cu, debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- *frame_base =
- DWARFExpression(module, debug_loc_data, cu,
- debug_loc_offset, loc_list_length);
+ DataExtractor data = dwarf.DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ *frame_base = DWARFExpression(module, data, cu);
if (lo_pc != LLDB_INVALID_ADDRESS) {
assert(lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc -
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 1e7b5f27642d..25c885608d85 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -31,7 +31,7 @@ public:
DWARFDebugInfoEntry()
: m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
- m_has_children(false), m_abbr_idx(0), m_tag(0) {}
+ m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -178,8 +178,9 @@ protected:
// a single NULL terminating child.
m_has_children : 1;
uint16_t m_abbr_idx;
- uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through
- // the compile unit abbrev table
+ /// A copy of the DW_TAG value so we don't have to go through the compile
+ /// unit abbrev table
+ dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
};
#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
deleted file mode 100644
index 953089fee22b..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-//===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFDebugLine.h"
-
-//#define ENABLE_DEBUG_PRINTF // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
-#include <assert.h>
-
-#include <memory>
-
-#include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Timer.h"
-
-#include "DWARFUnit.h"
-#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace std;
-
-// Parse
-//
-// Parse all information in the debug_line_data into an internal
-// representation.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
- m_lineTableMap.clear();
- lldb::offset_t offset = 0;
- LineTable::shared_ptr line_table_sp(new LineTable);
- while (debug_line_data.ValidOffset(offset)) {
- const lldb::offset_t debug_line_offset = offset;
-
- if (line_table_sp.get() == nullptr)
- break;
-
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
- // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
- // debug_line_offset);
- m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp = std::make_shared<LineTable>();
- } else
- ++offset; // Try next byte in line table
- }
-}
-
-void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
- if (m_lineTableMap.empty())
- Parse(debug_line_data);
-}
-
-// DWARFDebugLine::GetLineTable
-DWARFDebugLine::LineTable::shared_ptr
-DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
- DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
- LineTableConstIter pos = m_lineTableMap.find(offset);
- if (pos != m_lineTableMap.end())
- line_table_shared_ptr = pos->second;
- return line_table_shared_ptr;
-}
-
-// Parse
-//
-// Parse the entire line table contents calling callback each time a new
-// prologue is parsed and every time a new row is to be added to the line
-// table.
-void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback,
- void *userData) {
- lldb::offset_t offset = 0;
- if (debug_line_data.ValidOffset(offset)) {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
- ++offset; // Skip to next byte in .debug_line section
- }
-}
-
-namespace {
-struct EntryDescriptor {
- dw_sleb128_t code;
- dw_sleb128_t form;
-};
-
-static std::vector<EntryDescriptor>
-ReadDescriptors(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr) {
- std::vector<EntryDescriptor> ret;
- uint8_t n = debug_line_data.GetU8(offset_ptr);
- for (uint8_t i = 0; i < n; ++i) {
- EntryDescriptor ent;
- ent.code = debug_line_data.GetULEB128(offset_ptr);
- ent.form = debug_line_data.GetULEB128(offset_ptr);
- ret.push_back(ent);
- }
- return ret;
-}
-} // namespace
-
-// DWARFDebugLine::ParsePrologue
-bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr,
- Prologue *prologue, DWARFUnit *dwarf_cu) {
- const lldb::offset_t prologue_offset = *offset_ptr;
-
- // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
-
- prologue->Clear();
- uint32_t i;
- const char *s;
- prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
- prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 5)
- return false;
-
- if (prologue->version >= 5) {
- prologue->address_size = debug_line_data.GetU8(offset_ptr);
- prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
- }
-
- prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
- const lldb::offset_t end_prologue_offset =
- prologue->prologue_length + *offset_ptr;
- prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
- if (prologue->version >= 4)
- prologue->maximum_operations_per_instruction =
- debug_line_data.GetU8(offset_ptr);
- else
- prologue->maximum_operations_per_instruction = 1;
- prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
- prologue->line_base = debug_line_data.GetU8(offset_ptr);
- prologue->line_range = debug_line_data.GetU8(offset_ptr);
- prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
-
- prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
-
- for (i = 1; i < prologue->opcode_base; ++i) {
- uint8_t op_len = debug_line_data.GetU8(offset_ptr);
- prologue->standard_opcode_lengths.push_back(op_len);
- }
-
- if (prologue->version >= 5) {
- std::vector<EntryDescriptor> dirEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < dirCount; ++i) {
- for (EntryDescriptor &ent : dirEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (ent.code != DW_LNCT_path) {
- if (!value.SkipValue(debug_line_data, offset_ptr))
- return false;
- continue;
- }
-
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
- prologue->include_directories.push_back(value.AsCString());
- }
- }
-
- std::vector<EntryDescriptor> filesEntryFormatV =
- ReadDescriptors(debug_line_data, offset_ptr);
- llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
- uint8_t n = debug_line_data.GetULEB128(offset_ptr);
- for (int i = 0; i < n; ++i) {
- FileNameEntry entry;
- for (EntryDescriptor &ent : filesEntryFormatV) {
- DWARFFormValue value(dwarf_cu, ent.form);
- if (!value.ExtractValue(debug_line_data, offset_ptr))
- return false;
-
- switch (ent.code) {
- case DW_LNCT_path:
- entry.name = value.AsCString();
- break;
- case DW_LNCT_directory_index:
- entry.dir_idx = value.Unsigned();
- break;
- case DW_LNCT_timestamp:
- entry.mod_time = value.Unsigned();
- break;
- case DW_LNCT_size:
- entry.length = value.Unsigned();
- break;
- case DW_LNCT_MD5:
- assert(value.Unsigned() == 16);
- std::uninitialized_copy_n(value.BlockData(), 16,
- entry.checksum.Bytes.begin());
- break;
- default:
- break;
- }
- }
-
- if (seen.insert(entry.checksum.words()).second)
- prologue->file_names.push_back(entry);
- }
- } else {
- while (*offset_ptr < end_prologue_offset) {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
-
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.GetCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- prologue->file_names.push_back(fileEntry);
- } else
- break;
- }
- }
-
- // XXX GNU as is broken for 64-Bit DWARF
- if (*offset_ptr != end_prologue_offset) {
- Host::SystemLog(Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8" PRIx64
- " should have ended at 0x%8.8" PRIx64
- " but it ended at 0x%8.8" PRIx64 "\n",
- prologue_offset, end_prologue_offset, *offset_ptr);
- }
- return end_prologue_offset;
-}
-
-bool DWARFDebugLine::ParseSupportFiles(
- const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list, FileSpecList &support_files, DWARFUnit *dwarf_cu) {
- lldb::offset_t offset = stmt_list;
-
- Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
- Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
- "at 0x%8.8x (parsing ended around "
- "0x%8.8" PRIx64 "\n",
- stmt_list, offset);
- return false;
- }
-
- FileSpec file_spec;
- std::string remapped_file;
-
- for (uint32_t file_idx = 1;
- prologue.GetFile(file_idx, dwarf_cu->GetCompilationDirectory(),
- dwarf_cu->GetPathStyle(), file_spec);
- ++file_idx) {
- if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, FileSpec::Style::native);
- support_files.Append(file_spec);
- }
- return true;
-}
-
-// ParseStatementTable
-//
-// Parse a single line table (prologue and all rows) and call the callback
-// function once for the prologue (row in state will be zero) and each time a
-// row is to be added to the line table.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
- Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
- Prologue::shared_ptr prologue(new Prologue());
-
- const dw_offset_t debug_line_offset = *offset_ptr;
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
- debug_line_offset);
-
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
- if (log)
- log->Error("failed to parse DWARF line table prologue");
- // Restore our offset and return false to indicate failure!
- *offset_ptr = debug_line_offset;
- return false;
- }
-
- if (log)
- prologue->Dump(log);
-
- const dw_offset_t end_offset =
- debug_line_offset + prologue->total_length +
- (debug_line_data.GetDWARFSizeofInitialLength());
-
- State state(prologue, log, callback, userData);
-
- while (*offset_ptr < end_offset) {
- // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
- uint8_t opcode = debug_line_data.GetU8(offset_ptr);
-
- if (opcode == 0) {
- // Extended Opcodes always start with a zero opcode followed by a uleb128
- // length so you can skip ones you don't know about
- lldb::offset_t ext_offset = *offset_ptr;
- dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
- dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
-
- // DEBUG_PRINTF("Extended: <%2u> ", len);
- uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
- switch (sub_opcode) {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the state-
- // machine registers. Then reset the registers to the initial values
- // specified above. Every statement program sequence must end with a
- // DW_LNE_end_sequence instruction which creates a row whose address is
- // that of the byte after the last target machine instruction of the
- // sequence.
- state.end_sequence = true;
- state.AppendRowToMatrix(*offset_ptr);
- state.Reset();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes that
- // affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- if (arg_size == 4)
- state.address = debug_line_data.GetU32(offset_ptr);
- else // arg_size == 8
- state.address = debug_line_data.GetU64(offset_ptr);
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number
- // representing the directory index of the directory in which the file
- // was found. The third is an unsigned LEB128 number representing the
- // time of last modification of the file. The fourth is an unsigned
- // LEB128 number representing the length in bytes of the file. The time
- // and length fields may contain LEB128(0) if the information is not
- // available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0) if
- // the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by the
- // DW_LNE_define_file instruction. These numbers are used in the file
- // register of the state machine.
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(offset_ptr);
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- state.prologue->file_names.push_back(fileEntry);
- }
- break;
-
- default:
- // Length doesn't include the zero opcode byte or the length itself,
- // but it does include the sub_opcode, so we have to adjust for that
- // below
- (*offset_ptr) += arg_size;
- break;
- }
- } else if (opcode < prologue->opcode_base) {
- switch (opcode) {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the current
- // values of the state-machine registers. Then set the basic_block
- // register to false.
- state.AppendRowToMatrix(*offset_ptr);
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the result to the
- // address register of the state machine.
- state.address +=
- debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to the line
- // register of the state machine.
- state.line += debug_line_data.GetSLEB128(offset_ptr);
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- state.file = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.column = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state machine to
- // the logical negation of its current value.
- state.is_stmt = !state.is_stmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.basic_block = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state machine
- // the address increment value corresponding to special opcode 255. The
- // motivation for DW_LNS_const_add_pc is this: when the statement
- // program needs to advance the address by a small amount, it can use a
- // single special opcode, which occupies a single byte. When it needs
- // to advance the address by up to twice the range of the last special
- // opcode, it can use DW_LNS_const_add_pc followed by a special opcode,
- // for a total of two bytes. Only if it needs to advance the address by
- // more than twice that range will it need to use both
- // DW_LNS_advance_pc and a special opcode, requiring three or more
- // bytes.
- {
- uint8_t adjust_opcode = 255 - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
- prologue->min_inst_length;
- state.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of the
- // state machine the value of the (unencoded) operand. This is the only
- // extended opcode that takes an argument that is not a variable length
- // number. The motivation for DW_LNS_fixed_advance_pc is this: existing
- // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
- // they cannot encode LEB128 numbers or judge when the computation of a
- // special opcode overflows and requires the use of DW_LNS_advance_pc.
- // Such assemblers, however, can use DW_LNS_fixed_advance_pc instead,
- // sacrificing compression.
- state.address += debug_line_data.GetU16(offset_ptr);
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the state
- // machine to true
- state.prologue_end = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the state
- // machine to true
- state.epilogue_begin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the column
- // register of the state machine.
- state.isa = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths of
- // such opcodes because they are specified in the prologue as a
- // multiple of LEB128 operands for each opcode.
- {
- uint8_t i;
- assert(static_cast<size_t>(opcode - 1) <
- prologue->standard_opcode_lengths.size());
- const uint8_t opcode_length =
- prologue->standard_opcode_lengths[opcode - 1];
- for (i = 0; i < opcode_length; ++i)
- debug_line_data.Skip_LEB128(offset_ptr);
- }
- break;
- }
- } else {
- // Special Opcodes
-
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base field in
- // the header, plus the value of the line_range field, minus 1 (line base
- // + line range - 1). If the desired line increment is greater than the
- // maximum line increment, a standard opcode must be used instead of a
- // special opcode. The "address advance" is calculated by dividing the
- // desired address increment by the minimum_instruction_length field from
- // the header. The special opcode is then calculated using the following
- // formula:
- //
- // opcode = (desired line increment - line_base) + (line_range * address
- // advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode must be
- // used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the opcode
- // itself to give the adjusted opcode. The amount to increment the
- // address register is the result of the adjusted opcode divided by the
- // line_range multiplied by the minimum_instruction_length field from the
- // header. That is:
- //
- // address increment = (adjusted opcode / line_range) *
- // minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus the
- // result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t adjust_opcode = opcode - prologue->opcode_base;
- dw_addr_t addr_offset =
- (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- int32_t line_offset =
- prologue->line_base + (adjust_opcode % prologue->line_range);
- state.line += line_offset;
- state.address += addr_offset;
- state.AppendRowToMatrix(*offset_ptr);
- }
- }
-
- state.Finalize(*offset_ptr);
-
- return end_offset;
-}
-
-// ParseStatementTableCallback
-static void ParseStatementTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table, so lets keep a reference to the
- // prologue using the supplied shared pointer
- line_table->prologue = state.prologue;
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- // We have a new row, lets append it
- line_table->AppendRow(state);
- }
-}
-
-// ParseStatementTable
-//
-// Parse a line table at offset and populate the LineTable class with the
-// prologue and all rows.
-bool DWARFDebugLine::ParseStatementTable(
- const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- LineTable *line_table, DWARFUnit *dwarf_cu) {
- return ParseStatementTable(debug_line_data, offset_ptr,
- ParseStatementTableCallback, line_table, dwarf_cu);
-}
-
-inline bool DWARFDebugLine::Prologue::IsValid() const {
- return SymbolFileDWARF::SupportedVersion(version);
-}
-
-// DWARFDebugLine::Prologue::Dump
-void DWARFDebugLine::Prologue::Dump(Log *log) {
- uint32_t i;
-
- log->Printf("Line table prologue:");
- log->Printf(" total_length: 0x%8.8x", total_length);
- log->Printf(" version: %u", version);
- log->Printf("prologue_length: 0x%8.8x", prologue_length);
- log->Printf("min_inst_length: %u", min_inst_length);
- log->Printf("default_is_stmt: %u", default_is_stmt);
- log->Printf(" line_base: %i", line_base);
- log->Printf(" line_range: %u", line_range);
- log->Printf(" opcode_base: %u", opcode_base);
-
- for (i = 0; i < standard_opcode_lengths.size(); ++i) {
- log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
- standard_opcode_lengths[i]);
- }
-
- if (!include_directories.empty()) {
- for (i = 0; i < include_directories.size(); ++i) {
- log->Printf("include_directories[%3u] = '%s'", i + 1,
- include_directories[i]);
- }
- }
-
- if (!file_names.empty()) {
- log->PutCString(" Dir Mod Time File Len File Name");
- log->PutCString(" ---- ---------- ---------- "
- "---------------------------");
- for (i = 0; i < file_names.size(); ++i) {
- const FileNameEntry &fileEntry = file_names[i];
- log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
- fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
- fileEntry.name);
- }
- }
-}
-
-// DWARFDebugLine::ParsePrologue::Append
-//
-// Append the contents of the prologue to the binary stream buffer
-// void
-// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
-//{
-// uint32_t i;
-//
-// buff.Append32(total_length);
-// buff.Append16(version);
-// buff.Append32(prologue_length);
-// buff.Append8(min_inst_length);
-// buff.Append8(default_is_stmt);
-// buff.Append8(line_base);
-// buff.Append8(line_range);
-// buff.Append8(opcode_base);
-//
-// for (i=0; i<standard_opcode_lengths.size(); ++i)
-// buff.Append8(standard_opcode_lengths[i]);
-//
-// for (i=0; i<include_directories.size(); ++i)
-// buff.AppendCStr(include_directories[i].c_str());
-// buff.Append8(0); // Terminate the include directory section with empty
-// string
-//
-// for (i=0; i<file_names.size(); ++i)
-// {
-// buff.AppendCStr(file_names[i].name.c_str());
-// buff.Append32_as_ULEB128(file_names[i].dir_idx);
-// buff.Append32_as_ULEB128(file_names[i].mod_time);
-// buff.Append32_as_ULEB128(file_names[i].length);
-// }
-// buff.Append8(0); // Terminate the file names section with empty string
-//}
-
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
- const FileSpec &comp_dir,
- FileSpec::Style style,
- FileSpec &file) const {
- uint32_t idx = file_idx - 1; // File indexes are 1 based...
- if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, style);
- if (file.IsRelative()) {
- if (file_names[idx].dir_idx > 0) {
- const uint32_t dir_idx = file_names[idx].dir_idx - 1;
- if (dir_idx < include_directories.size()) {
- file.PrependPathComponent(include_directories[dir_idx]);
- if (!file.IsRelative())
- return true;
- }
- }
-
- if (comp_dir)
- file.PrependPathComponent(comp_dir);
- }
- return true;
- }
- return false;
-}
-
-void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
- rows.push_back(state);
-}
-
-// Compare function for the binary search in
-// DWARFDebugLine::LineTable::LookupAddress()
-static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
- const DWARFDebugLine::Row &row2) {
- return row1.address < row2.address;
-}
-
-// DWARFDebugLine::LineTable::LookupAddress
-uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
- dw_addr_t cu_high_pc) const {
- uint32_t index = UINT32_MAX;
- if (!rows.empty()) {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.address = address;
- Row::const_iterator begin_pos = rows.begin();
- Row::const_iterator end_pos = rows.end();
- Row::const_iterator pos =
- lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
- if (pos == end_pos) {
- if (address < cu_high_pc)
- return rows.size() - 1;
- } else {
- // Rely on fact that we are using a std::vector and we can do pointer
- // arithmetic to find the row index (which will be one less that what we
- // found since it will find the first position after the current address)
- // since std::vector iterators are just pointers to the container type.
- index = pos - begin_pos;
- if (pos->address > address) {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
- }
- return index; // Failed to find address
-}
-
-// DWARFDebugLine::Row::Row
-DWARFDebugLine::Row::Row(bool default_is_stmt)
- : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
- basic_block(false), end_sequence(false), prologue_end(false),
- epilogue_begin(false), isa(0) {}
-
-// Called after a row is appended to the matrix
-void DWARFDebugLine::Row::PostAppend() {
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
-}
-
-// DWARFDebugLine::Row::Reset
-void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
- address = 0;
- line = 1;
- column = 0;
- file = 1;
- is_stmt = default_is_stmt;
- basic_block = false;
- end_sequence = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
-}
-// DWARFDebugLine::Row::Dump
-void DWARFDebugLine::Row::Dump(Log *log) const {
- log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
- column, file, isa, is_stmt ? " is_stmt" : "",
- basic_block ? " basic_block" : "",
- prologue_end ? " prologue_end" : "",
- epilogue_begin ? " epilogue_begin" : "",
- end_sequence ? " end_sequence" : "");
-}
-
-// Compare function LineTable structures
-static bool AddressLessThan(const DWARFDebugLine::Row &a,
- const DWARFDebugLine::Row &b) {
- return a.address < b.address;
-}
-
-// Insert a row at the correct address if the addresses can be out of order
-// which can only happen when we are linking a line table that may have had
-// it's contents rearranged.
-void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
- const Row &state) {
- // If we don't have anything yet, or if the address of the last state in our
- // line table is less than the current one, just append the current state
- if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
- state_coll.push_back(state);
- } else {
- // Do a binary search for the correct entry
- pair<Row::iterator, Row::iterator> range(equal_range(
- state_coll.begin(), state_coll.end(), state, AddressLessThan));
-
- // If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence
- // entry. We currently always place an extra end sequence when ever we exit
- // a valid address range for a function in case the functions get
- // rearranged by optimizations or by order specifications. These extra end
- // sequences will disappear by getting replaced with valid consecutive
- // entries within a compile unit if there are no gaps.
- if (range.first == range.second) {
- state_coll.insert(range.first, state);
- } else {
- if ((distance(range.first, range.second) == 1) &&
- range.first->end_sequence == true) {
- *range.first = state;
- } else {
- state_coll.insert(range.second, state);
- }
- }
- }
-}
-
-// DWARFDebugLine::State::State
-DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
- DWARFDebugLine::State::Callback cb, void *userData)
- : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
- callbackUserData(userData), row(StartParsingLineTable) {
- // Call the callback with the initial row state of zero for the prologue
- if (callback)
- callback(0, *this, callbackUserData);
-}
-
-// DWARFDebugLine::State::Reset
-void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
-
-// DWARFDebugLine::State::AppendRowToMatrix
-void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
- // Each time we are to add an entry into the line table matrix call the
- // callback function so that someone can do something with the current state
- // of the state machine (like build a line table or dump the line table!)
- if (log) {
- if (row == 0) {
- log->PutCString("Address Line Column File ISA Flags");
- log->PutCString(
- "------------------ ------ ------ ------ --- -------------");
- }
- Dump(log);
- }
-
- ++row; // Increase the row number before we call our callback for a real row
- if (callback)
- callback(offset, *this, callbackUserData);
- PostAppend();
-}
-
-// DWARFDebugLine::State::Finalize
-void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
- // Call the callback with a special row state when we are done parsing a line
- // table
- row = DoneParsingLineTable;
- if (callback)
- callback(offset, *this, callbackUserData);
-}
-
-// void
-// DWARFDebugLine::AppendLineTableData
-//(
-// const DWARFDebugLine::Prologue* prologue,
-// const DWARFDebugLine::Row::collection& state_coll,
-// const uint32_t addr_size,
-// BinaryStreamBuf &debug_line_data
-//)
-//{
-// if (state_coll.empty())
-// {
-// // We have no entries, just make an empty line table
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-// }
-// else
-// {
-// DWARFDebugLine::Row::const_iterator pos;
-// Row::const_iterator end = state_coll.end();
-// bool default_is_stmt = prologue->default_is_stmt;
-// const DWARFDebugLine::Row reset_state(default_is_stmt);
-// const DWARFDebugLine::Row* prev_state = &reset_state;
-// const int32_t max_line_increment_for_special_opcode =
-// prologue->MaxLineIncrementForSpecialOpcode();
-// for (pos = state_coll.begin(); pos != end; ++pos)
-// {
-// const DWARFDebugLine::Row& curr_state = *pos;
-// int32_t line_increment = 0;
-// dw_addr_t addr_offset = curr_state.address - prev_state->address;
-// dw_addr_t addr_advance = (addr_offset) / prologue->min_inst_length;
-// line_increment = (int32_t)(curr_state.line - prev_state->line);
-//
-// // If our previous state was the reset state, then let's emit the
-// // address to keep GDB's DWARF parser happy. If we don't start each
-// // sequence with a DW_LNE_set_address opcode, the line table won't
-// // get slid properly in GDB.
-//
-// if (prev_state == &reset_state)
-// {
-// debug_line_data.Append8(0); // Extended opcode
-// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
-// opcode bytes
-// debug_line_data.Append8(DW_LNE_set_address);
-// debug_line_data.AppendMax64(curr_state.address, addr_size);
-// addr_advance = 0;
-// }
-//
-// if (prev_state->file != curr_state.file)
-// {
-// debug_line_data.Append8(DW_LNS_set_file);
-// debug_line_data.Append32_as_ULEB128(curr_state.file);
-// }
-//
-// if (prev_state->column != curr_state.column)
-// {
-// debug_line_data.Append8(DW_LNS_set_column);
-// debug_line_data.Append32_as_ULEB128(curr_state.column);
-// }
-//
-// // Don't do anything fancy if we are at the end of a sequence
-// // as we don't want to push any extra rows since the
-// DW_LNE_end_sequence
-// // will push a row itself!
-// if (curr_state.end_sequence)
-// {
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push the end sequence on!
-// debug_line_data.Append8(0);
-// debug_line_data.Append8(1);
-// debug_line_data.Append8(DW_LNE_end_sequence);
-//
-// prev_state = &reset_state;
-// }
-// else
-// {
-// if (line_increment || addr_advance)
-// {
-// if (line_increment > max_line_increment_for_special_opcode)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// line_increment = 0;
-// }
-//
-// uint32_t special_opcode = (line_increment >=
-// prologue->line_base) ? ((line_increment -
-// prologue->line_base) + (prologue->line_range * addr_advance)
-// + prologue->opcode_base) : 256;
-// if (special_opcode > 255)
-// {
-// // Both the address and line won't fit in one special
-// opcode
-// // check to see if just the line advance will?
-// uint32_t special_opcode_line = ((line_increment >=
-// prologue->line_base) && (line_increment != 0)) ?
-// ((line_increment - prologue->line_base) +
-// prologue->opcode_base) : 256;
-//
-//
-// if (special_opcode_line > 255)
-// {
-// // Nope, the line advance won't fit by itself, check
-// the address increment by itself
-// uint32_t special_opcode_addr = addr_advance ?
-// ((0 - prologue->line_base) +
-// (prologue->line_range * addr_advance) +
-// prologue->opcode_base) : 256;
-//
-// if (special_opcode_addr > 255)
-// {
-// // Neither the address nor the line will fit in
-// a
-// // special opcode, we must manually enter both
-// then
-// // do a DW_LNS_copy to push a row (special
-// opcode
-// // automatically imply a new row is pushed)
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Now push a row onto the line table manually
-// debug_line_data.Append8(DW_LNS_copy);
-//
-// }
-// else
-// {
-// // The address increment alone will fit into a
-// special opcode
-// // so modify our line change, then issue a
-// special opcode
-// // for the address increment and it will push a
-// row into the
-// // line table
-// if (line_increment != 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_line);
-// debug_line_data.Append32_as_SLEB128(line_increment);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line
-// table
-// debug_line_data.Append8(special_opcode_addr);
-// }
-// }
-// else
-// {
-// // The line change alone will fit into a special
-// opcode
-// // so modify our address increment first, then issue
-// a
-// // special opcode for the line change and it will
-// push
-// // a row into the line table
-// if (addr_advance > 0)
-// {
-// debug_line_data.Append8(DW_LNS_advance_pc);
-// debug_line_data.Append32_as_ULEB128(addr_advance);
-// }
-//
-// // Advance of line and address will fit into a
-// single byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode_line);
-// }
-// }
-// else
-// {
-// // Advance of line and address will fit into a single
-// byte special opcode
-// // and this will also push a row onto the line table
-// debug_line_data.Append8(special_opcode);
-// }
-// }
-// prev_state = &curr_state;
-// }
-// }
-// }
-//}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
deleted file mode 100644
index 0d236ca686b5..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-private.h"
-
-#include "DWARFDataExtractor.h"
-#include "DWARFDefines.h"
-
-#include "llvm/Support/MD5.h"
-
-class DWARFUnit;
-class SymbolFileDWARF;
-
-// DWARFDebugLine
-class DWARFDebugLine {
-public:
- // FileNameEntry
- struct FileNameEntry {
- FileNameEntry()
- : name(nullptr), dir_idx(0), mod_time(0), length(0), checksum() {}
-
- const char *name;
- dw_sleb128_t dir_idx;
- dw_sleb128_t mod_time;
- dw_sleb128_t length;
- llvm::MD5::MD5Result checksum;
- };
-
- // Prologue
- struct Prologue {
-
- Prologue()
- : total_length(0), version(0), prologue_length(0), min_inst_length(0),
- default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
- standard_opcode_lengths(), include_directories(), file_names() {}
-
- typedef std::shared_ptr<Prologue> shared_ptr;
-
- uint32_t total_length; // The size in bytes of the statement information for
- // this compilation unit (not including the
- // total_length field itself).
- uint16_t
- version; // Version identifier for the statement information format.
-
- uint8_t address_size;
- uint8_t segment_selector_size;
-
- uint32_t prologue_length; // The number of bytes following the
- // prologue_length field to the beginning of the
- // first byte of the statement program itself.
- uint8_t min_inst_length; // The size in bytes of the smallest target machine
- // instruction. Statement program opcodes that
- // alter the address register first multiply their
- // operands by this value.
- uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum
- // number of individual
- // operations that may be
- // encoded in an instruction.
- uint8_t default_is_stmt; // The initial value of theis_stmtregister.
- int8_t line_base; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t line_range; // This parameter affects the meaning of the special
- // opcodes. See below.
- uint8_t opcode_base; // The number assigned to the first special opcode.
- std::vector<uint8_t> standard_opcode_lengths;
- std::vector<const char *> include_directories;
- std::vector<FileNameEntry> file_names;
-
- int32_t MaxLineIncrementForSpecialOpcode() const {
- return line_base + (int8_t)line_range - 1;
- }
- bool IsValid() const;
- // void Append(BinaryStreamBuf& buff) const;
- void Dump(lldb_private::Log *log);
- void Clear() {
- total_length = version = prologue_length = min_inst_length = line_base =
- line_range = opcode_base = 0;
- line_base = 0;
- standard_opcode_lengths.clear();
- include_directories.clear();
- file_names.clear();
- }
- bool GetFile(uint32_t file_idx, const lldb_private::FileSpec &cu_comp_dir,
- lldb_private::FileSpec::Style style,
- lldb_private::FileSpec &file) const;
- };
-
- // Standard .debug_line state machine structure
- struct Row {
- typedef std::vector<Row> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- Row(bool default_is_stmt = false);
- virtual ~Row() {}
- void PostAppend();
- void Reset(bool default_is_stmt);
- void Dump(lldb_private::Log *log) const;
- static void Insert(Row::collection &state_coll, const Row &state);
-
- dw_addr_t address; // The program-counter value corresponding to a machine
- // instruction generated by the compiler.
- uint32_t line; // An unsigned integer indicating a source line number. Lines
- // are numbered beginning at 1. The compiler may emit the
- // value 0 in cases where an instruction cannot be attributed
- // to any source line.
- uint16_t column; // An unsigned integer indicating a column number within a
- // source line. Columns are numbered beginning at 1. The
- // value 0 is reserved to indicate that a statement begins
- // at the 'left edge' of the line.
- uint16_t file; // An unsigned integer indicating the identity of the source
- // file corresponding to a machine instruction.
- uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
- // the beginning of a statement.
- basic_block : 1, // A boolean indicating that the current instruction is
- // the beginning of a basic block.
- end_sequence : 1, // A boolean indicating that the current address is
- // that of the first byte after the end of a sequence
- // of target machine instructions.
- prologue_end : 1, // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an entry breakpoint of a function.
- epilogue_begin : 1; // A boolean indicating that the current address is
- // one (of possibly many) where execution should be
- // suspended for an exit breakpoint of a function.
- uint32_t isa; // An unsigned integer whose value encodes the applicable
- // instruction set architecture for the current instruction.
- };
-
- // LineTable
- struct LineTable {
- typedef std::shared_ptr<LineTable> shared_ptr;
-
- LineTable() : prologue(), rows() {}
-
- void AppendRow(const DWARFDebugLine::Row &state);
- void Clear() {
- prologue.reset();
- rows.clear();
- }
-
- uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
-
- Prologue::shared_ptr prologue;
- Row::collection rows;
- };
-
- // State
- struct State : public Row {
- typedef void (*Callback)(dw_offset_t offset, const State &state,
- void *userData);
-
- // Special row codes used when calling the callback
- enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
-
- State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
- Callback callback, void *userData);
-
- void AppendRowToMatrix(dw_offset_t offset);
-
- void Finalize(dw_offset_t offset);
-
- void Reset();
-
- Prologue::shared_ptr prologue;
- lldb_private::Log *log;
- Callback callback; // Callback function that gets called each time an entry
- // is to be added to the matrix
- void *callbackUserData;
- int row; // The row number that starts at zero for the prologue, and
- // increases for each row added to the matrix
- private:
- DISALLOW_COPY_AND_ASSIGN(State);
- };
-
- static bool
- ParseSupportFiles(const lldb::ModuleSP &module_sp,
- const lldb_private::DWARFDataExtractor &debug_line_data,
- dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files,
- DWARFUnit *dwarf_cu);
- static bool
- ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, Prologue *prologue,
- DWARFUnit *dwarf_cu = nullptr);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, State::Callback callback,
- void *userData, DWARFUnit *dwarf_cu);
- static bool
- ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, LineTable *line_table,
- DWARFUnit *dwarf_cu);
- static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
- DWARFDebugLine::State::Callback callback, void *userData);
- // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
- // const DWARFDebugLine::Row::collection& state_coll, const uint32_t
- // addr_size, BinaryStreamBuf &debug_line_data);
-
- DWARFDebugLine() : m_lineTableMap() {}
-
- void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
- void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
- LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
-
-protected:
- typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
- typedef LineTableMap::iterator LineTableIter;
- typedef LineTableMap::const_iterator LineTableConstIter;
-
- LineTableMap m_lineTableMap;
-};
-
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 207c71211c9a..0b08fa09f906 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -123,11 +123,6 @@ bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
return false;
}
-uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
- lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
- return 0;
-}
-
bool DWARFDebugRngLists::ExtractRangeList(
const DWARFDataExtractor &data, uint8_t addrSize,
lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index baf2667f0afe..c398259056b3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -24,7 +24,6 @@ public:
virtual void Extract(lldb_private::DWARFContext &context) = 0;
virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const = 0;
- virtual uint64_t GetOffset(size_t Index) const = 0;
};
class DWARFDebugRanges final : public DWARFDebugRangesBase {
@@ -34,7 +33,6 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
static void Dump(lldb_private::Stream &s,
const lldb_private::DWARFDataExtractor &debug_ranges_data,
@@ -62,7 +60,7 @@ public:
void Extract(lldb_private::DWARFContext &context) override;
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const override;
+ uint64_t GetOffset(size_t Index) const;
protected:
bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index d0d70dd5123e..6501ac27f27d 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -23,7 +23,7 @@
class DWARFDeclContext {
public:
struct Entry {
- Entry() : tag(0), name(nullptr) {}
+ Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {}
Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
bool NameMatches(const Entry &rhs) const {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 3bf0bb088227..2ae1bbc9f507 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -59,6 +59,8 @@ const char *DW_OP_value_to_name(uint32_t val) {
}
DRC_class DW_OP_value_to_class(uint32_t val) {
+ // FIXME: If we just used llvm's DWARFExpression printer, we could delete
+ // all this code (and more in lldb's DWARFExpression.cpp).
switch (val) {
case 0x03:
return DRC_ONEOPERAND;
@@ -358,6 +360,8 @@ DRC_class DW_OP_value_to_class(uint32_t val) {
return DRC_DWARFv3 | DRC_ONEOPERAND;
case 0x9a:
return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0xa3: /* DW_OP_entry_value */
+ return DRC_TWOOPERANDS;
case 0xf0:
return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
case 0xe0:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 33e83d1fe57f..9964cf4b893c 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -438,7 +438,7 @@ lldb::ByteOrder DWARFUnit::GetByteOrder() const {
return m_dwarf.GetObjectFile()->GetByteOrder();
}
-TypeSystem *DWARFUnit::GetTypeSystem() {
+llvm::Expected<TypeSystem &> DWARFUnit::GetTypeSystem() {
return m_dwarf.GetTypeSystemForLanguage(GetLanguageType());
}
@@ -540,19 +540,15 @@ void DWARFUnit::ParseProducerInfo() {
} else if (strstr(producer_cstr, "clang")) {
static RegularExpression g_clang_version_regex(
llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"));
- RegularExpression::Match regex_match(3);
+ llvm::SmallVector<llvm::StringRef, 4> matches;
if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr),
- &regex_match)) {
- std::string str;
- if (regex_match.GetMatchAtIndex(producer_cstr, 1, str))
- m_producer_version_major =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 2, str))
- m_producer_version_minor =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
- if (regex_match.GetMatchAtIndex(producer_cstr, 3, str))
- m_producer_version_update =
- StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
+ &matches)) {
+ m_producer_version_major =
+ StringConvert::ToUInt32(matches[1].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_minor =
+ StringConvert::ToUInt32(matches[2].str().c_str(), UINT32_MAX, 10);
+ m_producer_version_update =
+ StringConvert::ToUInt32(matches[3].str().c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
} else if (strstr(producer_cstr, "GNU"))
@@ -870,7 +866,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
llvm::Expected<DWARFRangeList>
DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
- const DWARFDebugRangesBase *debug_rnglists = m_dwarf.GetDebugRngLists();
+ const DWARFDebugRngLists *debug_rnglists = m_dwarf.GetDebugRngLists();
if (!debug_rnglists)
return llvm::make_error<llvm::object::GenericBinaryError>(
"No debug_rnglists section");
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 8aa1e449f3ed..87e0de283de4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -153,7 +153,7 @@ public:
lldb::ByteOrder GetByteOrder() const;
- lldb_private::TypeSystem *GetTypeSystem();
+ llvm::Expected<lldb_private::TypeSystem &> GetTypeSystem();
const DWARFDebugAranges &GetFunctionAranges();
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 9746ad76c930..007ef2e05e59 100644
--- a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -24,7 +24,7 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
return llvm::make_error<llvm::StringError>("debug info null",
llvm::inconvertibleErrorCode());
}
- auto index_up = llvm::make_unique<DebugNames>(debug_names.GetAsLLVM(),
+ auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(),
debug_str.GetAsLLVM());
if (llvm::Error E = index_up->extract())
return std::move(E);
@@ -105,7 +105,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -125,7 +125,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
uint64_t cu_offset = cu.GetOffset();
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
for (DebugNames::NameTableEntry nte: ni) {
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
if (entry_or->tag() != DW_TAG_variable)
@@ -248,7 +248,7 @@ void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
if (!regex.Execute(nte.getString()))
continue;
- uint32_t entry_offset = nte.getEntryOffset();
+ uint64_t entry_offset = nte.getEntryOffset();
llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
Tag tag = entry_or->tag();
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 62b0ad37a9fc..88a29f4a2672 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -125,7 +125,7 @@ DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
: die_base_offset(_die_base_offset), atoms(), atom_mask(0),
min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
// Define an array of DIE offsets by first defining an array, and then define
- // the atom type for the array, in this case we have an array of DIE offsets
+ // the atom type for the array, in this case we have an array of DIE offsets.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
}
@@ -208,9 +208,10 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
const uint32_t atom_count = data.GetU32(&offset);
if (atom_count == 0x00060003u) {
- // Old format, deal with contents of old pre-release format
- while (data.GetU32(&offset))
+ // Old format, deal with contents of old pre-release format.
+ while (data.GetU32(&offset)) {
/* do nothing */;
+ }
// Hardcode to the only known value for now.
AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
@@ -226,7 +227,7 @@ DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
size_t DWARFMappedHash::Prologue::GetByteSize() const {
// Add an extra count to the atoms size for the zero termination Atom that
- // gets written to disk
+ // gets written to disk.
return sizeof(die_base_offset) + sizeof(uint32_t) +
atoms.size() * sizeof(Atom);
}
@@ -286,7 +287,7 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
break;
default:
- // We can always skip atoms we don't know about
+ // We can always skip atoms we don't know about.
break;
}
}
@@ -308,8 +309,8 @@ DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
HashData &hash_data) const {
lldb::offset_t offset = hash_data_offset;
- offset += 4; // Skip string table offset that contains offset of hash name in
- // .debug_str
+ // Skip string table offset that contains offset of hash name in .debug_str.
+ offset += 4;
const uint32_t count = m_data.GetU32(&offset);
if (count > 0) {
hash_data.resize(count);
@@ -335,7 +336,7 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr) {
*hash_data_offset_ptr = UINT32_MAX;
@@ -345,9 +346,8 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
// We have at least one HashData entry, and we have enough data to parse at
// least "count" HashData entries.
@@ -370,21 +370,22 @@ DWARFMappedHash::MemoryTable::GetHashDataForName(
if (match)
pair.value.push_back(die_info);
} else {
- // Something went wrong while reading the data
+ // Something went wrong while reading the data.
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
}
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -402,7 +403,7 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
return eResultEndOfHashData;
// There definitely should be a string for this string offset, if there
- // isn't, there is something wrong, return and error
+ // isn't, there is something wrong, return and error.
const char *strp_cstr = m_string_table.PeekCStr(pair.key);
if (strp_cstr == nullptr)
return eResultError;
@@ -410,9 +411,8 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
const size_t min_total_hash_data_size =
count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 &&
- m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
- min_total_hash_data_size)) {
+ if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
const bool match = regex.Execute(llvm::StringRef(strp_cstr));
if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
@@ -438,14 +438,15 @@ DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
}
}
// Return the correct response depending on if the string matched or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup
- // results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will
- // get called
- // again for the next key/value or the key terminator which in our case is
- // a zero .debug_str offset.
+ if (match) {
+ // The key (cstring) matches and we have lookup results!
+ return eResultKeyMatch;
+ } else {
+ // The key doesn't match, this function will get called again for the
+ // next key/value or the key terminator which in our case is a zero
+ // .debug_str offset.
+ return eResultKeyMismatch;
+ }
} else {
*hash_data_offset_ptr = UINT32_MAX;
return eResultError;
@@ -466,7 +467,7 @@ size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
if (prev_hash_data_offset == hash_data_offset)
break;
- // Check the result of getting our hash data
+ // Check the result of getting our hash data.
switch (hash_result) {
case eResultKeyMatch:
case eResultKeyMismatch:
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index a01612b59528..56d9bc548877 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -24,37 +24,41 @@ class DWARFMappedHash {
public:
enum AtomType : uint16_t {
eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that
- // contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1
- // (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
- eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name
- // (since all hash entries are basename only)
- // For example a type like "std::vector<int>::iterator" would have a name of
- // "iterator"
- // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not
- // have to pull
- // in debug info for a type when we know the fully qualified name.
+ /// DIE offset, check form for encoding.
+ eAtomTypeDIEOffset = 1u,
+ /// DIE offset of the compiler unit header that contains the item in
+ /// question.
+ eAtomTypeCUOffset = 2u,
+ /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed
+ /// 255) or DW_FORM_data2.
+ eAtomTypeTag = 3u,
+ // Flags from enum NameFlags.
+ eAtomTypeNameFlags = 4u,
+ // Flags from enum TypeFlags.
+ eAtomTypeTypeFlags = 5u,
+ /// A 32 bit hash of the full qualified name (since all hash entries are
+ /// basename only) For example a type like "std::vector<int>::iterator"
+ /// would have a name of "iterator" and a 32 bit hash for
+ /// "std::vector<int>::iterator" to allow us to not have to pull in debug
+ /// info for a type when we know the fully qualified name.
+ eAtomTypeQualNameHash = 6u
};
- // Bit definitions for the eAtomTypeTypeFlags flags
+ /// Bit definitions for the eAtomTypeTypeFlags flags.
enum TypeFlags {
- // Always set for C++, only set for ObjC if this is the
- // @implementation for class
+ /// Always set for C++, only set for ObjC if this is the
+ /// @implementation for class.
eTypeFlagClassIsImplementation = (1u << 1)
};
struct DIEInfo {
dw_offset_t die_offset = DW_INVALID_OFFSET;
- dw_tag_t tag = 0;
+ dw_tag_t tag = llvm::dwarf::DW_TAG_null;
- /// Any flags for this DIEInfo
+ /// Any flags for this DIEInfo.
uint32_t type_flags = 0;
- /// A 32 bit hash of the fully qualified name
+ /// A 32 bit hash of the fully qualified name.
uint32_t qualified_name_hash = 0;
DIEInfo() = default;
@@ -94,7 +98,7 @@ public:
bool HashDataHasFixedByteSize() const;
- // DIE offset base so die offsets in hash_data can be CU relative
+ /// DIE offset base so die offsets in hash_data can be CU relative.
dw_offset_t die_base_offset;
AtomArray atoms;
uint32_t atom_mask;
@@ -113,8 +117,8 @@ public:
lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
};
- // A class for reading and using a saved hash table from a block of data
- // in memory
+ /// A class for reading and using a saved hash table from a block of data in
+ /// memory.
class MemoryTable
: public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
DIEInfoArray> {
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index e2ddcfc5d64b..c982d59c2830 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -8,6 +8,7 @@
#include "SymbolFileDWARF.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -43,7 +44,7 @@
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
@@ -58,7 +59,6 @@
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
-#include "DWARFDebugLine.h"
#include "DWARFDebugMacro.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
@@ -72,6 +72,7 @@
#include "SymbolFileDWARFDwo.h"
#include "SymbolFileDWARFDwp.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Support/FileSystem.h"
#include <algorithm>
@@ -113,18 +114,12 @@ using namespace lldb_private;
namespace {
-static constexpr PropertyDefinition g_properties[] = {
- {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- {},
- "If the DW_AT_comp_dir matches any of these paths the symbolic "
- "links will be resolved at DWARF parse time."},
- {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {},
- "Ignore indexes present in the object files and always index DWARF "
- "manually."}};
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFProperties.inc"
enum {
- ePropertySymLinkPaths,
- ePropertyIgnoreIndexes,
+#define LLDB_PROPERTIES_symbolfiledwarf
+#include "SymbolFileDWARFPropertiesEnum.inc"
};
class PluginProperties : public Properties {
@@ -135,7 +130,7 @@ public:
PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_symbolfiledwarf_properties);
}
FileSpecList GetSymLinkPaths() {
@@ -159,7 +154,66 @@ static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-} // anonymous namespace end
+} // namespace
+
+static const llvm::DWARFDebugLine::LineTable *
+ParseLLVMLineTable(lldb_private::DWARFContext &context,
+ llvm::DWARFDebugLine &line, dw_offset_t line_offset,
+ dw_offset_t unit_offset) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+
+ llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = context.GetAsLLVM();
+ llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table =
+ line.getOrParseLineTable(
+ data, line_offset, ctx, nullptr, [&](llvm::Error e) {
+ LLDB_LOG_ERROR(log, std::move(e),
+ "SymbolFileDWARF::ParseLineTable failed to parse");
+ });
+
+ if (!line_table) {
+ LLDB_LOG_ERROR(log, line_table.takeError(),
+ "SymbolFileDWARF::ParseLineTable failed to parse");
+ return nullptr;
+ }
+ return *line_table;
+}
+
+static FileSpecList ParseSupportFilesFromPrologue(
+ const lldb::ModuleSP &module,
+ const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style,
+ llvm::StringRef compile_dir = {}, FileSpec first_file = {}) {
+ FileSpecList support_files;
+ support_files.Append(first_file);
+
+ const size_t number_of_files = prologue.FileNames.size();
+ for (size_t idx = 1; idx <= number_of_files; ++idx) {
+ std::string original_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::Default, original_file,
+ style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack();
+ continue;
+ }
+
+ std::string remapped_file;
+ if (!prologue.getFileNameByIndex(
+ idx, compile_dir,
+ llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ remapped_file, style)) {
+ // Always add an entry so the indexes remain correct.
+ support_files.EmplaceBack(original_file, style);
+ continue;
+ }
+
+ module->RemapSourceFile(llvm::StringRef(original_file), remapped_file);
+ support_files.EmplaceBack(remapped_file, style);
+ }
+
+ return support_files;
+}
FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
return GetGlobalPluginProperties()->GetSymLinkPaths();
@@ -197,20 +251,16 @@ const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader.";
}
-SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARF(obj_file,
+SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARF(std::move(objfile_sp),
/*dwo_section_list*/ nullptr);
}
-TypeList *SymbolFileDWARF::GetTypeList() {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
+TypeList &SymbolFileDWARF::GetTypeList() {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
return debug_map_symfile->GetTypeList();
- else
- return m_obj_file->GetModule()->GetTypeList();
+ return SymbolFile::GetTypeList();
}
void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
dw_offset_t max_die_offset, uint32_t type_mask,
@@ -264,6 +314,8 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
case DW_TAG_ptr_to_member_type:
add_type = (type_mask & eTypeClassMemberPointer) != 0;
break;
+ default:
+ break;
}
if (add_type) {
@@ -283,11 +335,11 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
}
}
-size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask, TypeList &type_list)
+void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask, TypeList &type_list)
{
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeSet type_set;
CompileUnit *comp_unit = nullptr;
@@ -297,8 +349,8 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
if (comp_unit) {
dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == nullptr)
- return 0;
+ if (!dwarf_cu)
+ return;
GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
} else {
@@ -315,16 +367,13 @@ size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
}
std::set<CompilerType> compiler_type_set;
- size_t num_types_added = 0;
for (Type *type : type_set) {
CompilerType compiler_type = type->GetForwardCompilerType();
if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
compiler_type_set.insert(compiler_type);
type_list.Insert(type->shared_from_this());
- ++num_types_added;
}
}
- return num_types_added;
}
// Gets the first parent that is a lexical block, function or inlined
@@ -342,19 +391,21 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
case DW_TAG_inlined_subroutine:
case DW_TAG_lexical_block:
return die;
+ default:
+ break;
}
}
return DWARFDIE();
}
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile,
+SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
SectionList *dwo_section_list)
- : SymbolFile(objfile),
+ : SymbolFile(std::move(objfile_sp)),
UserID(0x7fffffff00000000), // 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(nullptr),
- m_context(objfile->GetModule()->GetSectionList(), dwo_section_list),
+ m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
m_data_debug_loc(), m_abbr(), m_info(), m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate),
m_unique_ast_type_map() {}
@@ -374,17 +425,17 @@ UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
return m_unique_ast_type_map;
}
-TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- TypeSystem *type_system;
- if (debug_map_symfile) {
- type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
- } else {
- type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
+llvm::Expected<TypeSystem &>
+SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
+ return debug_map_symfile->GetTypeSystemForLanguage(language);
+
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
}
- return type_system;
+ return type_system_or_err;
}
void SymbolFileDWARF::InitializeObject() {
@@ -420,7 +471,7 @@ void SymbolFileDWARF::InitializeObject() {
}
}
- m_index = llvm::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
+ m_index = std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(),
DebugInfo());
}
@@ -430,9 +481,9 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
uint32_t SymbolFileDWARF::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file != nullptr) {
+ if (m_objfile_sp != nullptr) {
const Section *section = nullptr;
- const SectionList *section_list = m_obj_file->GetSectionList();
+ const SectionList *section_list = m_objfile_sp->GetSectionList();
if (section_list == nullptr)
return 0;
@@ -462,10 +513,12 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
abbrev->GetUnsupportedForms(invalid_forms);
if (!invalid_forms.empty()) {
StreamString error;
- error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+ error.Printf("unsupported DW_FORM value%s:",
+ invalid_forms.size() > 1 ? "s" : "");
for (auto form : invalid_forms)
error.Printf(" %#x", form);
- m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+ m_objfile_sp->GetModule()->ReportWarning(
+ "%s", error.GetString().str().c_str());
return 0;
}
}
@@ -477,10 +530,10 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
debug_line_file_size = section->GetFileSize();
} else {
const char *symfile_dir_cstr =
- m_obj_file->GetFileSpec().GetDirectory().GetCString();
+ m_objfile_sp->GetFileSpec().GetDirectory().GetCString();
if (symfile_dir_cstr) {
if (strcasestr(symfile_dir_cstr, ".dsym")) {
- if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
+ if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) {
// We have a dSYM file that didn't have a any debug info. If the
// string table has a size of 1, then it was made from an
// executable with no debug info, or from an executable that was
@@ -489,7 +542,7 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
.get();
if (section && section->GetFileSize() == 1) {
- m_obj_file->GetModule()->ReportWarning(
+ m_objfile_sp->GetModule()->ReportWarning(
"empty dSYM file detected, dSYM was created with an "
"executable with no debug info.");
}
@@ -519,7 +572,7 @@ SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
const SectionList *section_list = module_sp->GetSectionList();
if (!section_list)
return;
@@ -529,7 +582,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
return;
data.Clear();
- m_obj_file->ReadSectionData(section_sp.get(), data);
+ m_objfile_sp->ReadSectionData(section_sp.get(), data);
}
const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() {
@@ -556,7 +609,7 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
if (debug_abbrev_data.GetByteSize() == 0)
return nullptr;
- auto abbr = llvm::make_unique<DWARFDebugAbbrev>();
+ auto abbr = std::make_unique<DWARFDebugAbbrev>();
llvm::Error error = abbr->parse(debug_abbrev_data);
if (error) {
Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
@@ -579,7 +632,7 @@ DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
- m_info = llvm::make_unique<DWARFDebugInfo>(*this, m_context);
+ m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
}
return m_info.get();
}
@@ -604,7 +657,7 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return nullptr;
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
+DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
if (!m_ranges) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -619,7 +672,7 @@ DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
return m_ranges.get();
}
-DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() {
+DWARFDebugRngLists *SymbolFileDWARF::GetDebugRngLists() {
if (!m_rnglists) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
@@ -648,7 +701,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
cu_sp = m_debug_map_symfile->GetCompileUnit(this);
dwarf_cu.SetUserData(cu_sp.get());
} else {
- ModuleSP module_sp(m_obj_file->GetModule());
+ ModuleSP module_sp(m_objfile_sp->GetModule());
if (module_sp) {
const DWARFDIE cu_die = dwarf_cu.DIE();
if (cu_die) {
@@ -677,8 +730,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
dwarf_cu.SetUserData(cu_sp.get());
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- dwarf_cu.GetID(), cu_sp);
+ SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
}
}
}
@@ -715,7 +767,7 @@ llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
return m_lldb_cu_to_dwarf_unit[cu_idx];
}
-uint32_t SymbolFileDWARF::GetNumCompileUnits() {
+uint32_t SymbolFileDWARF::CalculateNumCompileUnits() {
DWARFDebugInfo *info = DebugInfo();
if (!info)
return 0;
@@ -741,17 +793,21 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
const DWARFDIE &die) {
ASSERT_MODULE_LOCK(this);
- if (die.IsValid()) {
- TypeSystem *type_system =
- GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system) {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
- }
+ if (!die.IsValid())
+ return nullptr;
+
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse function");
+ return nullptr;
}
- return nullptr;
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+ if (!dwarf_ast)
+ return nullptr;
+
+ return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
}
bool SymbolFileDWARF::FixupAddress(Address &addr) {
@@ -763,7 +819,7 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {
return true;
}
lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetLanguageType();
@@ -772,7 +828,7 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (!dwarf_cu)
return 0;
@@ -790,21 +846,23 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
return functions_added;
}
+void SymbolFileDWARF::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ UpdateExternalModuleListIfNeeded();
+
+ for (auto &p : m_external_type_modules) {
+ ModuleSP module = p.second;
+ f(module);
+ for (std::size_t i = 0; i < module->GetNumCompileUnits(); ++i)
+ module->GetCompileUnitAtIndex(i)->ForEachExternalModule(f);
+ }
+}
+
bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
- ASSERT_MODULE_LOCK(this);
- if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) {
- const dw_offset_t stmt_list = unit->GetLineTableOffset();
- if (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.
- support_files.Append(comp_unit);
- return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(),
- m_context.getOrLoadLineData(),
- stmt_list, support_files, unit);
- }
- }
- return false;
+ if (!comp_unit.GetLineTable())
+ ParseLineTable(comp_unit);
+ return true;
}
FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
@@ -833,16 +891,26 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
auto iter_bool = m_type_unit_support_files.try_emplace(offset);
FileSpecList &list = iter_bool.first->second;
if (iter_bool.second) {
- list.Append(FileSpec());
- DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(),
- m_context.getOrLoadLineData(), offset,
- list, &tu);
+ uint64_t line_table_offset = offset;
+ llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM();
+ llvm::DWARFContext &ctx = m_context.GetAsLLVM();
+ llvm::DWARFDebugLine::Prologue prologue;
+ llvm::Error error = prologue.parse(data, &line_table_offset, ctx);
+ if (error) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ LLDB_LOG_ERROR(log, std::move(error),
+ "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse "
+ "the line table prologue");
+ } else {
+ list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(),
+ prologue, tu.GetPathStyle());
+ }
}
return list;
}
bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetIsOptimized();
@@ -852,7 +920,7 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<SourceModule> &imported_modules) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
assert(sc.comp_unit);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (!dwarf_cu)
@@ -901,102 +969,63 @@ bool SymbolFileDWARF::ParseImportedModules(
return true;
}
-struct ParseDWARFLineTableCallbackInfo {
- LineTable *line_table;
- std::unique_ptr<LineSequence> sequence_up;
- lldb::addr_t addr_mask;
-};
-
-// ParseStatementTableCallback
-static void ParseDWARFLineTableCallback(dw_offset_t offset,
- const DWARFDebugLine::State &state,
- void *userData) {
- if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
- // Just started parsing the line table
- } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
- // Done parsing line table, nothing to do for the cleanup
- } else {
- ParseDWARFLineTableCallbackInfo *info =
- (ParseDWARFLineTableCallbackInfo *)userData;
- LineTable *line_table = info->line_table;
-
- // If this is our first time here, we need to create a sequence container.
- if (!info->sequence_up) {
- info->sequence_up.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_up.get());
- }
- line_table->AppendLineEntryToSequence(
- info->sequence_up.get(), state.address & info->addr_mask, state.line,
- state.column, state.file, state.is_stmt, state.basic_block,
- state.prologue_end, state.epilogue_begin, state.end_sequence);
- if (state.end_sequence) {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->sequence_up.get());
- // Then, empty it to prepare for the next sequence.
- info->sequence_up->Clear();
- }
- }
-}
-
bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable() != nullptr)
return true;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
- if (dwarf_cu) {
- const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
- if (dwarf_cu_die) {
- 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_up(new LineTable(&comp_unit));
- if (line_table_up) {
- ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_up.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.
- */
- switch (GetObjectFile()->GetArchitecture().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;
- }
+ if (!dwarf_cu)
+ return false;
- lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(
- m_context.getOrLoadLineData(), &offset,
- ParseDWARFLineTableCallback, &info, dwarf_cu);
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We have an object file that has a line table with addresses that
- // are not linked. We need to link the line table and convert the
- // addresses that are relative to the .o file into addresses for
- // the main executable.
- comp_unit.SetLineTable(
- debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
- } else {
- comp_unit.SetLineTable(line_table_up.release());
- return true;
- }
- }
- }
+ const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
+ if (!dwarf_cu_die)
+ return false;
+
+ 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)
+ return false;
+
+ llvm::DWARFDebugLine line;
+ const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(
+ m_context, line, cu_line_offset, dwarf_cu->GetOffset());
+
+ if (!line_table)
+ return false;
+
+ // FIXME: Rather than parsing the whole line table and then copying it over
+ // into LLDB, we should explore using a callback to populate the line table
+ // while we parse to reduce memory usage.
+ std::unique_ptr<LineTable> line_table_up =
+ std::make_unique<LineTable>(&comp_unit);
+ LineSequence *sequence = line_table_up->CreateLineSequenceContainer();
+ for (auto &row : line_table->Rows) {
+ line_table_up->AppendLineEntryToSequence(
+ sequence, row.Address.Address, row.Line, row.Column, row.File,
+ row.IsStmt, row.BasicBlock, row.PrologueEnd, row.EpilogueBegin,
+ row.EndSequence);
+ if (row.EndSequence) {
+ line_table_up->InsertSequence(sequence);
+ sequence = line_table_up->CreateLineSequenceContainer();
}
}
- return false;
+
+ if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) {
+ // We have an object file that has a line table with addresses that are not
+ // linked. We need to link the line table and convert the addresses that
+ // are relative to the .o file into addresses for the main executable.
+ comp_unit.SetLineTable(
+ debug_map_symfile->LinkOSOLineTable(this, line_table_up.get()));
+ } else {
+ comp_unit.SetLineTable(line_table_up.release());
+ }
+
+ comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue(
+ comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(),
+ dwarf_cu->GetCompilationDirectory().GetCString(), FileSpec(comp_unit)));
+
+ return true;
}
lldb_private::DebugMacrosSP
@@ -1022,7 +1051,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
}
bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu == nullptr)
@@ -1114,7 +1143,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
"0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64
") which has a base that is less than the function's low PC "
"0x%" PRIx64 ". Please file a bug and attach the file at the "
- "start of this error message",
+ "start of this error message",
block->GetID(), range_base, range.GetRangeEnd(),
subprogram_low_pc);
}
@@ -1188,15 +1217,10 @@ bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
}
void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
- TypeSystem *type_system = decl_ctx.GetTypeSystem();
- DWARFASTParser *ast_parser = type_system->GetDWARFParser();
- std::vector<DWARFDIE> decl_ctx_die_list =
- ast_parser->GetDIEForDeclContext(decl_ctx);
-
- for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
- for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl;
- decl = decl.GetSibling())
- ast_parser->GetDeclForUIDFromDWARF(decl);
+ auto *type_system = decl_ctx.GetTypeSystem();
+ if (type_system != nullptr)
+ type_system->GetDWARFParser()->EnsureAllDIEsInDeclContextHaveBeenParsed(
+ decl_ctx);
}
user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
@@ -1281,8 +1305,6 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIE(). See comments inside the
@@ -1293,8 +1315,6 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
}
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
- // This method can be called without going through the symbol vendor so we
- // need to lock the module.
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIE(). See comments inside the
@@ -1341,8 +1361,9 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
// 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",
+ 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;
@@ -1504,7 +1525,6 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
->GetDIE(die_ref);
}
-
DWARFDebugInfo *debug_info = DebugInfo();
if (debug_info)
return debug_info->GetDIE(die_ref);
@@ -1567,7 +1587,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
if (dwo_obj_file == nullptr)
return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
+ return std::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
}
void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
@@ -1607,7 +1627,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
}
}
dwo_module_spec.GetArchitecture() =
- m_obj_file->GetModule()->GetArchitecture();
+ m_objfile_sp->GetModule()->GetArchitecture();
// When LLDB loads "external" modules it looks at the presence of
// DW_AT_GNU_dwo_name. However, when the already created module
@@ -1621,8 +1641,8 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
// printed. However, as one can notice in this case we don't
// actually need to try to load the already loaded module
// (corresponding to .dwo) so we simply skip it.
- if (m_obj_file->GetFileSpec().GetFileNameExtension() == ".dwo" &&
- llvm::StringRef(m_obj_file->GetFileSpec().GetPath())
+ if (m_objfile_sp->GetFileSpec().GetFileNameExtension() == ".dwo" &&
+ llvm::StringRef(m_objfile_sp->GetFileSpec().GetPath())
.endswith(dwo_module_spec.GetFileSpec().GetPath())) {
continue;
}
@@ -1694,6 +1714,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARF::"
@@ -1837,6 +1858,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool check_inlines,
SymbolContextItem resolve_scope,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
@@ -1849,7 +1871,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
bool file_spec_matches_cu_file_spec =
FileSpec::Equal(file_spec, *dc_cu, full_match);
if (check_inlines || file_spec_matches_cu_file_spec) {
- SymbolContext sc(m_obj_file->GetModule());
+ SymbolContext sc(m_objfile_sp->GetModule());
sc.comp_unit = dc_cu;
uint32_t file_idx = UINT32_MAX;
@@ -1961,9 +1983,16 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
}
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to match namespace decl using TypeSystem");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
// The namespace AST was valid, and it does not match...
@@ -1976,9 +2005,10 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
return false;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(
+void SymbolFileDWARF::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log)
@@ -1990,11 +2020,11 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
max_matches);
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2012,7 +2042,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
const size_t num_die_matches = die_offsets.size();
if (num_die_matches) {
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
// Loop invariant: Variables up to this index have been checked for context
@@ -2081,12 +2111,12 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(
name.GetCString(), static_cast<const void *>(parent_decl_ctx),
max_matches, num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
+void SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
+ uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2098,8 +2128,8 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
}
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
// Remember how many variables are in the list before we search.
const uint32_t original_size = variables.GetSize();
@@ -2108,7 +2138,7 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->GetGlobalVariables(regex, die_offsets);
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
assert(sc.module_sp);
const size_t num_matches = die_offsets.size();
@@ -2132,9 +2162,6 @@ uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression &regex,
m_index->ReportInvalidDIERef(die_ref, regex.GetText());
}
}
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
@@ -2210,10 +2237,12 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
return false;
}
-uint32_t SymbolFileDWARF::FindFunctions(
- ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
@@ -2226,21 +2255,17 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, append=%u, sc_list)",
- name.GetCString(), name_type_mask, append);
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+ name.GetCString(), name_type_mask);
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
// If name is empty then we won't find anything.
if (name.IsEmpty())
- return 0;
+ return;
// Remember how many sc_list are in the list before we search in case we are
// appending the results to a variable list.
@@ -2255,7 +2280,7 @@ uint32_t SymbolFileDWARF::FindFunctions(
std::vector<DWARFDIE> dies;
m_index->GetFunctions(name, *this, *parent_decl_ctx, name_type_mask, dies);
- for (const DWARFDIE &die: dies) {
+ for (const DWARFDIE &die : dies) {
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
@@ -2265,18 +2290,18 @@ uint32_t SymbolFileDWARF::FindFunctions(
if (log && num_matches > 0) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
- "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => "
- "%u",
- name.GetCString(), name_type_mask, include_inlines, append,
+ log,
+ "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
+ name.GetCString(), name_type_mask, include_inlines,
num_matches);
}
- return num_matches;
}
-uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
@@ -2285,22 +2310,13 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
- regex.GetText().str().c_str(), append);
+ log, "SymbolFileDWARF::FindFunctions (regex=\"%s\", sc_list)",
+ regex.GetText().str().c_str());
}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
DWARFDebugInfo *info = DebugInfo();
if (!info)
- return 0;
-
- // 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 = sc_list.GetSize();
+ return;
DIEArray offsets;
m_index->GetFunctions(regex, offsets);
@@ -2315,9 +2331,6 @@ uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
if (resolved_dies.insert(die.GetDIE()).second)
ResolveFunction(die, include_inlines, sc_list);
}
-
- // Return the number of variable that were appended to the list
- return sc_list.GetSize() - original_size;
}
void SymbolFileDWARF::GetMangledNamesForFunction(
@@ -2345,156 +2358,141 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
}
-uint32_t SymbolFileDWARF::FindTypes(
+void SymbolFileDWARF::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Make sure we haven't already searched this SymbolFile before...
if (searched_symbol_files.count(this))
- return 0;
- else
- searched_symbol_files.insert(this);
+ return;
+
+ searched_symbol_files.insert(this);
DWARFDebugInfo *info = DebugInfo();
- if (info == nullptr)
- return 0;
+ if (!info)
+ return;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
if (parent_decl_ctx)
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "%p (\"%s\"), append=%u, max_matches=%u, type_list)",
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "%p (\"%s\"), max_matches=%u, type_list)",
name.GetCString(), static_cast<const void *>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches);
+ parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches);
else
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
- "NULL, append=%u, max_matches=%u, type_list)",
- name.GetCString(), append, max_matches);
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "NULL, max_matches=%u, type_list)",
+ name.GetCString(), max_matches);
}
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- const uint32_t initial_types_size = types.GetSize();
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
-
- if (die) {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- 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());
- if (types.GetSize() >= max_matches)
- break;
- }
- } else {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
- }
- const uint32_t num_matches = types.GetSize() - initial_types_size;
- if (log && num_matches) {
- if (parent_decl_ctx) {
- GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
- "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), 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\", parent_decl_ctx "
- "= NULL, append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(), append, max_matches, num_matches);
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ 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());
+ if (types.GetSize() >= max_matches)
+ break;
}
+ } else {
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
}
- return num_matches;
- } else {
+ }
+
+ // Next search through the reachable Clang modules. This only applies for
+ // DWARF objects compiled with -gmodules that haven't been processed by
+ // dsymutil.
+ if (num_die_matches < max_matches) {
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(name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types);
- if (num_external_matches)
- return num_external_matches;
- }
- }
- }
+ for (const auto &pair : m_external_type_modules)
+ if (ModuleSP external_module_sp = pair.second)
+ if (SymbolFile *sym_file = external_module_sp->GetSymbolFile())
+ sym_file->FindTypes(name, parent_decl_ctx, max_matches,
+ searched_symbol_files, types);
}
- return 0;
+ if (log && types.GetSize()) {
+ if (parent_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= %p (\"%s\"), max_matches=%u, type_list) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"), max_matches,
+ types.GetSize());
+ } else {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= NULL, max_matches=%u, type_list) => %u",
+ name.GetCString(), max_matches, types.GetSize());
+ }
+ }
}
-size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- if (!append)
- types.Clear();
-
- if (context.empty())
- return 0;
+void SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (pattern.empty())
+ return;
- ConstString name = context.back().name;
+ ConstString name = pattern.back().name;
if (!name)
- return 0;
+ return;
DIEArray die_offsets;
m_index->GetTypes(name, die_offsets);
const size_t num_die_matches = die_offsets.size();
- if (num_die_matches) {
- size_t num_matches = 0;
- for (size_t i = 0; i < num_die_matches; ++i) {
- const DIERef &die_ref = die_offsets[i];
- DWARFDIE die = GetDIE(die_ref);
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
- if (die) {
- std::vector<CompilerContext> die_context;
- die.GetDeclContext(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 {
- m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
- }
+ if (!die) {
+ m_index->ReportInvalidDIERef(die_ref, name.GetStringRef());
+ continue;
}
- return num_matches;
+ if (!languages[die.GetCU()->GetLanguageType()])
+ continue;
+
+ llvm::SmallVector<CompilerContext, 4> die_context;
+ die.GetDeclContext(die_context);
+ if (!contextMatches(die_context, pattern))
+ continue;
+
+ if (Type *matching_type = ResolveType(die, true, true))
+ // We found a type pointer, now find the shared pointer form our type
+ // list.
+ types.InsertUnique(matching_type->shared_from_this());
}
- return 0;
}
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
if (log) {
@@ -2536,8 +2534,9 @@ SymbolFileDWARF::FindNamespace(ConstString name,
}
if (log && namespace_decl_ctx) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
- "CompilerDeclContext(%p/%p) \"%s\"",
+ log,
+ "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
+ "CompilerDeclContext(%p/%p) \"%s\"",
name.GetCString(),
static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
@@ -2632,11 +2631,10 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
return DWARFDIE();
}
-Symbol *
-SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
+Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
Symbol *objc_class_symbol = nullptr;
- if (m_obj_file) {
- Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
@@ -2653,8 +2651,7 @@ SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
// worry about the debug map
// DWARF file
// if we are doing darwin DWARF in .o file debugging.
-bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
- DWARFUnit *cu) {
+bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
@@ -2681,8 +2678,7 @@ bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
// 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 DWARFDIE &die, ConstString type_name,
- bool must_be_implementation) {
+ const DWARFDIE &die, ConstString type_name, bool must_be_implementation) {
TypeSP type_sp;
@@ -2727,7 +2723,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
" (cu 0x%8.8" PRIx64 ")\n",
die.GetID(),
- m_obj_file->GetFileSpec().GetFilename().AsCString(
+ m_objfile_sp->GetFileSpec().GetFilename().AsCString(
"<Unknown>"),
type_die.GetID(), type_cu->GetID());
@@ -2849,8 +2845,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
DWARF_LOG_LOOKUPS));
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
- "s, qualified-name='%s')",
+ log,
+ "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
+ "s, qualified-name='%s')",
DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
dwarf_decl_ctx.GetQualifiedName());
}
@@ -2863,10 +2860,18 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
// use this to ensure any matches we find are in a language that this
// type system supports
const LanguageType language = dwarf_decl_ctx.GetLanguage();
- TypeSystem *type_system = (language == eLanguageTypeUnknown)
- ? nullptr
- : GetTypeSystemForLanguage(language);
-
+ TypeSystem *type_system = nullptr;
+ if (language != eLanguageTypeUnknown) {
+ auto type_system_or_err = GetTypeSystemForLanguage(language);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Cannot get TypeSystem for language {}",
+ Language::GetNameForLanguageType(language));
+ } else {
+ type_system = &type_system_or_err.get();
+ }
+ }
if (num_matches) {
for (size_t i = 0; i < num_matches; ++i) {
const DIERef &die_ref = die_offsets[i];
@@ -2916,9 +2921,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
if (log) {
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') trying die=0x%8.8x (%s)",
+ log,
+ "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_dwarf_decl_ctx.GetQualifiedName());
@@ -2937,9 +2943,10 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
std::string qualified_name;
type_die.GetQualifiedName(qualified_name);
GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::"
- "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
- "qualified-name='%s') ignoring die=0x%8.8x (%s)",
+ 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(),
qualified_name.c_str());
@@ -2960,21 +2967,21 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
if (!die)
return {};
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
- if (!type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse type");
return {};
+ }
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
if (!dwarf_ast)
return {};
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ TypeSP type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, type_is_new_ptr);
if (type_sp) {
- TypeList *type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
+ GetTypeList().Insert(type_sp);
if (die.Tag() == DW_TAG_subprogram) {
std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
@@ -2995,12 +3002,21 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
bool parse_siblings, bool parse_children) {
size_t types_added = 0;
DWARFDIE die = orig_die;
+
while (die) {
+ const dw_tag_t tag = die.Tag();
bool type_is_new = false;
- if (ParseType(sc, die, &type_is_new).get()) {
- if (type_is_new)
- ++types_added;
- }
+
+ Tag dwarf_tag = static_cast<Tag>(tag);
+
+ // TODO: Currently ParseTypeFromDWARF(...) which is called by ParseType(...)
+ // does not handle DW_TAG_subrange_type. It is not clear if this is a bug or
+ // not.
+ if (isType(dwarf_tag) && tag != DW_TAG_subrange_type)
+ ParseType(sc, die, &type_is_new);
+
+ if (type_is_new)
+ ++types_added;
if (parse_children && die.HasChildren()) {
if (die.Tag() == DW_TAG_subprogram) {
@@ -3020,7 +3036,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
}
size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
lldbassert(comp_unit);
@@ -3040,7 +3056,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t types_added = 0;
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
@@ -3056,7 +3072,7 @@ size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
- ASSERT_MODULE_LOCK(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (sc.comp_unit != nullptr) {
DWARFDebugInfo *info = DebugInfo();
if (info == nullptr)
@@ -3193,15 +3209,18 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, debug_info_data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU());
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Retrieve the value as a data expression.
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(
+ module,
+ DataExtractor(debug_info_data, data_offset, *data_length),
+ die.GetCU());
else {
const uint8_t *data_pointer = form_value.BlockData();
if (data_pointer) {
@@ -3217,17 +3236,21 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (form_value.Form() == DW_FORM_strp) {
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
if (auto data_length = form_value.GetFixedSize())
- location =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- data_offset, *data_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ data_offset,
+ *data_length),
+ die.GetCU());
} else {
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 =
- DWARFExpression(module, debug_info_data, die.GetCU(),
- string_offset, string_length);
+ location = DWARFExpression(module,
+ DataExtractor(debug_info_data,
+ string_offset,
+ string_length),
+ die.GetCU());
}
}
}
@@ -3241,17 +3264,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(module, data, die.GetCU(),
- block_offset, block_length);
+ location = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length),
+ die.GetCU());
} else {
- const DWARFDataExtractor &debug_loc_data = DebugLocData();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(
- die.GetCU(), debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0) {
- location = DWARFExpression(module, debug_loc_data, die.GetCU(),
- debug_loc_offset, loc_list_length);
+ DataExtractor data = DebugLocData();
+ const dw_offset_t offset = form_value.Unsigned();
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ location = DWARFExpression(module, data, die.GetCU());
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide(
func_low_pc -
@@ -3522,6 +3543,8 @@ SymbolFileDWARF::FindBlockContainingSpecification(
spec_block_die_offset)
return die;
} break;
+ default:
+ break;
}
// Give the concrete function die specified by "func_die_offset", find the
@@ -3577,8 +3600,7 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
} 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",
+ "symbol context for 0x%8.8" PRIx64 " %s.\n",
sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
orig_die.GetID(), orig_die.GetTagAsCString());
}
@@ -3654,9 +3676,57 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
return vars_added;
}
+/// Collect call site parameters in a DW_TAG_call_site DIE.
+static CallSiteParameterArray
+CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
+ CallSiteParameterArray parameters;
+ for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid();
+ child = child.GetSibling()) {
+ if (child.Tag() != DW_TAG_call_site_parameter)
+ continue;
+
+ llvm::Optional<DWARFExpression> LocationInCallee = {};
+ llvm::Optional<DWARFExpression> LocationInCaller = {};
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = child.GetAttributes(attributes);
+
+ // Parse the location at index \p attr_index within this call site parameter
+ // DIE, or return None on failure.
+ auto parse_simple_location =
+ [&](int attr_index) -> llvm::Optional<DWARFExpression> {
+ DWARFFormValue form_value;
+ if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
+ return {};
+ if (!DWARFFormValue::IsBlockForm(form_value.Form()))
+ return {};
+ auto data = child.GetData();
+ uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ return DWARFExpression(module,
+ DataExtractor(data, block_offset, block_length),
+ child.GetCU());
+ };
+
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ if (attr == DW_AT_location)
+ LocationInCallee = parse_simple_location(i);
+ if (attr == DW_AT_call_value)
+ LocationInCaller = parse_simple_location(i);
+ }
+
+ if (LocationInCallee && LocationInCaller) {
+ CallSiteParameter param = {*LocationInCallee, *LocationInCaller};
+ parameters.push_back(param);
+ }
+ }
+ return parameters;
+}
+
/// Collect call graph edges present in a function DIE.
static std::vector<lldb_private::CallEdge>
-CollectCallEdges(DWARFDIE function_die) {
+CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
// Check if the function has a supported call site-related attribute.
// TODO: In the future it may be worthwhile to support call_all_source_calls.
uint64_t has_call_edges =
@@ -3693,9 +3763,28 @@ CollectCallEdges(DWARFDIE function_die) {
addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc,
LLDB_INVALID_ADDRESS);
+ // Extract call site parameters.
+ CallSiteParameterArray parameters =
+ CollectCallSiteParameters(module, child);
+
LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
call_origin.GetPubname(), return_pc);
- call_edges.emplace_back(call_origin.GetMangledName(), return_pc);
+ if (log && parameters.size()) {
+ for (const CallSiteParameter &param : parameters) {
+ StreamString callee_loc_desc, caller_loc_desc;
+ param.LocationInCallee.GetDescription(&callee_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ param.LocationInCaller.GetDescription(&caller_loc_desc,
+ eDescriptionLevelBrief,
+ LLDB_INVALID_ADDRESS, nullptr);
+ LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}",
+ callee_loc_desc.GetString(), caller_loc_desc.GetString());
+ }
+ }
+
+ call_edges.emplace_back(call_origin.GetMangledName(), return_pc,
+ std::move(parameters));
}
return call_edges;
}
@@ -3704,7 +3793,7 @@ std::vector<lldb_private::CallEdge>
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
DWARFDIE func_die = GetDIE(func_id.GetID());
if (func_die.IsValid())
- return CollectCallEdges(func_die);
+ return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
return {};
}
@@ -3713,11 +3802,17 @@ ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
-void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); }
+void SymbolFileDWARF::Dump(lldb_private::Stream &s) {
+ SymbolFile::Dump(s);
+ m_index->Dump(s);
+}
void SymbolFileDWARF::DumpClangAST(Stream &s) {
- TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
- ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts);
+ auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+ if (!ts_or_err)
+ return;
+ ClangASTContext *clang =
+ llvm::dyn_cast_or_null<ClangASTContext>(&ts_or_err.get());
if (!clang)
return;
clang->Dump(s);
@@ -3727,10 +3822,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
if (module_sp) {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- m_debug_map_symfile =
- (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
+ m_debug_map_symfile =
+ (SymbolFileDWARFDebugMap *)module_sp->GetSymbolFile();
}
}
return m_debug_map_symfile;
@@ -3746,9 +3839,9 @@ SymbolFileDWARF::GetLocationListFormat() const {
SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
llvm::call_once(m_dwp_symfile_once_flag, [this]() {
ModuleSpec module_spec;
- module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
+ module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
module_spec.GetSymbolFileSpec() =
- FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp");
+ FileSpec(m_objfile_sp->GetFileSpec().GetPath() + ".dwp");
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec dwp_filespec =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 018af47305f4..04cb11d426be 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -46,7 +46,8 @@ class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
-class DWARFDebugRangesBase;
+class DWARFDebugRanges;
+class DWARFDebugRngLists;
class DWARFDeclContext;
class DWARFFormValue;
class DWARFTypeUnit;
@@ -78,13 +79,13 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
static lldb_private::FileSpecList GetSymlinkPaths();
// Constructors and Destructors
- SymbolFileDWARF(lldb_private::ObjectFile *ofile,
+ SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,
lldb_private::SectionList *dwo_section_list);
~SymbolFileDWARF() override;
@@ -95,10 +96,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -108,6 +105,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -156,47 +157,46 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
- lldb_private::TypeList *GetTypeList() override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
-
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -223,8 +223,8 @@ public:
const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugRangesBase *GetDebugRanges();
- DWARFDebugRangesBase *GetDebugRngLists();
+ DWARFDebugRanges *GetDebugRanges();
+ DWARFDebugRngLists *GetDebugRngLists();
const lldb_private::DWARFDataExtractor &DebugLocData();
@@ -331,6 +331,12 @@ protected:
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb_private::TypeList &GetTypeList() override;
+
virtual DWARFUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
@@ -477,8 +483,8 @@ protected:
typedef std::set<lldb::user_id_t> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
- std::unique_ptr<DWARFDebugRangesBase> m_ranges;
- std::unique_ptr<DWARFDebugRangesBase> m_rnglists;
+ std::unique_ptr<DWARFDebugRanges> m_ranges;
+ std::unique_ptr<DWARFDebugRngLists> m_rnglists;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 8ec64dbaf764..a50d4e460bae 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -41,7 +41,7 @@ using namespace lldb_private;
// Subclass lldb_private::Module so we can intercept the
// "Module::GetObjectFile()" (so we can fixup the object file sections) and
-// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
+// also for "Module::GetSymbolFile()" (so we can fixup the symbol file id.
const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
@@ -60,11 +60,11 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
return file_range_map;
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf(
- "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
- static_cast<void *>(this),
- oso_module->GetSpecificationDescription().c_str());
+ LLDB_LOGF(
+ log,
+ "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
+ static_cast<void *>(this),
+ oso_module->GetSpecificationDescription().c_str());
std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
@@ -173,12 +173,12 @@ public:
~DebugMapModule() override = default;
- SymbolVendor *
- GetSymbolVendor(bool can_create = true,
- lldb_private::Stream *feedback_strm = nullptr) override {
+ SymbolFile *
+ GetSymbolFile(bool can_create = true,
+ lldb_private::Stream *feedback_strm = nullptr) override {
// Scope for locker
if (m_symfile_up.get() || !can_create)
- return m_symfile_up.get();
+ return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
ModuleSP exe_module_sp(m_exe_module_wp.lock());
if (exe_module_sp) {
@@ -186,30 +186,28 @@ public:
ObjectFile *oso_objfile = GetObjectFile();
if (oso_objfile) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- SymbolVendor *symbol_vendor =
- Module::GetSymbolVendor(can_create, feedback_strm);
- if (symbol_vendor) {
+ if (SymbolFile *symfile =
+ Module::GetSymbolFile(can_create, feedback_strm)) {
// Set a pointer to this class to set our OSO DWARF file know that
// the DWARF is being used along with a debug map and that it will
// have the remapped sections that we do below.
SymbolFileDWARF *oso_symfile =
- SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
- symbol_vendor->GetSymbolFile());
+ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symfile);
if (!oso_symfile)
return nullptr;
ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
+ SymbolFile *exe_symfile = exe_module_sp->GetSymbolFile();
- if (exe_objfile && exe_sym_vendor) {
+ if (exe_objfile && exe_symfile) {
oso_symfile->SetDebugMapModule(exe_module_sp);
// Set the ID of the symbol file DWARF to the index of the OSO
// shifted left by 32 bits to provide a unique prefix for any
// UserID's that get created in the symbol file.
oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
}
- return symbol_vendor;
+ return symfile;
}
}
}
@@ -239,13 +237,13 @@ const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
return "DWARF and DWARF3 debug symbol file reader (debug map).";
}
-SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileDWARFDebugMap(obj_file);
+SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileDWARFDebugMap(std::move(objfile_sp));
}
-SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
- : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
- m_glob_indexes(),
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
+ m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
@@ -260,12 +258,12 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// If the object file has been stripped, there is no sense in looking further
// as all of the debug symbols for the debug map will not be available
- if (m_obj_file->IsStripped())
+ if (m_objfile_sp->IsStripped())
return;
// Also make sure the file type is some sort of executable. Core files, debug
// info files (dSYM), object files (.o files), and stub libraries all can
- switch (m_obj_file->GetType()) {
+ switch (m_objfile_sp->GetType()) {
case ObjectFile::eTypeInvalid:
case ObjectFile::eTypeCoreFile:
case ObjectFile::eTypeDebugInfo:
@@ -286,7 +284,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// these files exist and also contain valid DWARF. If we get any of that then
// we return the abilities of the first N_OSO's DWARF.
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
@@ -352,7 +350,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
// The sibling index can't be less that or equal to the current index
// "i"
if (sibling_idx == UINT32_MAX) {
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO in symbol with UID %u has invalid sibling in debug map, "
"please file a bug and attach the binary listed in this error",
so_symbol->GetID());
@@ -363,28 +361,27 @@ void SymbolFileDWARFDebugMap::InitOSO() {
m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
- oso_symbol->GetName().GetCString());
+ LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i,
+ oso_symbol->GetName().GetCString());
}
} else {
if (oso_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO symbol[%u] can't be found, please file a bug and attach "
"the binary listed in this error",
oso_idx);
else if (so_symbol == nullptr)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO not found for N_OSO symbol[%u], please file a bug and "
"attach the binary listed in this error",
oso_idx);
else if (so_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
so_symbol->GetType(), oso_idx);
else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
- m_obj_file->GetModule()->ReportError(
+ m_objfile_sp->GetModule()->ReportError(
"N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
"please file a bug and attach the binary listed in this error",
oso_symbol->GetType(), oso_idx);
@@ -421,7 +418,11 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// than the one from the CU.
auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
FileSystem::Instance().GetModificationTime(oso_file));
- if (oso_mod_time != comp_unit_info->oso_mod_time) {
+ // A timestamp of 0 means that the linker was in deterministic mode. In
+ // that case, we should skip the check against the filesystem last
+ // modification timestamp, since it will never match.
+ if (comp_unit_info->oso_mod_time != llvm::sys::TimePoint<>() &&
+ oso_mod_time != comp_unit_info->oso_mod_time) {
obj_file->GetModule()->ReportError(
"debug map object file '%s' has changed (actual time is "
"%s, debug map time is %s"
@@ -448,7 +449,7 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
// since .o files for "i386-apple-ios" will historically show up as "i386
// -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
// LC_VERSION_MIN_IPHONEOS load command...
- oso_arch.SetTriple(m_obj_file->GetModule()
+ oso_arch.SetTriple(m_objfile_sp->GetModule()
->GetArchitecture()
.GetTriple()
.getArchName()
@@ -534,12 +535,8 @@ SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
SymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
CompileUnitInfo *comp_unit_info) {
- Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
- if (oso_module) {
- SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
- if (sym_vendor)
- return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
- }
+ if (Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info))
+ return GetSymbolFileAsSymbolFileDWARF(oso_module->GetSymbolFile());
return nullptr;
}
@@ -562,7 +559,7 @@ uint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
return 0;
}
-uint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
+uint32_t SymbolFileDWARFDebugMap::CalculateNumCompileUnits() {
InitOSO();
return m_compile_unit_infos.size();
}
@@ -581,13 +578,12 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
lldb::user_id_t cu_id = 0;
m_compile_unit_infos[cu_idx].compile_unit_sp =
std::make_shared<CompileUnit>(
- m_obj_file->GetModule(), nullptr, so_file_spec, cu_id,
+ m_objfile_sp->GetModule(), nullptr, so_file_spec, cu_id,
eLanguageTypeUnknown, eLazyBoolCalculate);
if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
- // Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
+ SetCompileUnitAtIndex(cu_idx,
+ m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
@@ -625,6 +621,7 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
lldb::LanguageType
SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLanguage(comp_unit);
@@ -632,6 +629,7 @@ SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseFunctions(comp_unit);
@@ -639,6 +637,7 @@ size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseLineTable(comp_unit);
@@ -646,14 +645,24 @@ bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
}
bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseDebugMacros(comp_unit);
return false;
}
+void SymbolFileDWARFDebugMap::ForEachExternalModule(
+ CompileUnit &comp_unit, llvm::function_ref<void(ModuleSP)> f) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
+ if (oso_dwarf)
+ oso_dwarf->ForEachExternalModule(comp_unit, f);
+}
+
bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
@@ -661,6 +670,7 @@ bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
}
bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseIsOptimized(comp_unit);
@@ -669,6 +679,7 @@ bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
bool SymbolFileDWARFDebugMap::ParseImportedModules(
const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseImportedModules(sc, imported_modules);
@@ -676,6 +687,7 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules(
}
size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *comp_unit = func.GetCompileUnit();
if (!comp_unit)
return 0;
@@ -687,6 +699,7 @@ size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
return oso_dwarf->ParseTypes(comp_unit);
@@ -695,6 +708,7 @@ size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
if (oso_dwarf)
return oso_dwarf->ParseVariablesForContext(sc);
@@ -702,6 +716,7 @@ SymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
}
Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf)
@@ -738,8 +753,9 @@ uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
- Symtab *symtab = m_obj_file->GetSymtab();
+ Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
@@ -766,7 +782,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
Address oso_so_addr;
if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
resolved_flags |=
- oso_module->GetSymbolVendor()->ResolveSymbolContext(
+ oso_module->GetSymbolFile()->ResolveSymbolContext(
oso_so_addr, resolve_scope, sc);
}
}
@@ -780,6 +796,7 @@ SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
@@ -807,12 +824,11 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
return sc_list.GetSize() - initial;
}
-uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
+void SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t>
&indexes, // Indexes into the symbol table that match "name"
uint32_t max_matches, VariableList &variables) {
- const uint32_t original_size = variables.GetSize();
const size_t match_count = indexes.size();
for (size_t i = 0; i < match_count; ++i) {
uint32_t oso_idx;
@@ -821,28 +837,26 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
if (comp_unit_info) {
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (oso_dwarf) {
- if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
- variables))
- if (variables.GetSize() > max_matches)
- break;
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ if (variables.GetSize() > max_matches)
+ break;
}
}
}
- return variables.GetSize() - original_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
-
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
- name, parent_decl_ctx, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
+ variables);
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -861,22 +875,18 @@ uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
-uint32_t
-SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
- uint32_t max_matches,
- VariableList &variables) {
- // Remember how many variables are in the list before we search.
- const uint32_t original_size = variables.GetSize();
-
+void SymbolFileDWARFDebugMap::FindGlobalVariables(
+ const RegularExpression &regex, uint32_t max_matches,
+ VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- const uint32_t oso_matches =
- oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+ const uint32_t old_size = variables.GetSize();
+ oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
+
+ const uint32_t oso_matches = variables.GetSize() - old_size;
if (oso_matches > 0) {
total_matches += oso_matches;
@@ -895,9 +905,6 @@ SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
return false;
});
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
}
int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
@@ -993,71 +1000,58 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
}
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(
+void SymbolFileDWARFDebugMap::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
name.GetCString());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
- bool include_inlines,
- bool append,
- SymbolContextList &sc_list) {
+void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
- uint32_t initial_size = 0;
- if (append)
- initial_size = sc_list.GetSize();
- else
- sc_list.Clear();
-
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
uint32_t sc_idx = sc_list.GetSize();
- if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
- RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
+ oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
+ if (!sc_list.IsEmpty()) {
+ RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
});
-
- return sc_list.GetSize() - initial_size;
}
-size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- TypeList &type_list) {
+void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
"SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
type_mask);
- uint32_t initial_size = type_list.GetSize();
SymbolFileDWARF *oso_dwarf = nullptr;
if (sc_scope) {
SymbolContext sc;
@@ -1075,7 +1069,6 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
return false;
});
}
- return type_list.GetSize() - initial_size;
}
std::vector<lldb_private::CallEdge>
@@ -1124,7 +1117,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
// N_SO.
SymbolFileDWARF *oso_dwarf = nullptr;
TypeSP type_sp;
- ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+ ObjectFile *module_objfile = m_objfile_sp->GetModule()->GetObjectFile();
if (module_objfile) {
Symtab *symtab = module_objfile->GetSymtab();
if (symtab) {
@@ -1177,23 +1170,17 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
return TypeSP();
}
-uint32_t SymbolFileDWARFDebugMap::FindTypes(
+void SymbolFileDWARFDebugMap::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- if (!append)
- types.Clear();
-
- const uint32_t initial_types_size = types.GetSize();
-
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
+ oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
return types.GetSize() >= max_matches;
});
-
- return types.GetSize() - initial_types_size;
}
//
@@ -1212,6 +1199,7 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes(
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
lldb_private::ConstString name,
const CompilerDeclContext *parent_decl_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompilerDeclContext matching_namespace;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1284,8 +1272,7 @@ void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
cu_sp.get());
} else {
m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cu_idx, cu_sp);
+ SetCompileUnitAtIndex(cu_idx, cu_sp);
}
}
}
@@ -1388,8 +1375,8 @@ bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
if (addr_module == exe_module)
return true; // Address is already in terms of the main executable module
- CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
- addr_module->GetSymbolVendor()->GetSymbolFile()));
+ CompileUnitInfo *cu_info = GetCompileUnitInfo(
+ GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolFile()));
if (cu_info) {
const lldb::addr_t oso_file_addr = addr.GetFileAddress();
const FileRangeMap::Entry *oso_range_entry =
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index afc6142e8231..7adee1b356ce 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -34,19 +34,16 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileDWARFDebugMap(lldb_private::ObjectFile *ofile);
+ SymbolFileDWARFDebugMap(lldb::ObjectFileSP objfile_sp);
~SymbolFileDWARFDebugMap() override;
uint32_t CalculateAbilities() override;
void InitializeObject() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -56,6 +53,10 @@ public:
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+ void
+ ForEachExternalModule(lldb_private::CompileUnit &comp_unit,
+ llvm::function_ref<void(lldb::ModuleSP)> f) override;
+
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
lldb_private::FileSpecList &support_files) override;
@@ -91,34 +92,34 @@ public:
bool check_inlines,
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
lldb_private::CompilerDeclContext FindNamespace(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
std::vector<lldb_private::CallEdge>
ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
@@ -174,6 +175,9 @@ protected:
// Protected Member Functions
void InitOSO();
+ uint32_t CalculateNumCompileUnits() override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
return (uint32_t)((uid >> 32ull) - 1ull);
}
@@ -232,7 +236,7 @@ protected:
static int SymbolContainsSymbolWithID(lldb::user_id_t *symbol_idx_ptr,
const CompileUnitInfo *comp_unit_info);
- uint32_t PrivateFindGlobalVariables(
+ void PrivateFindGlobalVariables(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t> &name_symbol_indexes, uint32_t max_matches,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index c5b54b65ea29..b0f7e813d4f8 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -23,21 +23,21 @@ using namespace lldb_private;
SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
DWARFCompileUnit &dwarf_cu)
- : SymbolFileDWARF(objfile.get(), objfile->GetSectionList(
- /*update_module_section_list*/ false)),
- m_obj_file_sp(objfile), m_base_dwarf_cu(dwarf_cu) {
+ : SymbolFileDWARF(objfile, objfile->GetSectionList(
+ /*update_module_section_list*/ false)),
+ m_base_dwarf_cu(dwarf_cu) {
SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
}
void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
DWARFDataExtractor &data) {
const SectionList *section_list =
- m_obj_file->GetSectionList(false /* update_module_section_list */);
+ m_objfile_sp->GetSectionList(false /* update_module_section_list */);
if (section_list) {
SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
if (section_sp) {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+ if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
return;
data.Clear();
@@ -140,7 +140,7 @@ SymbolFileDWARFDwo::GetLocationListFormat() const {
return DWARFExpression::SplitDwarfLocationList;
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 9b2f3bb84c4f..ad290cdcf65e 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -30,7 +30,7 @@ public:
size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
DIEArray &method_die_offsets) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
DWARFDIE
@@ -71,7 +71,6 @@ protected:
DWARFCompileUnit *ComputeCompileUnit();
- lldb::ObjectFileSP m_obj_file_sp;
DWARFCompileUnit &m_base_dwarf_cu;
DWARFCompileUnit *m_cu = nullptr;
};
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
new file mode 100644
index 000000000000..ef6ae3498588
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "symbolfiledwarf" in {
+ def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">;
+ def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Ignore indexes present in the object files and always index DWARF manually.">;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 8da7e2226266..4862fea8d079 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -55,6 +55,8 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
case DW_TAG_partial_unit:
done = true;
break;
+ default:
+ break;
}
}
parent_arg_die = parent_arg_die.GetParent();
diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index 1838204e4ca6..830d78f81679 100644
--- a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -130,7 +130,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
if (!stream_data) {
llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, nullptr);
- cci = llvm::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
+ cci = std::make_unique<CompilandIndexItem>(PdbCompilandId{ modi }, debug_stream, std::move(descriptor));
return *cci;
}
@@ -139,7 +139,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
cantFail(debug_stream.reload());
- cci = llvm::make_unique<CompilandIndexItem>(
+ cci = std::make_unique<CompilandIndexItem>(
PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
ParseExtendedInfo(m_index, *cci);
diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3d8bfb058721..6aaff06cc134 100644
--- a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
@@ -247,6 +247,6 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
.take_front(size);
buffer->CopyData(bytes.data(), size);
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
- DWARFExpression result(nullptr, extractor, nullptr, 0, size);
+ DWARFExpression result(nullptr, extractor, nullptr);
return result;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 4991be8e70ce..986b0b785d87 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -121,13 +121,6 @@ AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
return false;
}
-static ClangASTContext &GetClangASTContext(ObjectFile &obj) {
- TypeSystem *ts =
- obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- lldbassert(ts);
- return static_cast<ClangASTContext &>(*ts);
-}
-
static llvm::Optional<clang::CallingConv>
TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
using CC = llvm::codeview::CallingConvention;
@@ -209,8 +202,8 @@ static bool IsAnonymousNamespaceName(llvm::StringRef name) {
return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
}
-PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
- : m_index(index), m_clang(GetClangASTContext(obj)) {
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang)
+ : m_index(index), m_clang(clang) {
BuildParentMap();
}
@@ -465,9 +458,9 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
}
}
-clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
+llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
if (clang::Decl *result = TryGetDecl(uid))
- return result;
+ return ToCompilerDecl(*result);
clang::Decl *result = nullptr;
switch (uid.kind()) {
@@ -480,13 +473,13 @@ clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
result = tag;
break;
}
- return nullptr;
+ return llvm::None;
}
default:
- return nullptr;
+ return llvm::None;
}
m_uid_to_decl[toOpaqueUid(uid)] = result;
- return result;
+ return ToCompilerDecl(*result);
}
clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
@@ -494,8 +487,10 @@ clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
if (uid.asCompilandSym().offset == 0)
return FromCompilerDeclContext(GetTranslationUnitDecl());
}
-
- clang::Decl *decl = GetOrCreateDeclForUid(uid);
+ auto option = GetOrCreateDeclForUid(uid);
+ if (!option)
+ return nullptr;
+ clang::Decl *decl = FromCompilerDecl(option.getValue());
if (!decl)
return nullptr;
@@ -1089,7 +1084,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr());
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
&function_decl, param_name.str().c_str(), param_type_ct,
- clang::SC_None);
+ clang::SC_None, true);
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 67d024741e0d..a4242e90810d 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -51,11 +51,12 @@ struct DeclStatus {
class PdbAstBuilder {
public:
// Constructors and Destructors
- PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
+ PdbAstBuilder(ObjectFile &obj, PdbIndex &index, ClangASTContext &clang);
lldb_private::CompilerDeclContext GetTranslationUnitDecl();
- clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
+ llvm::Optional<lldb_private::CompilerDecl>
+ GetOrCreateDeclForUid(PdbSymUid uid);
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
@@ -76,7 +77,7 @@ public:
CompilerDecl ToCompilerDecl(clang::Decl &decl);
CompilerType ToCompilerType(clang::QualType qt);
CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
- clang::Decl * FromCompilerDecl(CompilerDecl decl);
+ clang::Decl *FromCompilerDecl(CompilerDecl decl);
clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
ClangASTContext &clang() { return m_clang; }
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index 79dd010ff311..a7bc23519710 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -51,54 +51,23 @@ static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::A
return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
}
-static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
- llvm::BumpPtrAllocator &alloc,
- llvm::StringRef &register_name,
- Node *&ast) {
- // lvalue of assignment is always first token
- // rvalue program goes next
- std::tie(register_name, program) = getToken(program);
- if (register_name.empty())
- return false;
-
- ast = Parse(program, alloc);
- return ast != nullptr;
-}
-
-static Node *ParseFPOProgram(llvm::StringRef program,
+static Node *ResolveFPOProgram(llvm::StringRef program,
llvm::StringRef register_name,
llvm::Triple::ArchType arch_type,
llvm::BumpPtrAllocator &alloc) {
- llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
-
- size_t cur = 0;
- while (true) {
- size_t assign_index = program.find('=', cur);
- if (assign_index == llvm::StringRef::npos) {
- llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
- if (!tail.trim().empty()) {
- // missing assign operator
- return nullptr;
- }
- break;
- }
- llvm::StringRef assignment_program = program.slice(cur, assign_index);
-
- llvm::StringRef lvalue_name;
- Node *rvalue_ast = nullptr;
- if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
- rvalue_ast)) {
- return nullptr;
- }
-
- lldbassert(rvalue_ast);
+ std::vector<std::pair<llvm::StringRef, Node *>> parsed =
+ postfix::ParseFPOProgram(program, alloc);
+ for (auto it = parsed.begin(), end = parsed.end(); it != end; ++it) {
// Emplace valid dependent subtrees to make target assignment independent
// from predecessors. Resolve all other SymbolNodes as registers.
bool success =
- ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
- if (Node *node = dependent_programs.lookup(symbol.GetName()))
- return node;
+ ResolveSymbols(it->second, [&](SymbolNode &symbol) -> Node * {
+ for (const auto &pair : llvm::make_range(parsed.begin(), it)) {
+ if (pair.first == symbol.GetName())
+ return pair.second;
+ }
+
uint32_t reg_num =
ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
@@ -110,13 +79,10 @@ static Node *ParseFPOProgram(llvm::StringRef program,
if (!success)
return nullptr;
- if (lvalue_name == register_name) {
+ if (it->first == register_name) {
// found target assignment program - no need to parse further
- return rvalue_ast;
+ return it->second;
}
-
- dependent_programs[lvalue_name] = rvalue_ast;
- cur = assign_index + 1;
}
return nullptr;
@@ -127,7 +93,7 @@ bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
llvm::Triple::ArchType arch_type, Stream &stream) {
llvm::BumpPtrAllocator node_alloc;
Node *target_program =
- ParseFPOProgram(program, register_name, arch_type, node_alloc);
+ ResolveFPOProgram(program, register_name, arch_type, node_alloc);
if (target_program == nullptr) {
return false;
}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 1f5c97da81cf..fc047e25a2f4 100644
--- a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -641,14 +641,14 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
llvm::StringRef program;
if (GetFrameDataProgram(index, ranges, program)) {
result.location =
- MakeVFrameRelLocationExpression(program, loc.Offset, module);
+ MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
} else {
// invalid variable
}
} else {
result.location =
- MakeRegRelLocationExpression(base_reg, loc.Offset, module);
+ MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
result.ranges = std::move(ranges);
}
} else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index e27d4699ae2f..33b8da3b543b 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -20,7 +20,6 @@
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -30,6 +29,7 @@
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Utility/Log.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
@@ -90,10 +90,10 @@ static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
llvm::StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>(
+ auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
std::move(Buffer), llvm::support::little);
- auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
if (auto EC = File->parseFileHeaders()) {
llvm::consumeError(std::move(EC));
return nullptr;
@@ -119,6 +119,8 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
}
OwningBinary<Binary> binary = std::move(*expected_binary);
+ // TODO: Avoid opening the PE/COFF binary twice by reading this information
+ // directly from the lldb_private::ObjectFile.
auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
if (!obj)
return nullptr;
@@ -264,27 +266,27 @@ const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
return "Microsoft PDB debug symbol cross-platform file reader.";
}
-SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileNativePDB(obj_file);
+SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileNativePDB(std::move(objfile_sp));
}
-SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file)
- : SymbolFile(object_file) {}
+SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)) {}
SymbolFileNativePDB::~SymbolFileNativePDB() {}
uint32_t SymbolFileNativePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_index) {
// Lazily load and match the PDB file, but only do this once.
std::unique_ptr<PDBFile> file_up =
- loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator);
+ loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), m_allocator);
if (!file_up) {
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -317,19 +319,24 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
}
void SymbolFileNativePDB::InitializeObject() {
- m_obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ m_obj_load_address = m_objfile_sp->GetBaseAddress().GetFileAddress();
m_index->SetLoadAddress(m_obj_load_address);
m_index->ParseSectionContribs();
- TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage(
+ auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
lldb::eLanguageTypeC_plus_plus);
- if (ts)
- ts->SetSymbolFile(this);
-
- m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index);
+ if (auto err = ts_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Failed to initialize");
+ } else {
+ ts_or_err->SetSymbolFile(this);
+ auto *clang = llvm::cast_or_null<ClangASTContext>(&ts_or_err.get());
+ lldbassert(clang);
+ m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
+ }
}
-uint32_t SymbolFileNativePDB::GetNumCompileUnits() {
+uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
const DbiModuleList &modules = m_index->dbi().modules();
uint32_t count = modules.getModuleCount();
if (count == 0)
@@ -430,11 +437,10 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
FileSpec fs(source_file_name);
CompUnitSP cu_sp =
- std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs,
+ std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
toOpaqueUid(cci.m_id), lang, optimized);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
- cci.m_id.modi, cu_sp);
+ SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
return cu_sp;
}
@@ -730,7 +736,7 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
TypeSP type = CreateAndCacheType(type_id);
if (type)
- m_obj_file->GetModule()->GetTypeList()->Insert(type);
+ GetTypeList().Insert(type);
return type;
}
@@ -900,6 +906,7 @@ lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid(comp_unit.GetID());
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
@@ -915,6 +922,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid uid{comp_unit.GetID()};
lldbassert(uid.kind() == PdbSymUidKind::Compiland);
uint16_t modi = uid.asCompiland().modi;
@@ -948,6 +956,7 @@ static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
uint32_t SymbolFileNativePDB::ResolveSymbolContext(
const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
lldb::addr_t file_addr = addr.GetFileAddress();
@@ -1052,12 +1061,13 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
// all at once, even if all it really needs is line info for a specific
// function. In the future it would be nice if it could set the sc.m_function
// member, and we could only get the line info for the function in question.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
lldbassert(cci);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// This is basically a copy of the .debug$S subsections from all original COFF
// object files merged together with address relocations applied. We are
@@ -1130,6 +1140,7 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
FileSpecList &support_files) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
PdbSymUid cu_id(comp_unit.GetID());
lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
CompilandIndexItem *cci =
@@ -1160,6 +1171,7 @@ bool SymbolFileNativePDB::ParseImportedModules(
}
size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
// FIXME: Parse child blocks
return 1;
@@ -1167,9 +1179,10 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
-uint32_t SymbolFileNativePDB::FindGlobalVariables(
+void SymbolFileNativePDB::FindGlobalVariables(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
@@ -1191,16 +1204,16 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables(
continue;
}
}
- return variables.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(
+void SymbolFileNativePDB::FindFunctions(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// For now we only support lookup by method name.
if (!(name_type_mask & eFunctionNameTypeMethod))
- return 0;
+ return;
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
@@ -1225,45 +1238,34 @@ uint32_t SymbolFileNativePDB::FindFunctions(
sc_list.Append(sc);
}
-
- return sc_list.GetSize();
}
-uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) {
- return 0;
-}
+void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
+ bool include_inlines,
+ SymbolContextList &sc_list) {}
-uint32_t SymbolFileNativePDB::FindTypes(
+void SymbolFileNativePDB::FindTypes(
ConstString name, const CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- if (!append)
- types.Clear();
+ uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
// There is an assumption 'name' is not a regex
- size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types);
-
- return match_count;
+ FindTypesByName(name.GetStringRef(), max_matches, types);
}
-size_t
-SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context,
- bool append, TypeMap &types) {
- return 0;
-}
+void SymbolFileNativePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages, TypeMap &types) {}
-size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
- uint32_t max_matches,
- TypeMap &types) {
+void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
+ uint32_t max_matches,
+ TypeMap &types) {
- size_t match_count = 0;
std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
if (max_matches > 0 && max_matches < matches.size())
matches.resize(max_matches);
@@ -1274,17 +1276,16 @@ size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
continue;
types.Insert(type);
- ++match_count;
}
- return match_count;
}
size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Only do the full type scan the first time.
if (m_done_full_type_scan)
return 0;
- size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t old_count = GetTypeList().GetSize();
LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
// First process the entire TPI stream.
@@ -1314,7 +1315,7 @@ size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
GetOrCreateTypedef(global);
}
- size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ const size_t new_count = GetTypeList().GetSize();
m_done_full_type_scan = true;
@@ -1476,6 +1477,7 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
}
size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert(sc.function || sc.comp_unit);
VariableListSP variables;
@@ -1506,9 +1508,10 @@ size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
}
CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
- clang::Decl *decl = m_ast->GetOrCreateDeclForUid(PdbSymUid(uid));
-
- return m_ast->ToCompilerDecl(*decl);
+ if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
+ return decl.getValue();
+ else
+ return CompilerDecl();
}
CompilerDeclContext
@@ -1528,6 +1531,7 @@ SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
}
Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto iter = m_types.find(type_uid);
// lldb should not be passing us non-sensical type uids. the only way it
// could have a type uid in the first place is if we handed it out, in which
@@ -1561,11 +1565,9 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
return m_ast->CompleteType(qt);
}
-size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
CompilerDeclContext
SymbolFileNativePDB::FindNamespace(ConstString name,
@@ -1573,13 +1575,14 @@ SymbolFileNativePDB::FindNamespace(ConstString name,
return {};
}
-TypeSystem *
+llvm::Expected<TypeSystem &>
SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
ConstString SymbolFileNativePDB::GetPluginName() {
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 20daff219a0a..ca7de0e7d1ed 100644
--- a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -9,7 +9,6 @@
#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/SymbolFile.h"
#include "llvm/ADT/DenseMap.h"
@@ -35,7 +34,6 @@ struct UnionRecord;
} // namespace llvm
namespace lldb_private {
-class ClangASTImporter;
namespace npdb {
class PdbAstBuilder;
@@ -55,10 +53,10 @@ public:
static const char *GetPluginDescriptionStatic();
- static SymbolFile *CreateInstance(ObjectFile *obj_file);
+ static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFileNativePDB(ObjectFile *ofile);
+ SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFileNativePDB() override;
@@ -68,13 +66,9 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
void
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -94,10 +88,10 @@ public:
size_t ParseBlocksRecursive(Function &func) override;
- uint32_t FindGlobalVariables(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t max_matches,
- VariableList &variables) override;
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override;
size_t ParseVariablesForContext(const SymbolContext &sc) override;
@@ -120,28 +114,27 @@ public:
lldb::SymbolContextItem resolve_scope,
SymbolContextList &sc_list) override;
- size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
- TypeList &type_list) override;
+ void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
- uint32_t FindFunctions(ConstString name,
- const CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask,
- bool include_inlines, bool append,
- SymbolContextList &sc_list) override;
+ void FindFunctions(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
- bool append, SymbolContextList &sc_list) override;
+ void FindFunctions(const RegularExpression &regex, bool include_inlines,
+ SymbolContextList &sc_list) override;
- uint32_t FindTypes(ConstString name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
- size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
- TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
+ TypeMap &types) override;
- TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
+ llvm::Expected<TypeSystem &>
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
CompilerDeclContext
FindNamespace(ConstString name,
@@ -157,9 +150,12 @@ public:
void DumpClangAST(Stream &s) override;
private:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches,
- TypeMap &types);
+ void FindTypesByName(llvm::StringRef name, uint32_t max_matches,
+ TypeMap &types);
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id,
const llvm::codeview::ModifierRecord &mr,
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 82cfcfbb040f..47c4ad088494 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -120,24 +120,31 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
return clang_ast.GetBasicType(eBasicTypeBool);
case PDB_BuiltinType::Long:
if (width == ast->getTypeSize(ast->LongTy))
- return CompilerType(ast, ast->LongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->LongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::ULong:
if (width == ast->getTypeSize(ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongTy.getAsOpaquePtr());
if (width == ast->getTypeSize(ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->UnsignedLongLongTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::WCharT:
if (width == ast->getTypeSize(ast->WCharTy))
- return CompilerType(ast, ast->WCharTy);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->WCharTy.getAsOpaquePtr());
break;
case PDB_BuiltinType::Char16:
- return CompilerType(ast, ast->Char16Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char16Ty.getAsOpaquePtr());
case PDB_BuiltinType::Char32:
- return CompilerType(ast, ast->Char32Ty);
+ return CompilerType(ClangASTContext::GetASTContext(ast),
+ ast->Char32Ty.getAsOpaquePtr());
case PDB_BuiltinType::Float:
// Note: types `long double` and `double` have same bit size in MSVC and
// there is no information in the PDB to distinguish them. So when falling
@@ -940,7 +947,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
decl, nullptr, arg_type->GetForwardCompilerType(),
- clang::SC_None);
+ clang::SC_None, true);
if (param)
params.push_back(param);
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 1c17bf6563b3..42bf1b34c956 100644
--- a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -174,7 +174,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(
DataBufferSP buffer =
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
- DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ DWARFExpression result(module, extractor, nullptr);
result.SetRegisterKind(register_kind);
return result;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 17dfcdaceb9c..854e735b5f83 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -24,6 +24,7 @@
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
@@ -118,29 +119,28 @@ const char *SymbolFilePDB::GetPluginDescriptionStatic() {
}
lldb_private::SymbolFile *
-SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
- return new SymbolFilePDB(obj_file);
+SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFilePDB(std::move(objfile_sp));
}
-SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
- : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
- m_cached_compile_unit_count(0) {}
+SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
SymbolFilePDB::~SymbolFilePDB() {}
uint32_t SymbolFilePDB::CalculateAbilities() {
uint32_t abilities = 0;
- if (!m_obj_file)
+ if (!m_objfile_sp)
return 0;
if (!m_session_up) {
// Lazily load and match the PDB file, but only do this once.
- std::string exePath = m_obj_file->GetFileSpec().GetPath();
+ std::string exePath = m_objfile_sp->GetFileSpec().GetPath();
auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
m_session_up);
if (error) {
llvm::consumeError(std::move(error));
- auto module_sp = m_obj_file->GetModule();
+ auto module_sp = m_objfile_sp->GetModule();
if (!module_sp)
return 0;
// See if any symbol file is specified through `--symfile` option.
@@ -183,7 +183,8 @@ uint32_t SymbolFilePDB::CalculateAbilities() {
}
void SymbolFilePDB::InitializeObject() {
- lldb::addr_t obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress();
+ lldb::addr_t obj_load_address =
+ m_objfile_sp->GetBaseAddress().GetFileAddress();
lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
m_session_up->setLoadAddress(obj_load_address);
if (!m_global_scope_up)
@@ -191,33 +192,30 @@ void SymbolFilePDB::InitializeObject() {
lldbassert(m_global_scope_up.get());
}
-uint32_t SymbolFilePDB::GetNumCompileUnits() {
- if (m_cached_compile_unit_count == 0) {
- auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
- if (!compilands)
- return 0;
+uint32_t SymbolFilePDB::CalculateNumCompileUnits() {
+ auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
+ if (!compilands)
+ return 0;
- // The linker could link *.dll (compiland language = LINK), or import
- // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
- // found as a child of the global scope (PDB executable). Usually, such
- // compilands contain `thunk` symbols in which we are not interested for
- // now. However we still count them in the compiland list. If we perform
- // any compiland related activity, like finding symbols through
- // llvm::pdb::IPDBSession methods, such compilands will all be searched
- // automatically no matter whether we include them or not.
- m_cached_compile_unit_count = compilands->getChildCount();
-
- // The linker can inject an additional "dummy" compilation unit into the
- // PDB. Ignore this special compile unit for our purposes, if it is there.
- // It is always the last one.
- auto last_compiland_up =
- compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
- lldbassert(last_compiland_up.get());
- std::string name = last_compiland_up->getName();
- if (name == "* Linker *")
- --m_cached_compile_unit_count;
- }
- return m_cached_compile_unit_count;
+ // The linker could link *.dll (compiland language = LINK), or import
+ // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
+ // found as a child of the global scope (PDB executable). Usually, such
+ // compilands contain `thunk` symbols in which we are not interested for
+ // now. However we still count them in the compiland list. If we perform
+ // any compiland related activity, like finding symbols through
+ // llvm::pdb::IPDBSession methods, such compilands will all be searched
+ // automatically no matter whether we include them or not.
+ uint32_t compile_unit_count = compilands->getChildCount();
+
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB. Ignore this special compile unit for our purposes, if it is there.
+ // It is always the last one.
+ auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1);
+ lldbassert(last_compiland_up.get());
+ std::string name = last_compiland_up->getName();
+ if (name == "* Linker *")
+ --compile_unit_count;
+ return compile_unit_count;
}
void SymbolFilePDB::GetCompileUnitIndex(
@@ -261,6 +259,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
}
lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return lldb::eLanguageTypeUnknown;
@@ -302,11 +301,15 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
comp_unit.AddFunction(func_sp);
LanguageType lang = ParseLanguage(comp_unit);
- TypeSystem *type_system = GetTypeSystemForLanguage(lang);
- if (!type_system)
+ auto type_system_or_err = GetTypeSystemForLanguage(lang);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse PDBFunc");
return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
@@ -315,6 +318,7 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
}
size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t func_added = 0;
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
@@ -333,6 +337,7 @@ size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
}
bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (comp_unit.GetLineTable())
return true;
return ParseCompileUnitLineTable(comp_unit, 0);
@@ -351,6 +356,7 @@ bool SymbolFilePDB::ParseSupportFiles(
// second time seems like a waste. Unfortunately, there's no good way around
// this short of a moderate refactor since SymbolVendor depends on being able
// to cache this list.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return false;
@@ -428,6 +434,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
}
size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto uid = func.GetID();
auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
@@ -440,6 +447,7 @@ size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
}
size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
@@ -492,6 +500,7 @@ size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
size_t
SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!sc.comp_unit)
return 0;
@@ -540,14 +549,21 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
}
lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
auto find_result = m_types.find(type_uid);
if (find_result != m_types.end())
return find_result->second.get();
- TypeSystem *type_system =
+ auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to ResolveTypeUID");
+ return nullptr;
+ }
+
ClangASTContext *clang_type_system =
- llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
PDBASTParser *pdb = clang_type_system->GetPDBParser();
@@ -561,9 +577,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
if (result) {
m_types.insert(std::make_pair(type_uid, result));
- auto type_list = GetTypeList();
- if (type_list)
- type_list->Insert(result);
+ GetTypeList().Insert(result);
}
return result.get();
}
@@ -577,8 +591,17 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
std::lock_guard<std::recursive_mutex> guard(
GetObjectFile()->GetModule()->GetMutex());
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get dynamic array info for UID");
+ return false;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+
if (!clang_ast_ctx)
return false;
@@ -590,8 +613,16 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
}
lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get decl for UID");
+ return CompilerDecl();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDecl();
@@ -612,8 +643,16 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext for UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -634,8 +673,16 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get DeclContext containing UID");
+ return CompilerDeclContext();
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return CompilerDeclContext();
@@ -655,8 +702,16 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
void SymbolFilePDB::ParseDeclsForContext(
lldb_private::CompilerDeclContext decl_ctx) {
- ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
- GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to parse decls for context");
+ return;
+ }
+
+ ClangASTContext *clang_ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_ctx)
return;
@@ -672,6 +727,7 @@ uint32_t
SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextCompUnit ||
resolve_scope & eSymbolContextVariable ||
@@ -680,7 +736,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
resolve_scope & eSymbolContextLineEntry) {
auto cu_sp = GetCompileUnitContainsAddress(so_addr);
if (!cu_sp) {
- if (resolved_flags | eSymbolContextVariable) {
+ if (resolved_flags & eSymbolContextVariable) {
// TODO: Resolve variables
}
return 0;
@@ -732,6 +788,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
uint32_t SymbolFilePDB::ResolveSymbolContext(
const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const size_t old_size = sc_list.GetSize();
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
@@ -1040,18 +1097,19 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
return num_added;
}
-uint32_t SymbolFilePDB::FindGlobalVariables(
+void SymbolFilePDB::FindGlobalVariables(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches, lldb_private::VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1061,7 +1119,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
break;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
if (!name.GetStringRef().equals(
@@ -1080,19 +1138,17 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
-uint32_t
-SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) {
+void SymbolFilePDB::FindGlobalVariables(
+ const lldb_private::RegularExpression &regex, uint32_t max_matches,
+ lldb_private::VariableList &variables) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
- return 0;
+ return;
uint32_t matches = 0;
size_t old_size = variables.GetSize();
@@ -1106,7 +1162,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
if (!regex.Execute(var_name))
continue;
SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
+ sc.module_sp = m_objfile_sp->GetModule();
lldbassert(sc.module_sp.get());
sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
@@ -1117,8 +1173,6 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
-
- return matches;
}
bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
@@ -1240,23 +1294,21 @@ void SymbolFilePDB::CacheFunctionNames() {
m_func_base_names.SizeToFit();
}
-uint32_t SymbolFilePDB::FindFunctions(
+void SymbolFilePDB::FindFunctions(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- FunctionNameType name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines,
lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
if (name_type_mask == eFunctionNameTypeNone)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
if (name.IsEmpty())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
if (name_type_mask & eFunctionNameTypeFull ||
name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod) {
@@ -1286,26 +1338,20 @@ uint32_t SymbolFilePDB::FindFunctions(
ResolveFn(m_func_base_names);
ResolveFn(m_func_method_names);
}
- if (name_type_mask & eFunctionNameTypeBase) {
+ if (name_type_mask & eFunctionNameTypeBase)
ResolveFn(m_func_base_names);
- }
- if (name_type_mask & eFunctionNameTypeMethod) {
+ if (name_type_mask & eFunctionNameTypeMethod)
ResolveFn(m_func_method_names);
- }
}
- return sc_list.GetSize() - old_size;
}
-uint32_t
-SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) {
- if (!append)
- sc_list.Clear();
+void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!regex.IsValid())
- return 0;
+ return;
- auto old_size = sc_list.GetSize();
CacheFunctionNames();
std::set<uint32_t> resolved_ids;
@@ -1322,8 +1368,6 @@ SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
};
ResolveFn(m_func_full_names);
ResolveFn(m_func_base_names);
-
- return sc_list.GetSize() - old_size;
}
void SymbolFilePDB::GetMangledNamesForFunction(
@@ -1339,7 +1383,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
if (!results)
return;
- auto section_list = m_obj_file->GetSectionList();
+ auto section_list = m_objfile_sp->GetSectionList();
if (!section_list)
return;
@@ -1361,7 +1405,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.AddSymbol(
Symbol(pub_symbol->getSymIndexId(), // symID
pub_symbol->getName().c_str(), // name
- true, // name_is_mangled
pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
true, // external
false, // is_debug
@@ -1380,34 +1423,39 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.Finalize();
}
-uint32_t SymbolFilePDB::FindTypes(
+void SymbolFilePDB::FindTypes(
lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) {
- if (!append)
- types.Clear();
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
if (!name)
- return 0;
+ return;
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
+ return;
searched_symbol_files.clear();
searched_symbol_files.insert(this);
// There is an assumption 'name' is not a regex
FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
-
- return types.GetSize();
}
void SymbolFilePDB::DumpClangAST(Stream &s) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang)
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to dump ClangAST");
+ return;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
+ if (!clang_type_system)
return;
- clang->Dump(s);
+ clang_type_system->Dump(s);
}
void SymbolFilePDB::FindTypesByRegex(
@@ -1514,15 +1562,9 @@ void SymbolFilePDB::FindTypesByName(
}
}
-size_t SymbolFilePDB::FindTypes(
- const std::vector<lldb_private::CompilerContext> &contexts, bool append,
- lldb_private::TypeMap &types) {
- return 0;
-}
-
-lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
- return m_obj_file->GetModule()->GetTypeList();
-}
+void SymbolFilePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+ LanguageSet languages,
+ lldb_private::TypeMap &types) {}
void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
uint32_t type_mask,
@@ -1574,17 +1616,17 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
}
-size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
+void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
TypeCollection type_collection;
- uint32_t old_size = type_list.GetSize();
CompileUnit *cu =
sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
if (cu) {
auto compiland_up = GetPDBCompilandByUID(cu->GetID());
if (!compiland_up)
- return 0;
+ return;
GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
} else {
for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
@@ -1600,21 +1642,29 @@ size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
type->GetForwardCompilerType();
type_list.Insert(type->shared_from_this());
}
- return type_list.GetSize() - old_size;
}
-lldb_private::TypeSystem *
+llvm::Expected<lldb_private::TypeSystem &>
SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
- auto type_system =
- m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- return type_system;
+ auto type_system_or_err =
+ m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system_or_err) {
+ type_system_or_err->SetSymbolFile(this);
+ }
+ return type_system_or_err;
}
PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to get PDB AST parser");
+ return nullptr;
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return nullptr;
@@ -1625,8 +1675,18 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) {
- auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
- auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ auto type_system_or_err =
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err), "Unable to find namespace {}",
+ name.AsCString());
+ return CompilerDeclContext();
+ }
+
+ auto *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get());
if (!clang_type_system)
return CompilerDeclContext();
@@ -1644,7 +1704,7 @@ lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
if (!namespace_decl)
return CompilerDeclContext();
- return CompilerDeclContext(type_system,
+ return CompilerDeclContext(clang_type_system,
static_cast<clang::DeclContext *>(namespace_decl));
}
@@ -1688,7 +1748,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
// Don't support optimized code for now, DebugInfoPDB does not return this
// information.
LazyBool optimized = eLazyBoolNo;
- auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
+ auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
path.c_str(), id, lang, optimized);
if (!cu_sp)
@@ -1698,8 +1758,7 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
if (index == UINT32_MAX)
GetCompileUnitIndex(*compiland_up, index);
lldbassert(index != UINT32_MAX);
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
- cu_sp);
+ SetCompileUnitAtIndex(index, cu_sp);
return cu_sp;
}
@@ -1715,7 +1774,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
// to do a mapping so that we can hand out indices.
llvm::DenseMap<uint32_t, uint32_t> index_map;
BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
- auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+ auto line_table = std::make_unique<LineTable>(&comp_unit);
// Find contributions to `compiland` from all source and header files.
std::string path = comp_unit.GetPath();
@@ -1925,9 +1984,17 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
if (!decl_ctx_type_system)
return false;
- TypeSystem *type_system = GetTypeSystemForLanguage(
+ auto type_system_or_err = GetTypeSystemForLanguage(
decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
+ std::move(err),
+ "Unable to determine if DeclContext matches this symbol file");
+ return false;
+ }
+
+ if (decl_ctx_type_system == &type_system_or_err.get())
return true; // The type systems match, return true
return false;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index ba3099aaec4d..df717bbbbdb0 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -35,10 +35,10 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
// Constructors and Destructors
- SymbolFilePDB(lldb_private::ObjectFile *ofile);
+ SymbolFilePDB(lldb::ObjectFileSP objfile_sp);
~SymbolFilePDB() override;
@@ -48,10 +48,6 @@ public:
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -103,25 +99,25 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
- uint32_t
+ void
FindGlobalVariables(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
uint32_t max_matches,
lldb_private::VariableList &variables) override;
- uint32_t FindGlobalVariables(const lldb_private::RegularExpression &regex,
- uint32_t max_matches,
- lldb_private::VariableList &variables) override;
+ void FindGlobalVariables(const lldb_private::RegularExpression &regex,
+ uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- lldb::FunctionNameType name_type_mask, bool include_inlines,
- bool append, lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(lldb_private::ConstString name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
- bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ void FindFunctions(const lldb_private::RegularExpression &regex,
+ bool include_inlines,
+ lldb_private::SymbolContextList &sc_list) override;
void GetMangledNamesForFunction(
const std::string &scope_qualified_name,
@@ -129,26 +125,25 @@ public:
void AddSymbols(lldb_private::Symtab &symtab) override;
- uint32_t
+ void
FindTypes(lldb_private::ConstString name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append, uint32_t max_matches,
+ uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
- size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
- bool append, lldb_private::TypeMap &types) override;
+ void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
+ lldb_private::LanguageSet languages,
+ lldb_private::TypeMap &types) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
- lldb_private::TypeList *GetTypeList() override;
-
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
+ llvm::Expected<lldb_private::TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
@@ -173,6 +168,10 @@ private:
};
using SecContribsMap = std::map<uint32_t, std::vector<SecContribInfo>>;
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
uint32_t index = UINT32_MAX);
@@ -245,7 +244,6 @@ private:
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
std::unique_ptr<llvm::pdb::PDBSymbolExe> m_global_scope_up;
- uint32_t m_cached_compile_unit_count;
lldb_private::UniqueCStringMap<uint32_t> m_func_full_names;
lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index a1b21e51b0fe..62da76581c3e 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -43,26 +43,24 @@ const char *SymbolFileSymtab::GetPluginDescriptionStatic() {
return "Reads debug symbols from an object file's symbol table.";
}
-SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
- return new SymbolFileSymtab(obj_file);
+SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFileSP objfile_sp) {
+ return new SymbolFileSymtab(std::move(objfile_sp));
}
-size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
- TypeClass type_mask,
- lldb_private::TypeList &type_list) {
- return 0;
-}
+void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {}
-SymbolFileSymtab::SymbolFileSymtab(ObjectFile *obj_file)
- : SymbolFile(obj_file), m_source_indexes(), m_func_indexes(),
+SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
+ : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(),
m_code_indexes(), m_objc_class_name_to_index() {}
SymbolFileSymtab::~SymbolFileSymtab() {}
uint32_t SymbolFileSymtab::CalculateAbilities() {
uint32_t abilities = 0;
- if (m_obj_file) {
- const Symtab *symtab = m_obj_file->GetSymtab();
+ if (m_objfile_sp) {
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
if (symtab) {
// The snippet of code below will get the indexes the module symbol table
// entries that are code, data, or function related (debug info), sort
@@ -104,7 +102,7 @@ uint32_t SymbolFileSymtab::CalculateAbilities() {
return abilities;
}
-uint32_t SymbolFileSymtab::GetNumCompileUnits() {
+uint32_t SymbolFileSymtab::CalculateNumCompileUnits() {
// If we don't have any source file symbols we will just have one compile
// unit for the entire object file
if (m_source_indexes.empty())
@@ -122,10 +120,10 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
// unit for the entire object file
if (idx < m_source_indexes.size()) {
const Symbol *cu_symbol =
- m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+ m_objfile_sp->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
- cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
- cu_symbol->GetName().AsCString(), 0,
+ cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
+ cu_symbol->GetName().AsCString(), 0,
eLanguageTypeUnknown, eLazyBoolNo);
}
return cu_sp;
@@ -136,12 +134,13 @@ lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
}
size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
size_t num_added = 0;
// We must at least have a valid compile unit
- const Symtab *symtab = m_obj_file->GetSymtab();
+ const Symtab *symtab = m_objfile_sp->GetSymtab();
const Symbol *curr_symbol = nullptr;
const Symbol *next_symbol = nullptr;
- // const char *prefix = m_obj_file->SymbolPrefix();
+ // const char *prefix = m_objfile_sp->SymbolPrefix();
// if (prefix == NULL)
// prefix == "";
//
@@ -246,12 +245,13 @@ bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
- if (m_obj_file->GetSymtab() == nullptr)
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (m_objfile_sp->GetSymtab() == nullptr)
return 0;
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextSymbol) {
- sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(
+ sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
so_addr.GetFileAddress());
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index bc9a531419ae..2ac4660f0125 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -18,7 +18,7 @@
class SymbolFileSymtab : public lldb_private::SymbolFile {
public:
// Constructors and Destructors
- SymbolFileSymtab(lldb_private::ObjectFile *obj_file);
+ SymbolFileSymtab(lldb::ObjectFileSP objfile_sp);
~SymbolFileSymtab() override;
@@ -32,15 +32,11 @@ public:
static const char *GetPluginDescriptionStatic();
static lldb_private::SymbolFile *
- CreateInstance(lldb_private::ObjectFile *obj_file);
+ CreateInstance(lldb::ObjectFileSP objfile_sp);
uint32_t CalculateAbilities() override;
// Compile Unit function calls
- uint32_t GetNumCompileUnits() override;
-
- lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
-
lldb::LanguageType
ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
@@ -75,9 +71,9 @@ public:
lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
- size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- lldb::TypeClass type_mask,
- lldb_private::TypeList &type_list) override;
+ void GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ lldb::TypeClass type_mask,
+ lldb_private::TypeList &type_list) override;
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -85,6 +81,10 @@ public:
uint32_t GetPluginVersion() override;
protected:
+ uint32_t CalculateNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap;
lldb_private::Symtab::IndexCollection m_source_indexes;