Error TypeStreamMerger::remapType(const CVType &Type) { auto DoSerialize = [this, Type]() -> ArrayRef<uint8_t> { RemappedType R(Type); SmallVector<TiReference, 32> Refs; discoverTypeIndices(Type.RecordData, Refs); if (!remapIndices(R, Refs)) return {}; return serializeRemapped(R); }; TypeIndex DestIdx = Untranslated; if (UseGlobalHashes) { GlobalTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; DestIdx = Dest.insertRecordAs(H, DoSerialize); } else { MergingTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; auto Data = DoSerialize(); if (!Data.empty()) DestIdx = Dest.insertRecordBytes(Data); } addMapping(DestIdx); ++CurIndex; assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) && "visitKnownRecord should add one index map entry"); return Error::success(); }
static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi) { if (ti.isSimple()) { SimpleTypeKind stk = ti.getSimpleKind(); return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)}; } CVType cvt = tpi.getType(ti); switch (cvt.kind()) { case LF_MODIFIER: { ModifierRecord mfr; llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr)); return GetIntegralTypeInfo(mfr.ModifiedType, tpi); } case LF_POINTER: { PointerRecord pr; llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr)); return GetIntegralTypeInfo(pr.ReferentType, tpi); } case LF_ENUM: { EnumRecord er; llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); return GetIntegralTypeInfo(er.UnderlyingType, tpi); } default: assert(false && "Type is not integral!"); return {0, false}; } }
Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) { switch (Rec.kind()) { case LF_CLASS: case LF_STRUCTURE: case LF_INTERFACE: return getHashForUdt<ClassRecord>(Rec); case LF_UNION: return getHashForUdt<UnionRecord>(Rec); case LF_ENUM: return getHashForUdt<EnumRecord>(Rec); case LF_UDT_SRC_LINE: return getSourceLineHash<UdtSourceLineRecord>(Rec); case LF_UDT_MOD_SRC_LINE: return getSourceLineHash<UdtModSourceLineRecord>(Rec); default: break; } // Run CRC32 over the bytes. This corresponds to `hashBufv8`. JamCRC JC(/*Init=*/0U); ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()), Rec.data().size()); JC.update(Bytes); return JC.getCRC(); }
Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, DataMemberRecord &data_member) { uint64_t offset = data_member.FieldOffset * 8; uint32_t bitfield_width = 0; TypeIndex ti(data_member.Type); if (!ti.isSimple()) { CVType cvt = m_tpi.getType(ti); if (cvt.kind() == LF_BITFIELD) { BitFieldRecord bfr; llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr)); offset += bfr.BitOffset; bitfield_width = bfr.BitSize; ti = bfr.Type; } } clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti)); m_ast_builder.CompleteType(member_qt); lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType( m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt), access, bitfield_width); // FIXME: Add a PdbSymUid namespace for field list members and update // the m_uid_to_decl map with this decl. m_layout.field_offsets.insert(std::make_pair(decl, offset)); return Error::success(); }
static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) { TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind()); T KnownRecord(RK); if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord)) return EC; return Error::success(); }
static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) { LeafRecord Result; auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind()); if (auto EC = Impl->fromCodeViewRecord(Type)) return std::move(EC); Result.Leaf = Impl; return Result; }
Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) { #define TYPE_RECORD(EnumName, EnumVal, ClassName) \ case EnumName: \ return fromCodeViewRecordImpl<ClassName##Record>(Type); #define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ TYPE_RECORD(EnumName, EnumVal, ClassName) #define MEMBER_RECORD(EnumName, EnumVal, ClassName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) switch (Type.kind()) { #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" default: { llvm_unreachable("Unknown leaf kind!"); } } return make_error<CodeViewError>(cv_error_code::corrupt_record); }
size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi) { if (id.index.isSimple()) { switch (id.index.getSimpleMode()) { case SimpleTypeMode::Direct: return GetTypeSizeForSimpleKind(id.index.getSimpleKind()); case SimpleTypeMode::NearPointer32: case SimpleTypeMode::FarPointer32: return 4; case SimpleTypeMode::NearPointer64: return 8; case SimpleTypeMode::NearPointer128: return 16; default: break; } return 0; } TypeIndex index = id.index; if (IsForwardRefUdt(index, tpi)) index = llvm::cantFail(tpi.findFullDeclForForwardRef(index)); CVType cvt = tpi.getType(index); switch (cvt.kind()) { case LF_MODIFIER: return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi); case LF_ENUM: { EnumRecord record; llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record)); return GetSizeOfType({record.UnderlyingType}, tpi); } case LF_POINTER: return GetSizeOfTypeInternal<PointerRecord>(cvt); case LF_ARRAY: return GetSizeOfTypeInternal<ArrayRecord>(cvt); case LF_CLASS: case LF_STRUCTURE: case LF_INTERFACE: return GetSizeOfTypeInternal<ClassRecord>(cvt); case LF_UNION: return GetSizeOfTypeInternal<UnionRecord>(cvt); default: break; } return 0; }
bool llvm::codeview::isUdtForwardRef(CVType CVT) { ClassOptions UdtOptions = ClassOptions::None; switch (CVT.kind()) { case LF_STRUCTURE: case LF_CLASS: case LF_INTERFACE: UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT)); break; case LF_ENUM: UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT)); break; case LF_UNION: UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT)); break; default: return false; } return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None; }
bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) { ClassRecord cr; UnionRecord ur; EnumRecord er; switch (cvt.kind()) { case LF_CLASS: case LF_STRUCTURE: case LF_INTERFACE: llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); return cr.isForwardRef(); case LF_UNION: llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); return ur.isForwardRef(); case LF_ENUM: llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); return er.isForwardRef(); default: return false; } }
UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, TpiStream &tpi) : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl), m_ast_builder(ast_builder), m_tpi(tpi) { CVType cvt = m_tpi.getType(m_id.index); switch (cvt.kind()) { case LF_ENUM: llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er)); break; case LF_UNION: llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, m_cvr.ur)); break; case LF_CLASS: case LF_STRUCTURE: llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, m_cvr.cr)); break; default: llvm_unreachable("unreachable!"); } }
TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) { switch (cvt.kind()) { case LF_CLASS: case LF_STRUCTURE: case LF_INTERFACE: { ClassRecord cr; cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); return cr.FieldList; } case LF_UNION: { UnionRecord ur; cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); return ur.FieldList; } case LF_ENUM: { EnumRecord er; cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); return er.FieldList; } default: llvm_unreachable("Unreachable!"); } }
CVTagRecord CVTagRecord::create(CVType type) { assert(IsTagRecord(type) && "type is not a tag record!"); switch (type.kind()) { case LF_CLASS: case LF_STRUCTURE: case LF_INTERFACE: { ClassRecord cr; llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr)); return CVTagRecord(std::move(cr)); } case LF_UNION: { UnionRecord ur; llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur)); return CVTagRecord(std::move(ur)); } case LF_ENUM: { EnumRecord er; llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er)); return CVTagRecord(std::move(er)); } default: llvm_unreachable("Unreachable!"); } }
void llvm::codeview::discoverTypeIndices(const CVType &Type, SmallVectorImpl<TiReference> &Refs) { ::discoverTypeIndices(Type.content(), Type.kind(), Refs); }
TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) { assert(CVT.kind() == LF_MODIFIER); SmallVector<TypeIndex, 1> Refs; discoverTypeIndices(CVT, Refs); return Refs.front(); }
Error TypeDumpVisitor::visitUnknownType(CVType &Record) { W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames)); W->printNumber("Length", uint32_t(Record.content().size())); return Error::success(); }
TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) { lldbassert(modifier.kind() == LF_MODIFIER); ModifierRecord mr; llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr)); return mr.ModifiedType; }