SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) { // First see if it's already in our cache. const auto Entry = TypeIndexToSymbolId.find(Index); if (Entry != TypeIndexToSymbolId.end()) return Entry->second; // Symbols for built-in types are created on the fly. if (Index.isSimple()) { // FIXME: We will eventually need to handle pointers to other simple types, // which are still simple types in the world of CodeView TypeIndexes. if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) return 0; const auto Kind = Index.getSimpleKind(); const auto It = std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes), [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; }); if (It == std::end(BuiltinTypes)) return 0; SymIndexId Id = SymbolCache.size(); SymbolCache.emplace_back( llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size)); TypeIndexToSymbolId[Index] = Id; return Id; } // TODO: Look up PDB type by type index return 0; }
std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI, bool IsType) const { if (TI.isSimple() || TI.isDecoratedItemId()) return formatv("{0}", TI).str(); auto &Container = IsType ? Types : Ids; StringRef Name = Container.getTypeName(TI); if (Name.size() > 32) { Name = Name.take_front(32); return formatv("{0} ({1}...)", TI, Name); } else return formatv("{0} ({1})", TI, Name); }
SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { // First see if it's already in our cache. const auto Entry = TypeIndexToSymbolId.find(Index); if (Entry != TypeIndexToSymbolId.end()) return Entry->second; // Symbols for built-in types are created on the fly. if (Index.isSimple()) { SymIndexId Result = createSimpleType(Index, ModifierOptions::None); assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Result; return Result; } // We need to instantiate and cache the desired type symbol. auto Tpi = Session.getPDBFile().getPDBTpiStream(); if (!Tpi) { consumeError(Tpi.takeError()); return 0; } codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection(); codeview::CVType CVT = Types.getType(Index); if (isUdtForwardRef(CVT)) { Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index); if (!EFD) consumeError(EFD.takeError()); else if (*EFD != Index) { assert(!isUdtForwardRef(Types.getType(*EFD))); SymIndexId Result = findSymbolByTypeIndex(*EFD); // Record a mapping from ForwardRef -> SymIndex of complete type so that // we'll take the fast path next time. assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Result; return Result; } } // At this point if we still have a forward ref udt it means the full decl was // not in the PDB. We just have to deal with it and use the forward ref. SymIndexId Id = 0; switch (CVT.kind()) { case codeview::LF_ENUM: Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT)); break; case codeview::LF_ARRAY: Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index, std::move(CVT)); break; case codeview::LF_CLASS: case codeview::LF_STRUCTURE: case codeview::LF_INTERFACE: Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT)); break; case codeview::LF_UNION: Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT)); break; case codeview::LF_POINTER: Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index, std::move(CVT)); break; case codeview::LF_MODIFIER: Id = createSymbolForModifiedType(Index, std::move(CVT)); break; case codeview::LF_PROCEDURE: Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>( Index, std::move(CVT)); break; case codeview::LF_MFUNCTION: Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>( Index, std::move(CVT)); break; case codeview::LF_VTSHAPE: Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>( Index, std::move(CVT)); break; default: Id = createSymbolPlaceholder(); break; } if (Id != 0) { assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Id; } return Id; }