Example #1
0
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);
}
Example #3
0
void ScalarTraits<codeview::TypeIndex>::output(const codeview::TypeIndex &S,
                                               void *, llvm::raw_ostream &OS) {
  OS << S.getIndex();
}
Example #4
0
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;
}