diff options
| author | Zachary Turner <zturner@google.com> | 2018-09-21 22:36:28 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2018-09-21 22:36:28 +0000 |
| commit | 6345e84dde9532483c109ab0df365f64b5d8852b (patch) | |
| tree | 3a9c64941563062a050a42a0c09bf37f4239971d /llvm/lib/DebugInfo/PDB/Native | |
| parent | 355ffb0032182e74f64349dc7e4b941147bac2a2 (diff) | |
| download | bcm5719-llvm-6345e84dde9532483c109ab0df365f64b5d8852b.tar.gz bcm5719-llvm-6345e84dde9532483c109ab0df365f64b5d8852b.zip | |
[NativePDB] Add support for reading function signatures.
This adds support for parsing function signature records and returning
them through the native DIA interface.
llvm-svn: 342780
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Native')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp | 198 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp | 37 |
5 files changed, 246 insertions, 29 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp index f16b776dc65..288a9128147 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp @@ -48,15 +48,17 @@ NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, } } +NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession, + std::vector<codeview::TypeIndex> Indices) + : Matches(std::move(Indices)), Index(0), Session(PDBSession) {} + uint32_t NativeEnumTypes::getChildCount() const { return static_cast<uint32_t>(Matches.size()); } -std::unique_ptr<PDBSymbol> -NativeEnumTypes::getChildAtIndex(uint32_t Index) const { - if (Index < Matches.size()) { - SymIndexId Id = - Session.getSymbolCache().findSymbolByTypeIndex(Matches[Index]); +std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const { + if (N < Matches.size()) { + SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]); return Session.getSymbolCache().getSymbolById(Id); } return nullptr; diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index ca173808358..bcc2198a5df 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -49,6 +49,10 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const { return Session.getSymbolCache().createTypeEnumerator( {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION, codeview::LF_INTERFACE}); + case PDB_SymType::FunctionSig: + return Session.getSymbolCache().createTypeEnumerator( + {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION}); + default: break; } diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp index 824d9bd8a94..7b0f13f3c07 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp @@ -10,12 +10,13 @@ #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h" #include "llvm/Support/FormatVariadic.h" -namespace llvm { -namespace pdb { +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id, - codeview::ModifierOptions Mods, - PDB_BuiltinType T, uint64_t L) + ModifierOptions Mods, PDB_BuiltinType T, + uint64_t L) : NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id), Session(PDBSession), Mods(Mods), Type(T), Length(L) {} @@ -31,13 +32,16 @@ PDB_SymType NativeTypeBuiltin::getSymTag() const { PDB_BuiltinType NativeTypeBuiltin::getBuiltinType() const { return Type; } -bool NativeTypeBuiltin::isConstType() const { return false; } +bool NativeTypeBuiltin::isConstType() const { + return (Mods & ModifierOptions::Const) != ModifierOptions::None; +} uint64_t NativeTypeBuiltin::getLength() const { return Length; } -bool NativeTypeBuiltin::isUnalignedType() const { return false; } - -bool NativeTypeBuiltin::isVolatileType() const { return false; } +bool NativeTypeBuiltin::isUnalignedType() const { + return (Mods & ModifierOptions::Unaligned) != ModifierOptions::None; +} -} // namespace pdb -} // namespace llvm +bool NativeTypeBuiltin::isVolatileType() const { + return (Mods & ModifierOptions::Volatile) != ModifierOptions::None; +} diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp new file mode 100644 index 00000000000..a798bcdba79 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp @@ -0,0 +1,198 @@ +//===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" + +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +namespace { +// This is kind of a silly class, hence why we keep it private to the file. +// It's only purpose is to wrap the real type record. I guess this is so that +// we can have the lexical parent point to the function instead of the global +// scope. +class NativeTypeFunctionArg : public NativeRawSymbol { +public: + NativeTypeFunctionArg(NativeSession &Session, + std::unique_ptr<PDBSymbol> RealType) + : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0), + RealType(std::move(RealType)) {} + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override { + NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); + + dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, + PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); + } + + SymIndexId getTypeId() const override { return RealType->getSymIndexId(); } + + std::unique_ptr<PDBSymbol> RealType; +}; + +class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> { +public: + NativeEnumFunctionArgs(NativeSession &Session, + std::unique_ptr<NativeEnumTypes> TypeEnumerator) + : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {} + + uint32_t getChildCount() const override { + return TypeEnumerator->getChildCount(); + } + std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override { + return wrap(TypeEnumerator->getChildAtIndex(Index)); + } + std::unique_ptr<PDBSymbol> getNext() override { + return wrap(TypeEnumerator->getNext()); + } + + void reset() override { TypeEnumerator->reset(); } + +private: + std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const { + if (!S) + return nullptr; + auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S)); + return PDBSymbol::create(Session, std::move(NTFA)); + } + NativeSession &Session; + std::unique_ptr<NativeEnumTypes> TypeEnumerator; +}; +} // namespace + +NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session, + SymIndexId Id, + codeview::TypeIndex Index, + codeview::ProcedureRecord Proc) + : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id), + Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {} + +NativeTypeFunctionSig::NativeTypeFunctionSig( + NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index, + codeview::MemberFunctionRecord MemberFunc) + : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id), + MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {} + +void NativeTypeFunctionSig::initialize() { + if (IsMemberFunction) { + ClassParentId = + Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType); + initializeArgList(MemberFunc.ArgumentList); + } else { + initializeArgList(Proc.ArgumentList); + } +} + +NativeTypeFunctionSig::~NativeTypeFunctionSig() {} + +void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) { + TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream()); + CVType CVT = Tpi.typeCollection().getType(ArgListTI); + + cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList)); +} + +void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent, + PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const { + + NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); + + dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, + PdbSymbolIdField::LexicalParent, ShowIdFields, + RecurseIdFields); + + dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent); + dumpSymbolField(OS, "count", getCount(), Indent); + dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session, + PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields); + if (IsMemberFunction) + dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent); + dumpSymbolField(OS, "constructor", hasConstructor(), Indent); + dumpSymbolField(OS, "constType", isConstType(), Indent); + dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(), + Indent); + dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent); + dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); + dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); +} + +std::unique_ptr<IPDBEnumSymbols> +NativeTypeFunctionSig::findChildren(PDB_SymType Type) const { + if (Type != PDB_SymType::FunctionArg) + return llvm::make_unique<NullEnumerator<PDBSymbol>>(); + + auto NET = llvm::make_unique<NativeEnumTypes>(Session, + /* copy */ ArgList.ArgIndices); + return std::unique_ptr<IPDBEnumSymbols>( + new NativeEnumFunctionArgs(Session, std::move(NET))); +} + +SymIndexId NativeTypeFunctionSig::getClassParentId() const { + if (!IsMemberFunction) + return 0; + + return ClassParentId; +} + +PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const { + return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv; +} + +uint32_t NativeTypeFunctionSig::getCount() const { + return IsMemberFunction ? (1 + MemberFunc.getParameterCount()) + : Proc.getParameterCount(); +} + +SymIndexId NativeTypeFunctionSig::getTypeId() const { + TypeIndex ReturnTI = + IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType(); + + return Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI); +} + +int32_t NativeTypeFunctionSig::getThisAdjust() const { + return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0; +} + +bool NativeTypeFunctionSig::hasConstructor() const { + if (!IsMemberFunction) + return false; + + return (MemberFunc.getOptions() & FunctionOptions::Constructor) != + FunctionOptions::None; +} + +bool NativeTypeFunctionSig::isConstType() const { return false; } + +bool NativeTypeFunctionSig::isConstructorVirtualBase() const { + if (!IsMemberFunction) + return false; + + return (MemberFunc.getOptions() & + FunctionOptions::ConstructorWithVirtualBases) != + FunctionOptions::None; +} + +bool NativeTypeFunctionSig::isCxxReturnUdt() const { + FunctionOptions Options = + IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions(); + return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None; +} + +bool NativeTypeFunctionSig::isUnalignedType() const { return false; } + +bool NativeTypeFunctionSig::isVolatileType() const { return false; } diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp index 4fd7adf1632..d4732fd69ee 100644 --- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h" +#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -29,6 +30,7 @@ static const struct BuiltinTypeEntry { uint32_t Size; } BuiltinTypes[] = { {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0}, + {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0}, {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2}, {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4}, @@ -76,24 +78,16 @@ SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) { SymIndexId SymbolCache::createSimpleType(TypeIndex Index, ModifierOptions Mods) { - if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) { - SymIndexId Id = Cache.size(); - Cache.emplace_back( - llvm::make_unique<NativeTypePointer>(Session, Id, Index)); - return Id; - } + if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) + return createSymbol<NativeTypePointer>(Index); - SymIndexId Id = Cache.size(); 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; - Cache.emplace_back(llvm::make_unique<NativeTypeBuiltin>(Session, Id, Mods, - It->Type, It->Size)); - TypeIndexToSymbolId[Index] = Id; - return Id; + return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size); } SymIndexId @@ -135,8 +129,12 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { return Entry->second; // Symbols for built-in types are created on the fly. - if (Index.isSimple()) - return createSimpleType(Index, ModifierOptions::None); + 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(); @@ -157,6 +155,7 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { 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; } @@ -184,12 +183,22 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { 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; default: Id = createSymbolPlaceholder(); break; } - if (Id != 0) + if (Id != 0) { + assert(TypeIndexToSymbolId.count(Index) == 0); TypeIndexToSymbolId[Index] = Id; + } return Id; } |

