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<PdbCompilandId>::value,
- "type is not standard layout!");
-static_assert(std::is_standard_layout<PdbCuSymId>::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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(type);
- uid.m_uid.type_sym.index = index.getIndex();
- uid.m_uid.type_sym.is_ipi = static_cast<uint8_t>(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<bool>(asCuSym().global);
- }
-
- llvm::pdb::PDB_SymType tag() const {
- return static_cast<llvm::pdb::PDB_SymType>(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 <typename T> uint64_t toOpaqueUid(const T &cid) {
+ return PdbSymUid(cid).toOpaqueId();
+}
+
struct SymbolAndUid {
llvm::codeview::CVSymbol sym;
PdbSymUid uid;
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);
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<Function>(
- 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);
CompUnitSP cu_sp =
std::make_shared<CompileUnit>(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();
else
name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
Declaration decl;
- return std::make_shared<Type>(type_uid.toOpaqueId(), m_clang->GetSymbolFile(),
+ return std::make_shared<Type>(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;
class_type->GetLayoutCompilerType(), pointee_ct);
return std::make_shared<Type>(
- 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);
}
if ((pr.getOptions() & PointerOptions::Restrict) != PointerOptions::None)
pointer_ct = pointer_ct.AddRestrictModifier();
- return std::make_shared<Type>(type_uid.toOpaqueId(), m_clang->GetSymbolFile(),
+ return std::make_shared<Type>(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<Type>(uid.toOpaqueId(), this,
- ConstString("std::nullptr_t"), 0, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- ct, Type::eResolveStateFull);
+ return std::make_shared<Type>(
+ 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();
return nullptr;
}
Declaration decl;
- return std::make_shared<Type>(uid.toOpaqueId(), m_clang->GetSymbolFile(),
- ConstString(), pointer_size, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
- ct, Type::eResolveStateFull);
+ return std::make_shared<Type>(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;
llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
Declaration decl;
- return std::make_shared<Type>(uid.toOpaqueId(), m_clang->GetSymbolFile(),
+ return std::make_shared<Type>(uid, m_clang->GetSymbolFile(),
ConstString(type_name), size, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
ct, Type::eResolveStateFull);
}
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 =
// FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
Declaration decl;
- return std::make_shared<Type>(type_uid.toOpaqueId(), m_clang->GetSymbolFile(),
+ return std::make_shared<Type>(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);
// We're just going to forward resolve this for now. We'll complete
// it only if the user requests.
return std::make_shared<lldb_private::Type>(
- 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();
Declaration decl;
TypeSP array_sp = std::make_shared<lldb_private::Type>(
- 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);
Declaration decl;
return std::make_shared<lldb_private::Type>(
- 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<ModifierRecord>(cvt, modifier));
- return CreateModifierType(type_uid, modifier);
+ return CreateModifierType(type_id, modifier);
}
if (cvt.kind() == LF_POINTER) {
PointerRecord pointer;
llvm::cantFail(
TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
- return CreatePointerType(type_uid, pointer);
+ return CreatePointerType(type_id, pointer);
}
if (IsClassRecord(cvt.kind())) {
ClassRecord cr;
llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
- return CreateTagType(type_uid, cr);
+ return CreateTagType(type_id, cr);
}
if (cvt.kind() == LF_ENUM) {
EnumRecord er;
llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
- return CreateTagType(type_uid, er);
+ return CreateTagType(type_id, er);
}
if (cvt.kind() == LF_UNION) {
UnionRecord ur;
llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
- return CreateTagType(type_uid, ur);
+ return CreateTagType(type_id, ur);
}
if (cvt.kind() == LF_ARRAY) {
ArrayRecord ar;
llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
- return CreateArrayType(type_uid, ar);
+ return CreateArrayType(type_id, ar);
}
if (cvt.kind() == LF_PROCEDURE) {
ProcedureRecord pr;
llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(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<PdbSymUid> 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<PdbTypeSymId> 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
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;
CompUnitSP comp_unit;
llvm::Optional<uint16_t> 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<SymbolFileType>(*this, tuid.toOpaqueId());
+ std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
Variable::RangeList ranges;
DWARFExpression location = MakeGlobalLocationExpression(
std::string global_name("::");
global_name += name;
VariableSP var_sp = std::make_shared<Variable>(
- 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);
}
lldb::VariableSP
-SymbolFileNativePDB::CreateConstantSymbol(PdbSymUid var_uid,
+SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
const CVSymbol &cvs) {
TpiStream &tpi = m_index->tpi();
ConstantSym constant(cvs.kind());
llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(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<SymbolFileType>(*this, tuid.toOpaqueId());
+ std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
Declaration decl;
Variable::RangeList ranges;
MakeConstantLocationExpression(constant.Type, tpi, constant, module);
VariableSP var_sp = std::make_shared<Variable>(
- 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;
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);
// 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;
llvm::Optional<uint16_t> 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;
lldbassert(sc.comp_unit);
std::vector<SymbolAndUid> 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;
}
// 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<LineTable>(sc.comp_unit);
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) {
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;
}
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);
}
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;
}
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);
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) {
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);
// 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();