From: Zachary Turner Date: Fri, 16 Nov 2018 02:42:32 +0000 (+0000) Subject: [NativePDB] Rewrite the PdbSymUid to use our own custom namespacing scheme. X-Git-Tag: llvmorg-8.0.0-rc1~4145 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6284aee9f811d596b941e44b30dee5befbc22f20;p=platform%2Fupstream%2Fllvm.git [NativePDB] Rewrite the PdbSymUid to use our own custom namespacing scheme. Originally we created our 64-bit UID scheme by using the first byte as sort of a "tag" to represent what kind of symbol this was, and we re-used the PDB_SymType enumeration for this. For native pdb support, this is not really the right abstraction layer, because what we really want is something that tells us *how* to find the symbol. This means, specifically, is in the globals stream / public stream / module stream / TPI stream / etc, and for whichever one it is in, where is it within that stream? A good example of why the old namespacing scheme was insufficient is that it is more or less impossible to create a uid for a field list member of a class/struction/union/enum that tells you how to locate the original record. With this new scheme, the first byte is no longer a PDB_SymType enum but a new enum created specifically to identify where in the PDB this record lives. This gives us much better flexibility in what kinds of symbols the uids can identify. llvm-svn: 347018 --- diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt index c463cd8..e9f792d 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN CompileUnitIndex.cpp PdbIndex.cpp + PdbSymUid.cpp PdbUtil.cpp SymbolFileNativePDB.cpp UdtRecordCompleter.cpp diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index b4725e5..68d8ded 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -108,26 +108,19 @@ static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) { } CompilandIndexItem::CompilandIndexItem( - PdbSymUid uid, llvm::pdb::ModuleDebugStreamRef debug_stream, + PdbCompilandId id, llvm::pdb::ModuleDebugStreamRef debug_stream, llvm::pdb::DbiModuleDescriptor descriptor) - : m_uid(uid), m_debug_stream(std::move(debug_stream)), + : m_id(id), m_debug_stream(std::move(debug_stream)), m_module_descriptor(std::move(descriptor)) {} CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { - PdbSymUid uid = PdbSymUid::makeCompilandId(modi); - return GetOrCreateCompiland(uid); -} - -CompilandIndexItem & -CompileUnitIndex::GetOrCreateCompiland(PdbSymUid compiland_uid) { - auto result = m_comp_units.try_emplace(compiland_uid.toOpaqueId(), nullptr); + auto result = m_comp_units.try_emplace(modi, nullptr); if (!result.second) return *result.first->second; // Find the module list and load its debug information stream and cache it // since we need to use it for almost all interesting operations. const DbiModuleList &modules = m_index.dbi().modules(); - uint16_t modi = compiland_uid.asCompiland().modi; llvm::pdb::DbiModuleDescriptor descriptor = modules.getModuleDescriptor(modi); uint16_t stream = descriptor.getModuleStreamIndex(); std::unique_ptr stream_data = @@ -139,7 +132,7 @@ CompileUnitIndex::GetOrCreateCompiland(PdbSymUid compiland_uid) { std::unique_ptr &cci = result.first->second; cci = llvm::make_unique( - compiland_uid, std::move(debug_stream), std::move(descriptor)); + PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor)); ParseExtendedInfo(m_index, *cci); cci->m_strings.initialize(debug_stream.getSubsectionsArray()); @@ -172,23 +165,14 @@ CompileUnitIndex::GetOrCreateCompiland(PdbSymUid compiland_uid) { } const CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) const { - return GetCompiland(PdbSymUid::makeCompilandId(modi)); -} - -const CompilandIndexItem * -CompileUnitIndex::GetCompiland(PdbSymUid compiland_uid) const { - auto iter = m_comp_units.find(compiland_uid.toOpaqueId()); + auto iter = m_comp_units.find(modi); if (iter == m_comp_units.end()) return nullptr; return iter->second.get(); } CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) { - return GetCompiland(PdbSymUid::makeCompilandId(modi)); -} - -CompilandIndexItem *CompileUnitIndex::GetCompiland(PdbSymUid compiland_uid) { - auto iter = m_comp_units.find(compiland_uid.toOpaqueId()); + auto iter = m_comp_units.find(modi); if (iter == m_comp_units.end()) return nullptr; return iter->second.get(); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index 54c40a0..c965870 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -36,12 +36,12 @@ class PdbIndex; /// parts of the PDB into a single place, simplifying acess to compile unit /// information for the callers. struct CompilandIndexItem { - CompilandIndexItem(PdbSymUid uid, + CompilandIndexItem(PdbCompilandId m_id, llvm::pdb::ModuleDebugStreamRef debug_stream, llvm::pdb::DbiModuleDescriptor descriptor); - // uid of this compile unit. - PdbSymUid m_uid; + // index of this compile unit. + PdbCompilandId m_id; // debug stream. llvm::pdb::ModuleDebugStreamRef m_debug_stream; @@ -76,20 +76,16 @@ struct CompilandIndexItem { /// global compile unit index to |CompilandIndexItem| structures. class CompileUnitIndex { PdbIndex &m_index; - llvm::DenseMap> - m_comp_units; + llvm::DenseMap> m_comp_units; public: explicit CompileUnitIndex(PdbIndex &index) : m_index(index) {} CompilandIndexItem &GetOrCreateCompiland(uint16_t modi); - CompilandIndexItem &GetOrCreateCompiland(PdbSymUid compiland_uid); const CompilandIndexItem *GetCompiland(uint16_t modi) const; - const CompilandIndexItem *GetCompiland(PdbSymUid compiland_uid) const; CompilandIndexItem *GetCompiland(uint16_t modi); - CompilandIndexItem *GetCompiland(PdbSymUid compiland_uid); llvm::SmallString<64> GetMainSourceFile(const CompilandIndexItem &item) const; }; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index cda9508..4650472 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -122,7 +122,7 @@ void PdbIndex::ParseSectionContribs() { void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { lldbassert(cci.m_symbols_by_va.empty() && "Addr to symbol map is already built!"); - uint16_t modi = cci.m_uid.asCompiland().modi; + uint16_t modi = cci.m_id.modi; const CVSymbolArray &syms = cci.m_debug_stream.getSymbolArray(); for (auto iter = syms.begin(); iter != syms.end(); ++iter) { if (!SymbolHasAddress(*iter)) @@ -134,14 +134,13 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { // We need to add 4 here to adjust for the codeview debug magic // at the beginning of the debug info stream. uint32_t sym_offset = iter.offset() + 4; - PdbSymUid cu_sym_uid = - PdbSymUid::makeCuSymId(CVSymToPDBSym(iter->kind()), modi, sym_offset); + PdbCompilandSymId cu_sym_id{modi, sym_offset}; // If the debug info is incorrect, we could have multiple symbols with the // same address. So use try_emplace instead of insert, and the first one // will win. auto insert_result = - cci.m_symbols_by_va.insert(std::make_pair(va, cu_sym_uid)); + cci.m_symbols_by_va.insert(std::make_pair(va, PdbSymUid(cu_sym_id))); (void)insert_result; // The odds of an error in some function such as GetSegmentAndOffset or @@ -180,7 +179,7 @@ std::vector PdbIndex::FindSymbolsByVa(lldb::addr_t va) { auto ub = cci.m_symbols_by_va.upper_bound(va); for (auto iter = cci.m_symbols_by_va.begin(); iter != ub; ++iter) { - const PdbCuSymId &cu_sym_id = iter->second.asCuSym(); + PdbCompilandSymId cu_sym_id = iter->second.asCompilandSym(); CVSymbol sym = ReadSymbolRecord(cu_sym_id); SegmentOffsetLength sol; @@ -198,11 +197,10 @@ std::vector PdbIndex::FindSymbolsByVa(lldb::addr_t va) { return result; } -CVSymbol PdbIndex::ReadSymbolRecord(PdbCuSymId cu_sym) const { +CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const { // We need to subtract 4 here to adjust for the codeview debug magic // at the beginning of the debug info stream. - PdbSymUid cuid = PdbSymUid::makeCompilandId(cu_sym.modi); - const CompilandIndexItem *cci = compilands().GetCompiland(cuid); + const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi); auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset - 4); lldbassert(iter != cci->m_debug_stream.getSymbolArray().end()); return *iter; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index ee03f30..e1a0bb8 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -149,7 +149,7 @@ public: std::vector FindSymbolsByVa(lldb::addr_t va); - llvm::codeview::CVSymbol ReadSymbolRecord(PdbCuSymId cu_sym) const; + llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const; llvm::Optional GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp new file mode 100644 index 0000000..e542456 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp @@ -0,0 +1,161 @@ +//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PdbSymUid.h" + +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; + +namespace { +struct GenericIdRepr { + uint64_t tag : 4; + uint64_t data : 60; +}; + +struct CompilandIdRepr { + uint64_t tag : 4; + uint64_t modi : 16; + uint64_t unused : 44; +}; + +struct CompilandSymIdRepr { + uint64_t tag : 4; + uint64_t modi : 16; + uint64_t offset : 32; + uint64_t unused : 12; +}; + +struct GlobalSymIdRepr { + uint64_t tag : 4; + uint64_t offset : 32; + uint64_t pub : 1; + uint64_t unused : 27; +}; + +struct TypeSymIdRepr { + uint64_t tag : 4; + uint64_t index : 32; + uint64_t ipi : 1; + uint64_t unused : 27; +}; + +struct FieldListMemberIdRepr { + uint64_t tag : 4; + uint64_t index : 32; + uint64_t offset : 16; + uint64_t unused : 12; +}; + +static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!"); +} // namespace + +template static OutT repr_cast(const InT &value) { + OutT result; + ::memcpy(&result, &value, sizeof(value)); + return result; +} + +PdbSymUid::PdbSymUid(const PdbCompilandId &cid) { + CompilandIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.modi = cid.modi; + repr.tag = static_cast(PdbSymUidKind::Compiland); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) { + CompilandSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.modi = csid.modi; + repr.offset = csid.offset; + repr.tag = static_cast(PdbSymUidKind::CompilandSym); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) { + GlobalSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.pub = gsid.is_public; + repr.offset = gsid.offset; + repr.tag = static_cast(PdbSymUidKind::GlobalSym); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) { + TypeSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.index = tsid.index.getIndex(); + repr.ipi = tsid.is_ipi; + repr.tag = static_cast(PdbSymUidKind::Type); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) { + FieldListMemberIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.index = flmid.index.getIndex(); + repr.offset = flmid.offset; + repr.tag = static_cast(PdbSymUidKind::FieldListMember); + m_repr = repr_cast(repr); +} + +PdbSymUidKind PdbSymUid::kind() const { + GenericIdRepr generic = repr_cast(m_repr); + return static_cast(generic.tag); +} + +PdbCompilandId PdbSymUid::asCompiland() const { + assert(kind() == PdbSymUidKind::Compiland); + auto repr = repr_cast(m_repr); + PdbCompilandId result; + result.modi = repr.modi; + return result; +} + +PdbCompilandSymId PdbSymUid::asCompilandSym() const { + assert(kind() == PdbSymUidKind::CompilandSym); + auto repr = repr_cast(m_repr); + PdbCompilandSymId result; + result.modi = repr.modi; + result.offset = repr.offset; + return result; +} + +PdbGlobalSymId PdbSymUid::asGlobalSym() const { + assert(kind() == PdbSymUidKind::GlobalSym || + kind() == PdbSymUidKind::PublicSym); + auto repr = repr_cast(m_repr); + PdbGlobalSymId result; + result.is_public = repr.pub; + result.offset = repr.offset; + return result; +} + +PdbTypeSymId PdbSymUid::asTypeSym() const { + assert(kind() == PdbSymUidKind::Type); + auto repr = repr_cast(m_repr); + PdbTypeSymId result; + result.index.setIndex(repr.index); + result.is_ipi = repr.ipi; + return result; +} + +PdbFieldListMemberId PdbSymUid::asFieldListMember() const { + assert(kind() == PdbSymUidKind::FieldListMember); + auto repr = repr_cast(m_repr); + PdbFieldListMemberId result; + result.index.setIndex(repr.index); + result.offset = repr.offset; + return result; +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h index f43e0f9..4794c5b 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h @@ -28,189 +28,82 @@ namespace lldb_private { namespace npdb { -// **important** - All concrete id types must have the 1-byte tag field at -// the beginning so that the types are all layout-compatible with each -// other, which is necessary in order to be able to safely access the tag -// member through any union member. +enum class PdbSymUidKind : uint8_t { + Compiland, + CompilandSym, + PublicSym, + GlobalSym, + Type, + FieldListMember +}; + struct PdbCompilandId { - uint64_t tag : 8; // PDB_SymType::Compiland - uint64_t modi : 16; // 0-based index of module in PDB - uint64_t unused : 32; + // 0-based index of module in PDB + uint16_t modi; +}; + +struct PdbCompilandSymId { + // 0-based index of module in PDB + uint16_t modi = 0; + + // Offset of symbol's record in module stream. This is + // offset by 4 from the CVSymbolArray's notion of offset + // due to the debug magic at the beginning of the stream. + uint32_t offset = 0; }; -struct PdbCuSymId { - uint64_t tag : 8; // PDB_SymType::Data, Function, Block, etc. - uint64_t - offset : 30; // Offset of symbol's record in module stream. This is - // offset by 4 from the CVSymbolArray's notion of offset - // due to the debug magic at the beginning of the stream. - uint64_t global : 1; // True if this is from the globals stream. - uint64_t unused : 1; - uint64_t modi : 16; // For non-global, this is the 0-based index of module. + +struct PdbGlobalSymId { + // Offset of symbol's record in globals or publics stream. + uint32_t offset = 0; + + // True if this symbol is in the public stream, false if it's in the globals + // stream. + bool is_public = false; }; struct PdbTypeSymId { - uint64_t tag : 8; // PDB_SymType::FunctionSig, Enum, PointerType, etc. - uint64_t is_ipi : 8; // 1 if this value is from the IPI stream, 0 for TPI. - uint64_t unused : 16; - uint64_t index : 32; // codeview::TypeIndex + // The index of the of the type in the TPI or IPI stream. + llvm::codeview::TypeIndex index; + + // True if this symbol comes from the IPI stream, false if it's from the TPI + // stream. + bool is_ipi = false; }; -static_assert(sizeof(PdbCompilandId) == 8, "invalid uid size"); -static_assert(sizeof(PdbCuSymId) == 8, "invalid uid size"); -static_assert(std::is_standard_layout::value, - "type is not standard layout!"); -static_assert(std::is_standard_layout::value, - "type is not standard layout!"); +struct PdbFieldListMemberId { + // The TypeIndex of the LF_FIELDLIST record. + llvm::codeview::TypeIndex index; -class PdbSymUid { - union { - PdbCompilandId comp_id; - PdbCuSymId cu_sym; - PdbTypeSymId type_sym; - } m_uid; + // The offset from the beginning of the LF_FIELDLIST record to this record. + uint16_t offset = 0; +}; - PdbSymUid() { ::memset(&m_uid, 0, sizeof(m_uid)); } +class PdbSymUid { + uint64_t m_repr = 0; public: - static bool isTypeSym(llvm::pdb::PDB_SymType tag) { - switch (tag) { - case llvm::pdb::PDB_SymType::ArrayType: - case llvm::pdb::PDB_SymType::BaseClass: - case llvm::pdb::PDB_SymType::BaseInterface: - case llvm::pdb::PDB_SymType::BuiltinType: - case llvm::pdb::PDB_SymType::CustomType: - case llvm::pdb::PDB_SymType::Enum: - case llvm::pdb::PDB_SymType::FunctionArg: - case llvm::pdb::PDB_SymType::FunctionSig: - case llvm::pdb::PDB_SymType::Typedef: - case llvm::pdb::PDB_SymType::VectorType: - case llvm::pdb::PDB_SymType::VTableShape: - case llvm::pdb::PDB_SymType::PointerType: - case llvm::pdb::PDB_SymType::UDT: - return true; - default: - return false; - } - } - - static bool isCuSym(llvm::pdb::PDB_SymType tag) { - switch (tag) { - case llvm::pdb::PDB_SymType::Block: - case llvm::pdb::PDB_SymType::Callee: - case llvm::pdb::PDB_SymType::Caller: - case llvm::pdb::PDB_SymType::CallSite: - case llvm::pdb::PDB_SymType::CoffGroup: - case llvm::pdb::PDB_SymType::CompilandDetails: - case llvm::pdb::PDB_SymType::CompilandEnv: - case llvm::pdb::PDB_SymType::Custom: - case llvm::pdb::PDB_SymType::Data: - case llvm::pdb::PDB_SymType::Function: - case llvm::pdb::PDB_SymType::Inlinee: - case llvm::pdb::PDB_SymType::InlineSite: - case llvm::pdb::PDB_SymType::Label: - case llvm::pdb::PDB_SymType::Thunk: - return true; - default: - return false; - } - } - - static PdbSymUid makeCuSymId(llvm::codeview::ProcRefSym sym) { - return makeCuSymId(llvm::pdb::PDB_SymType::Function, sym.Module - 1, - sym.SymOffset); - } - - static PdbSymUid makeCuSymId(llvm::pdb::PDB_SymType type, uint16_t modi, - uint32_t offset) { - lldbassert(isCuSym(type)); - - PdbSymUid uid; - uid.m_uid.cu_sym.modi = modi; - uid.m_uid.cu_sym.offset = offset; - uid.m_uid.cu_sym.global = false; - uid.m_uid.cu_sym.tag = static_cast(type); - return uid; - } - - static PdbSymUid makeGlobalVariableUid(uint32_t offset) { - PdbSymUid uid = {}; - uid.m_uid.cu_sym.modi = 0; - uid.m_uid.cu_sym.offset = offset; - uid.m_uid.cu_sym.global = 1; - uid.m_uid.cu_sym.unused = 0; - uid.m_uid.cu_sym.tag = static_cast(llvm::pdb::PDB_SymType::Data); - return uid; - } - - static PdbSymUid makeCompilandId(llvm::codeview::ProcRefSym sym) { - // S_PROCREF symbols are 1-based - lldbassert(sym.Module > 0); - return makeCompilandId(sym.Module - 1); - } - - static PdbSymUid makeCompilandId(uint16_t modi) { - PdbSymUid uid; - uid.m_uid.comp_id.modi = modi; - uid.m_uid.cu_sym.tag = - static_cast(llvm::pdb::PDB_SymType::Compiland); - return uid; - } - - static PdbSymUid makeTypeSymId(llvm::pdb::PDB_SymType type, - llvm::codeview::TypeIndex index, bool is_ipi) { - lldbassert(isTypeSym(type)); - - PdbSymUid uid; - uid.m_uid.type_sym.tag = static_cast(type); - uid.m_uid.type_sym.index = index.getIndex(); - uid.m_uid.type_sym.is_ipi = static_cast(is_ipi); - return uid; - } - - static PdbSymUid fromOpaqueId(uint64_t value) { - PdbSymUid result; - ::memcpy(&result.m_uid, &value, sizeof(value)); - return result; - } - - uint64_t toOpaqueId() const { - uint64_t result; - ::memcpy(&result, &m_uid, sizeof(m_uid)); - return result; - } - - bool isPubSym() const { - return tag() == llvm::pdb::PDB_SymType::PublicSymbol; - } - bool isCompiland() const { - return tag() == llvm::pdb::PDB_SymType::Compiland; - } - bool isGlobalVariable() const { - if (tag() != llvm::pdb::PDB_SymType::Data) - return false; - return static_cast(asCuSym().global); - } - - llvm::pdb::PDB_SymType tag() const { - return static_cast(m_uid.comp_id.tag); - } - - const PdbCompilandId &asCompiland() const { - lldbassert(tag() == llvm::pdb::PDB_SymType::Compiland); - return m_uid.comp_id; - } - - const PdbCuSymId &asCuSym() const { - lldbassert(isCuSym(tag())); - return m_uid.cu_sym; - } - - const PdbTypeSymId &asTypeSym() const { - lldbassert(isTypeSym(tag())); - return m_uid.type_sym; - } + PdbSymUid(uint64_t repr) : m_repr(repr) {} + PdbSymUid(const PdbCompilandId &cid); + PdbSymUid(const PdbCompilandSymId &csid); + PdbSymUid(const PdbGlobalSymId &gsid); + PdbSymUid(const PdbTypeSymId &tsid); + PdbSymUid(const PdbFieldListMemberId &flmid); + + uint64_t toOpaqueId() const { return m_repr; } + + PdbSymUidKind kind() const; + + PdbCompilandId asCompiland() const; + PdbCompilandSymId asCompilandSym() const; + PdbGlobalSymId asGlobalSym() const; + PdbTypeSymId asTypeSym() const; + PdbFieldListMemberId asFieldListMember() const; }; +template uint64_t toOpaqueUid(const T &cid) { + return PdbSymUid(cid).toOpaqueId(); +} + struct SymbolAndUid { llvm::codeview::CVSymbol sym; PdbSymUid uid; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index e1ba03f..e00190e 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -8,9 +8,11 @@ //===----------------------------------------------------------------------===// #include "PdbUtil.h" +#include "PdbSymUid.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "lldb/Utility/LLDBAssert.h" @@ -352,6 +354,19 @@ bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) { } } +bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id, + TpiStream &tpi) { + if (id.is_ipi || id.index.isSimple()) + return false; + return IsForwardRefUdt(tpi.getType(id.index)); +} + +bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) { + if (id.is_ipi || id.index.isSimple()) + return false; + return IsTagRecord(tpi.getType(id.index)); +} + lldb::AccessType lldb_private::npdb::TranslateMemberAccess(MemberAccess access) { switch (access) { diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 55dfbe6..6a5797c 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -19,9 +19,17 @@ #include #include +namespace llvm { +namespace pdb { +class TpiStream; +} +} // namespace llvm + namespace lldb_private { namespace npdb { +struct PdbTypeSymId; + struct CVTagRecord { enum Kind { Class, Struct, Union, Enum }; @@ -101,6 +109,9 @@ inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { bool IsForwardRefUdt(llvm::codeview::CVType cvt); bool IsTagRecord(llvm::codeview::CVType cvt); +bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); +bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); + lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); llvm::codeview::TypeIndex diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 174c0c4..b69ec5d 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -707,16 +707,12 @@ uint32_t SymbolFileNativePDB::GetNumCompileUnits() { return count; } -lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbSymUid func_uid, +lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, const SymbolContext &sc) { - lldbassert(func_uid.tag() == PDB_SymType::Function); - - PdbSymUid cuid = PdbSymUid::makeCompilandId(func_uid.asCuSym().modi); - - const CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid); + const CompilandIndexItem *cci = + m_index->compilands().GetCompiland(func_id.modi); lldbassert(cci); - CVSymbol sym_record = - cci->m_debug_stream.readSymbolAtOffset(func_uid.asCuSym().offset); + CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); @@ -733,11 +729,10 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbSymUid func_uid, Type *func_type = nullptr; // FIXME: Resolve types and mangled names. - PdbSymUid sig_uid = - PdbSymUid::makeTypeSymId(PDB_SymType::FunctionSig, TypeIndex{0}, false); + PdbTypeSymId sig_id{TypeIndex::None(), false}; Mangled mangled(getSymbolName(sym_record)); FunctionSP func_sp = std::make_shared( - sc.comp_unit, func_uid.toOpaqueId(), sig_uid.toOpaqueId(), mangled, + sc.comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, func_type, func_range); sc.comp_unit->AddFunction(func_sp); @@ -760,15 +755,14 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { CompUnitSP cu_sp = std::make_shared(m_obj_file->GetModule(), nullptr, fs, - cci.m_uid.toOpaqueId(), lang, optimized); + toOpaqueUid(cci.m_id), lang, optimized); - const PdbCompilandId &cuid = cci.m_uid.asCompiland(); - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cuid.modi, - cu_sp); + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cci.m_id.modi, cu_sp); return cu_sp; } -lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbSymUid type_uid, +lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, const ModifierRecord &mr) { TpiStream &stream = m_index->tpi(); @@ -784,14 +778,14 @@ lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbSymUid type_uid, else name = computeTypeName(stream.typeCollection(), mr.ModifiedType); Declaration decl; - return std::make_shared(type_uid.toOpaqueId(), m_clang->GetSymbolFile(), + return std::make_shared(toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(name), t->GetByteSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); } lldb::TypeSP SymbolFileNativePDB::CreatePointerType( - PdbSymUid type_uid, const llvm::codeview::PointerRecord &pr) { + PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr) { TypeSP pointee = GetOrCreateType(pr.ReferentType); if (!pointee) return nullptr; @@ -807,7 +801,7 @@ lldb::TypeSP SymbolFileNativePDB::CreatePointerType( class_type->GetLayoutCompilerType(), pointee_ct); return std::make_shared( - type_uid.toOpaqueId(), m_clang->GetSymbolFile(), ConstString(), + toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(), pr.getSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); } @@ -829,27 +823,23 @@ lldb::TypeSP SymbolFileNativePDB::CreatePointerType( if ((pr.getOptions() & PointerOptions::Restrict) != PointerOptions::None) pointer_ct = pointer_ct.AddRestrictModifier(); - return std::make_shared(type_uid.toOpaqueId(), m_clang->GetSymbolFile(), + return std::make_shared(toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(), pr.getSize(), nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, pointer_ct, Type::eResolveStateFull); } lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti) { + uint64_t uid = toOpaqueUid(PdbTypeSymId{ti, false}); if (ti == TypeIndex::NullptrT()) { - PdbSymUid uid = - PdbSymUid::makeTypeSymId(PDB_SymType::BuiltinType, ti, false); CompilerType ct = m_clang->GetBasicType(eBasicTypeNullPtr); Declaration decl; - return std::make_shared(uid.toOpaqueId(), this, - ConstString("std::nullptr_t"), 0, nullptr, - LLDB_INVALID_UID, Type::eEncodingIsUID, decl, - ct, Type::eResolveStateFull); + return std::make_shared( + uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); } if (ti.getSimpleMode() != SimpleTypeMode::Direct) { - PdbSymUid uid = - PdbSymUid::makeTypeSymId(PDB_SymType::PointerType, ti, false); TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); CompilerType ct = direct_sp->GetFullCompilerType(); ct = ct.GetPointerType(); @@ -867,13 +857,12 @@ lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti) { return nullptr; } Declaration decl; - return std::make_shared(uid.toOpaqueId(), m_clang->GetSymbolFile(), - ConstString(), pointer_size, nullptr, - LLDB_INVALID_UID, Type::eEncodingIsUID, decl, - ct, Type::eResolveStateFull); + return std::make_shared(uid, m_clang->GetSymbolFile(), ConstString(), + pointer_size, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, + Type::eResolveStateFull); } - PdbSymUid uid = PdbSymUid::makeTypeSymId(PDB_SymType::BuiltinType, ti, false); if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) return nullptr; @@ -886,7 +875,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti) { llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); Declaration decl; - return std::make_shared(uid.toOpaqueId(), m_clang->GetSymbolFile(), + return std::make_shared(uid, m_clang->GetSymbolFile(), ConstString(type_name), size, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); @@ -965,20 +954,18 @@ SymbolFileNativePDB::CreateDeclInfoForType(const TagRecord &record, } lldb::TypeSP SymbolFileNativePDB::CreateClassStructUnion( - PdbSymUid type_uid, const llvm::codeview::TagRecord &record, size_t size, + PdbTypeSymId type_id, const llvm::codeview::TagRecord &record, size_t size, clang::TagTypeKind ttk, clang::MSInheritanceAttr::Spelling inheritance) { - const PdbTypeSymId &tid = type_uid.asTypeSym(); - TypeIndex ti(tid.index); clang::DeclContext *decl_context = nullptr; std::string uname; - std::tie(decl_context, uname) = CreateDeclInfoForType(record, ti); + std::tie(decl_context, uname) = CreateDeclInfoForType(record, type_id.index); lldb::AccessType access = (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic; ClangASTMetadata metadata; - metadata.SetUserID(type_uid.toOpaqueId()); + metadata.SetUserID(toOpaqueUid(type_id)); metadata.SetIsDynamicCXXType(false); CompilerType ct = @@ -1004,35 +991,33 @@ lldb::TypeSP SymbolFileNativePDB::CreateClassStructUnion( // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. Declaration decl; - return std::make_shared(type_uid.toOpaqueId(), m_clang->GetSymbolFile(), + return std::make_shared(toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(uname), size, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, Type::eResolveStateForward); } -lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbSymUid type_uid, +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, const ClassRecord &cr) { clang::TagTypeKind ttk = TranslateUdtKind(cr); clang::MSInheritanceAttr::Spelling inheritance = GetMSInheritance(m_index->tpi().typeCollection(), cr); - return CreateClassStructUnion(type_uid, cr, cr.getSize(), ttk, inheritance); + return CreateClassStructUnion(type_id, cr, cr.getSize(), ttk, inheritance); } -lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbSymUid type_uid, +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, const UnionRecord &ur) { return CreateClassStructUnion( - type_uid, ur, ur.getSize(), clang::TTK_Union, + type_id, ur, ur.getSize(), clang::TTK_Union, clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance); } -lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbSymUid type_uid, +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, const EnumRecord &er) { - const PdbTypeSymId &tid = type_uid.asTypeSym(); - TypeIndex ti(tid.index); clang::DeclContext *decl_context = nullptr; std::string uname; - std::tie(decl_context, uname) = CreateDeclInfoForType(er, ti); + std::tie(decl_context, uname) = CreateDeclInfoForType(er, type_id.index); Declaration decl; TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); @@ -1046,13 +1031,13 @@ lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbSymUid type_uid, // We're just going to forward resolve this for now. We'll complete // it only if the user requests. return std::make_shared( - type_uid.toOpaqueId(), m_clang->GetSymbolFile(), ConstString(uname), + toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(uname), underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, enum_ct, lldb_private::Type::eResolveStateForward); } -TypeSP SymbolFileNativePDB::CreateArrayType(PdbSymUid type_uid, +TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, const ArrayRecord &ar) { TypeSP element_type = GetOrCreateType(ar.ElementType); uint64_t element_count = ar.Size / element_type->GetByteSize(); @@ -1064,14 +1049,14 @@ TypeSP SymbolFileNativePDB::CreateArrayType(PdbSymUid type_uid, Declaration decl; TypeSP array_sp = std::make_shared( - type_uid.toOpaqueId(), m_clang->GetSymbolFile(), ConstString(), ar.Size, + toOpaqueUid(type_id), m_clang->GetSymbolFile(), ConstString(), ar.Size, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, array_ct, lldb_private::Type::eResolveStateFull); array_sp->SetEncodingType(element_type.get()); return array_sp; } -TypeSP SymbolFileNativePDB::CreateProcedureType(PdbSymUid type_uid, +TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, const ProcedureRecord &pr) { TpiStream &stream = m_index->tpi(); CVType args_cvt = stream.getType(pr.ArgumentList); @@ -1109,138 +1094,126 @@ TypeSP SymbolFileNativePDB::CreateProcedureType(PdbSymUid type_uid, Declaration decl; return std::make_shared( - type_uid.toOpaqueId(), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, + toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type, lldb_private::Type::eResolveStateFull); } -TypeSP SymbolFileNativePDB::CreateType(PdbSymUid type_uid) { - const PdbTypeSymId &tsid = type_uid.asTypeSym(); - TypeIndex index(tsid.index); - - if (index.getIndex() < TypeIndex::FirstNonSimpleIndex) - return CreateSimpleType(index); +TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id) { + if (type_id.index.isSimple()) + return CreateSimpleType(type_id.index); - TpiStream &stream = tsid.is_ipi ? m_index->ipi() : m_index->tpi(); - CVType cvt = stream.getType(index); + TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); + CVType cvt = stream.getType(type_id.index); if (cvt.kind() == LF_MODIFIER) { ModifierRecord modifier; llvm::cantFail( TypeDeserializer::deserializeAs(cvt, modifier)); - return CreateModifierType(type_uid, modifier); + return CreateModifierType(type_id, modifier); } if (cvt.kind() == LF_POINTER) { PointerRecord pointer; llvm::cantFail( TypeDeserializer::deserializeAs(cvt, pointer)); - return CreatePointerType(type_uid, pointer); + return CreatePointerType(type_id, pointer); } if (IsClassRecord(cvt.kind())) { ClassRecord cr; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, cr)); - return CreateTagType(type_uid, cr); + return CreateTagType(type_id, cr); } if (cvt.kind() == LF_ENUM) { EnumRecord er; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); - return CreateTagType(type_uid, er); + return CreateTagType(type_id, er); } if (cvt.kind() == LF_UNION) { UnionRecord ur; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ur)); - return CreateTagType(type_uid, ur); + return CreateTagType(type_id, ur); } if (cvt.kind() == LF_ARRAY) { ArrayRecord ar; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); - return CreateArrayType(type_uid, ar); + return CreateArrayType(type_id, ar); } if (cvt.kind() == LF_PROCEDURE) { ProcedureRecord pr; llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); - return CreateProcedureType(type_uid, pr); + return CreateProcedureType(type_id, pr); } return nullptr; } -TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbSymUid type_uid) { +TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { // If they search for a UDT which is a forward ref, try and resolve the full // decl and just map the forward ref uid to the full decl record. - llvm::Optional full_decl_uid; - if (type_uid.tag() == PDB_SymType::UDT || - type_uid.tag() == PDB_SymType::Enum) { - const PdbTypeSymId &type_id = type_uid.asTypeSym(); - TypeIndex ti(type_id.index); - lldbassert(!ti.isSimple()); - CVType cvt = m_index->tpi().getType(ti); - - if (IsForwardRefUdt(cvt)) { - auto expected_full_ti = m_index->tpi().findFullDeclForForwardRef(ti); - if (!expected_full_ti) - llvm::consumeError(expected_full_ti.takeError()); - else if (*expected_full_ti != ti) { - full_decl_uid = PdbSymUid::makeTypeSymId( - type_uid.tag(), *expected_full_ti, type_id.is_ipi); - - // It's possible that a lookup would occur for the full decl causing it - // to be cached, then a second lookup would occur for the forward decl. - // We don't want to create a second full decl, so make sure the full - // decl hasn't already been cached. - auto full_iter = m_types.find(full_decl_uid->toOpaqueId()); - if (full_iter != m_types.end()) { - TypeSP result = full_iter->second; - // Map the forward decl to the TypeSP for the full decl so we can take - // the fast path next time. - m_types[type_uid.toOpaqueId()] = result; - return result; - } + llvm::Optional full_decl_uid; + if (IsForwardRefUdt(type_id, m_index->tpi())) { + auto expected_full_ti = + m_index->tpi().findFullDeclForForwardRef(type_id.index); + if (!expected_full_ti) + llvm::consumeError(expected_full_ti.takeError()); + else if (*expected_full_ti != type_id.index) { + full_decl_uid = PdbTypeSymId{*expected_full_ti, false}; + + // It's possible that a lookup would occur for the full decl causing it + // to be cached, then a second lookup would occur for the forward decl. + // We don't want to create a second full decl, so make sure the full + // decl hasn't already been cached. + auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); + if (full_iter != m_types.end()) { + TypeSP result = full_iter->second; + // Map the forward decl to the TypeSP for the full decl so we can take + // the fast path next time. + m_types[toOpaqueUid(type_id)] = result; + return result; } } } - PdbSymUid best_uid = full_decl_uid ? *full_decl_uid : type_uid; - TypeSP result = CreateType(best_uid); + PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; + TypeSP result = CreateType(best_decl_id); if (!result) return nullptr; - m_types[best_uid.toOpaqueId()] = result; + + uint64_t best_uid = toOpaqueUid(best_decl_id); + m_types[best_uid] = result; // If we had both a forward decl and a full decl, make both point to the new // type. if (full_decl_uid) - m_types[type_uid.toOpaqueId()] = result; + m_types[toOpaqueUid(type_id)] = result; - const PdbTypeSymId &type_id = best_uid.asTypeSym(); - if (best_uid.tag() == PDB_SymType::UDT || - best_uid.tag() == PDB_SymType::Enum) { + if (IsTagRecord(best_decl_id, m_index->tpi())) { clang::TagDecl *record_decl = m_clang->GetAsTagDecl(result->GetForwardCompilerType()); lldbassert(record_decl); TypeIndex ti(type_id.index); - m_uid_to_decl[best_uid.toOpaqueId()] = record_decl; + m_uid_to_decl[best_uid] = record_decl; m_decl_to_status[record_decl] = - DeclStatus(best_uid.toOpaqueId(), Type::eResolveStateForward); + DeclStatus(best_uid, Type::eResolveStateForward); } return result; } -TypeSP SymbolFileNativePDB::GetOrCreateType(PdbSymUid type_uid) { - lldbassert(PdbSymUid::isTypeSym(type_uid.tag())); +TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { // We can't use try_emplace / overwrite here because the process of creating // a type could create nested types, which could invalidate iterators. So // we have to do a 2-phase lookup / insert. - auto iter = m_types.find(type_uid.toOpaqueId()); + auto iter = m_types.find(toOpaqueUid(type_id)); if (iter != m_types.end()) return iter->second; - return CreateAndCacheType(type_uid); + return CreateAndCacheType(type_id); } static DWARFExpression @@ -1315,12 +1288,10 @@ static DWARFExpression MakeGlobalLocationExpression(uint16_t section, return result; } -VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbSymUid var_uid) { - const PdbCuSymId &cu_sym = var_uid.asCuSym(); - lldbassert(cu_sym.global); - CVSymbol sym = m_index->symrecords().readRecord(cu_sym.offset); +VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { + CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); if (sym.kind() == S_CONSTANT) - return CreateConstantSymbol(var_uid, sym); + return CreateConstantSymbol(var_id, sym); lldb::ValueType scope = eValueTypeInvalid; TypeIndex ti; @@ -1367,16 +1338,14 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbSymUid var_uid) { CompUnitSP comp_unit; llvm::Optional modi = m_index->GetModuleIndexForVa(addr); if (modi) { - PdbSymUid cuid = PdbSymUid::makeCompilandId(*modi); - CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(cuid); + CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); comp_unit = GetOrCreateCompileUnit(cci); } Declaration decl; - PDB_SymType pdbst = GetPdbSymType(m_index->tpi(), ti); - PdbSymUid tuid = PdbSymUid::makeTypeSymId(pdbst, ti, false); + PdbTypeSymId tid{ti, false}; SymbolFileTypeSP type_sp = - std::make_shared(*this, tuid.toOpaqueId()); + std::make_shared(*this, toOpaqueUid(tid)); Variable::RangeList ranges; DWARFExpression location = MakeGlobalLocationExpression( @@ -1385,7 +1354,7 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbSymUid var_uid) { std::string global_name("::"); global_name += name; VariableSP var_sp = std::make_shared( - var_uid.toOpaqueId(), name.str().c_str(), global_name.c_str(), type_sp, + toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external, false, false); var_sp->SetLocationIsConstantValueData(false); @@ -1394,7 +1363,7 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbSymUid var_uid) { } lldb::VariableSP -SymbolFileNativePDB::CreateConstantSymbol(PdbSymUid var_uid, +SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, const CVSymbol &cvs) { TpiStream &tpi = m_index->tpi(); ConstantSym constant(cvs.kind()); @@ -1402,10 +1371,9 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbSymUid var_uid, llvm::cantFail(SymbolDeserializer::deserializeAs(cvs, constant)); std::string global_name("::"); global_name += constant.Name; - PDB_SymType pdbst = GetPdbSymType(tpi, constant.Type); - PdbSymUid tuid = PdbSymUid::makeTypeSymId(pdbst, constant.Type, false); + PdbTypeSymId tid{constant.Type, false}; SymbolFileTypeSP type_sp = - std::make_shared(*this, tuid.toOpaqueId()); + std::make_shared(*this, toOpaqueUid(tid)); Declaration decl; Variable::RangeList ranges; @@ -1414,37 +1382,31 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbSymUid var_uid, MakeConstantLocationExpression(constant.Type, tpi, constant, module); VariableSP var_sp = std::make_shared( - var_uid.toOpaqueId(), constant.Name.str().c_str(), global_name.c_str(), + toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, false, false, false); var_sp->SetLocationIsConstantValueData(true); return var_sp; } -VariableSP SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbSymUid var_uid) { - lldbassert(var_uid.isGlobalVariable()); - - auto emplace_result = - m_global_vars.try_emplace(var_uid.toOpaqueId(), nullptr); +VariableSP +SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { + auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); if (emplace_result.second) - emplace_result.first->second = CreateGlobalVariable(var_uid); + emplace_result.first->second = CreateGlobalVariable(var_id); return emplace_result.first->second; } -lldb::TypeSP -SymbolFileNativePDB::GetOrCreateType(llvm::codeview::TypeIndex ti) { - PDB_SymType pdbst = GetPdbSymType(m_index->tpi(), ti); - PdbSymUid tuid = PdbSymUid::makeTypeSymId(pdbst, ti, false); - return GetOrCreateType(tuid); +lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { + return GetOrCreateType(PdbTypeSymId{ti, false}); } -FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbSymUid func_uid, +FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, const SymbolContext &sc) { - lldbassert(func_uid.tag() == PDB_SymType::Function); - auto emplace_result = m_functions.try_emplace(func_uid.toOpaqueId(), nullptr); + auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); if (emplace_result.second) - emplace_result.first->second = CreateFunction(func_uid, sc); + emplace_result.first->second = CreateFunction(func_id, sc); lldbassert(emplace_result.first->second); return emplace_result.first->second; @@ -1452,8 +1414,9 @@ FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbSymUid func_uid, CompUnitSP SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { + auto emplace_result = - m_compilands.try_emplace(cci.m_uid.toOpaqueId(), nullptr); + m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); if (emplace_result.second) emplace_result.first->second = CreateCompileUnit(cci); @@ -1479,10 +1442,11 @@ SymbolFileNativePDB::ParseCompileUnitLanguage(const SymbolContext &sc) { // safe to assume that `sc.comp_unit` is valid? if (!sc.comp_unit) return lldb::eLanguageTypeUnknown; - PdbSymUid uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(uid.tag() == PDB_SymType::Compiland); + PdbSymUid uid(sc.comp_unit->GetID()); + lldbassert(uid.kind() == PdbSymUidKind::Compiland); - CompilandIndexItem *item = m_index->compilands().GetCompiland(uid); + CompilandIndexItem *item = + m_index->compilands().GetCompiland(uid.asCompiland().modi); lldbassert(item); if (!item->m_compile_opts) return lldb::eLanguageTypeUnknown; @@ -1514,8 +1478,7 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( llvm::Optional modi = m_index->GetModuleIndexForVa(file_addr); if (!modi) return 0; - PdbSymUid cuid = PdbSymUid::makeCompilandId(*modi); - CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid); + CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi); if (!cci) return 0; @@ -1527,9 +1490,13 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( lldbassert(sc.comp_unit); std::vector matches = m_index->FindSymbolsByVa(file_addr); for (const auto &match : matches) { - if (match.uid.tag() != PDB_SymType::Function) + if (match.uid.kind() != PdbSymUidKind::CompilandSym) + continue; + PdbCompilandSymId csid = match.uid.asCompilandSym(); + CVSymbol cvs = m_index->ReadSymbolRecord(csid); + if (CVSymToPDBSym(cvs.kind()) != PDB_SymType::Function) continue; - sc.function = GetOrCreateFunction(match.uid, sc).get(); + sc.function = GetOrCreateFunction(csid, sc).get(); } resolved_flags |= eSymbolContextFunction; } @@ -1587,9 +1554,10 @@ bool SymbolFileNativePDB::ParseCompileUnitLineTable(const SymbolContext &sc) { // 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. lldbassert(sc.comp_unit); - PdbSymUid cu_id = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(cu_id.isCompiland()); - CompilandIndexItem *cci = m_index->compilands().GetCompiland(cu_id); + PdbSymUid cu_id(sc.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(sc.comp_unit); @@ -1664,10 +1632,10 @@ bool SymbolFileNativePDB::ParseCompileUnitSupportFiles( const SymbolContext &sc, FileSpecList &support_files) { lldbassert(sc.comp_unit); - PdbSymUid comp_uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(comp_uid.tag() == PDB_SymType::Compiland); - - const CompilandIndexItem *cci = m_index->compilands().GetCompiland(comp_uid); + PdbSymUid cu_id(sc.comp_unit->GetID()); + lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); + CompilandIndexItem *cci = + m_index->compilands().GetCompiland(cu_id.asCompiland().modi); lldbassert(cci); for (llvm::StringRef f : cci->m_file_list) { @@ -1712,8 +1680,8 @@ uint32_t SymbolFileNativePDB::FindGlobalVariables( case SymbolKind::S_GTHREAD32: case SymbolKind::S_LTHREAD32: case SymbolKind::S_CONSTANT: { - PdbSymUid uid = PdbSymUid::makeGlobalVariableUid(result.first); - var = GetOrCreateGlobalVariable(uid); + PdbGlobalSymId global{result.first, false}; + var = GetOrCreateGlobalVariable(global); variables.AddVariable(var); break; } @@ -1745,14 +1713,14 @@ uint32_t SymbolFileNativePDB::FindFunctions( if (!IsValidRecord(proc)) continue; - PdbSymUid cuid = PdbSymUid::makeCompilandId(proc); - CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(cuid); + CompilandIndexItem &cci = + m_index->compilands().GetOrCreateCompiland(proc.modi()); SymbolContext sc; sc.comp_unit = GetOrCreateCompileUnit(cci).get(); sc.module_sp = sc.comp_unit->GetModule(); - PdbSymUid func_uid = PdbSymUid::makeCuSymId(proc); - sc.function = GetOrCreateFunction(func_uid, sc).get(); + PdbCompilandSymId func_id{proc.modi(), proc.SymOffset}; + sc.function = GetOrCreateFunction(func_id, sc).get(); sc_list.Append(sc); } @@ -1823,14 +1791,13 @@ Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { if (iter != m_types.end()) return &*iter->second; - PdbSymUid uid = PdbSymUid::fromOpaqueId(type_uid); - lldbassert(uid.isTypeSym(uid.tag())); - const PdbTypeSymId &type_id = uid.asTypeSym(); - TypeIndex ti(type_id.index); - if (ti.isNoneType()) + PdbSymUid uid(type_uid); + lldbassert(uid.kind() == PdbSymUidKind::Type); + PdbTypeSymId type_id = uid.asTypeSym(); + if (type_id.index.isNoneType()) return nullptr; - TypeSP type_sp = CreateAndCacheType(uid); + TypeSP type_sp = CreateAndCacheType(type_id); return &*type_sp; } @@ -1853,10 +1820,9 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { if (status.status == Type::eResolveStateFull) return true; - PdbSymUid uid = PdbSymUid::fromOpaqueId(status.uid); - lldbassert(uid.tag() == PDB_SymType::UDT || uid.tag() == PDB_SymType::Enum); + PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym(); - const PdbTypeSymId &type_id = uid.asTypeSym(); + lldbassert(IsTagRecord(type_id, m_index->tpi())); ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false); @@ -1870,7 +1836,7 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { if (IsForwardRefUdt(cvt)) return false; - auto types_iter = m_types.find(uid.toOpaqueId()); + auto types_iter = m_types.find(status.uid); lldbassert(types_iter != m_types.end()); if (cvt.kind() == LF_MODIFIER) { @@ -1890,7 +1856,7 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { lldbassert(!IsForwardRefUdt(cvt)); unmodified_type = *expected_full_ti; } - uid = PdbSymUid::makeTypeSymId(uid.tag(), unmodified_type, false); + type_id = PdbTypeSymId{unmodified_type, false}; } TypeIndex field_list_ti = GetFieldListIndex(cvt); CVType field_list_cvt = m_index->tpi().getType(field_list_ti); @@ -1899,7 +1865,7 @@ bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { // Visit all members of this class, then perform any finalization necessary // to complete the class. - UdtRecordCompleter completer(uid, compiler_type, *tag_decl, *this); + UdtRecordCompleter completer(type_id, compiler_type, *tag_decl, *this); auto error = llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); completer.complete(); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index f147f47..980d485 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -170,38 +170,41 @@ private: size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches, TypeMap &types); - lldb::TypeSP CreateModifierType(PdbSymUid type_uid, + lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, const llvm::codeview::ModifierRecord &mr); - lldb::TypeSP CreatePointerType(PdbSymUid type_uid, + lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr); lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti); - lldb::TypeSP CreateTagType(PdbSymUid type_uid, + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::ClassRecord &cr); - lldb::TypeSP CreateTagType(PdbSymUid type_uid, + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::EnumRecord &er); - lldb::TypeSP CreateTagType(PdbSymUid type_uid, + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::UnionRecord &ur); - lldb::TypeSP CreateArrayType(PdbSymUid type_uid, + lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, const llvm::codeview::ArrayRecord &ar); - lldb::TypeSP CreateProcedureType(PdbSymUid type_uid, + lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, const llvm::codeview::ProcedureRecord &pr); - lldb::TypeSP CreateClassStructUnion( - PdbSymUid type_uid, const llvm::codeview::TagRecord &record, size_t size, - clang::TagTypeKind ttk, clang::MSInheritanceAttr::Spelling inheritance); + lldb::TypeSP + CreateClassStructUnion(PdbTypeSymId type_id, + const llvm::codeview::TagRecord &record, size_t size, + clang::TagTypeKind ttk, + clang::MSInheritanceAttr::Spelling inheritance); - lldb::FunctionSP GetOrCreateFunction(PdbSymUid func_uid, + lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, const SymbolContext &sc); lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci); - lldb::TypeSP GetOrCreateType(PdbSymUid type_uid); + lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id); lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti); - lldb::VariableSP GetOrCreateGlobalVariable(PdbSymUid var_uid); + lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id); - lldb::FunctionSP CreateFunction(PdbSymUid func_uid, const SymbolContext &sc); + lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, + const SymbolContext &sc); lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci); - lldb::TypeSP CreateType(PdbSymUid type_uid); - lldb::TypeSP CreateAndCacheType(PdbSymUid type_uid); - lldb::VariableSP CreateGlobalVariable(PdbSymUid var_uid); - lldb::VariableSP CreateConstantSymbol(PdbSymUid var_uid, + lldb::TypeSP CreateType(PdbTypeSymId type_id); + lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id); + lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id); + lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, const llvm::codeview::CVSymbol &cvs); llvm::BumpPtrAllocator m_allocator; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index dfca59d9..88eb6a8 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -24,26 +24,23 @@ using namespace lldb_private::npdb; using Error = llvm::Error; -UdtRecordCompleter::UdtRecordCompleter(PdbSymUid uid, CompilerType &derived_ct, +UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, + CompilerType &derived_ct, clang::TagDecl &tag_decl, SymbolFileNativePDB &symbol_file) - : m_uid(uid), m_derived_ct(derived_ct), m_tag_decl(tag_decl), + : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl), m_symbol_file(symbol_file) { TpiStream &tpi = symbol_file.m_index->tpi(); - TypeIndex ti(uid.asTypeSym().index); - CVType cvt = tpi.getType(ti); + CVType cvt = tpi.getType(m_id.index); switch (cvt.kind()) { case LF_ENUM: - lldbassert(uid.tag() == PDB_SymType::Enum); llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.er)); break; case LF_UNION: - lldbassert(uid.tag() == PDB_SymType::UDT); llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.ur)); break; case LF_CLASS: case LF_STRUCTURE: - lldbassert(uid.tag() == PDB_SymType::UDT); llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.cr)); break; default: @@ -171,7 +168,6 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, Declaration decl; llvm::StringRef name = DropNameScope(enumerator.getName()); - lldbassert(m_uid.tag() == PDB_SymType::Enum); TypeSP underlying_type = m_symbol_file.GetOrCreateType(m_cvr.er.getUnderlyingType()); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h index f20452e..1b2fca2 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -36,7 +36,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { llvm::codeview::EnumRecord er; } m_cvr; - PdbSymUid m_uid; + PdbTypeSymId m_id; CompilerType &m_derived_ct; clang::TagDecl &m_tag_decl; SymbolFileNativePDB &m_symbol_file; @@ -44,7 +44,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { ClangASTImporter::LayoutInfo m_layout; public: - UdtRecordCompleter(PdbSymUid uid, CompilerType &derived_ct, + UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, SymbolFileNativePDB &symbol_file); diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h index c63fb98..b58825c 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -400,6 +400,7 @@ public: uint16_t Module; StringRef Name; + uint16_t modi() const { return Module - 1; } uint32_t RecordOffset; };