diff options
19 files changed, 1338 insertions, 49 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h index 492caf7ee4a..f8ac1655dc6 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h @@ -28,6 +28,9 @@ public: codeview::LazyRandomTypeCollection &TypeCollection, std::vector<codeview::TypeLeafKind> Kinds); + NativeEnumTypes(NativeSession &Session, + std::vector<codeview::TypeIndex> Indices); + uint32_t getChildCount() const override; std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; std::unique_ptr<PDBSymbol> getNext() override; diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index 86c7a4c4167..6505a7d3957 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -20,6 +20,9 @@ namespace pdb { class NativeSession; class NativeRawSymbol : public IPDBRawSymbol { + friend class SymbolCache; + virtual void initialize() {} + public: NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag, SymIndexId SymbolId); diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h new file mode 100644 index 00000000000..1b1b87f6581 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h @@ -0,0 +1,74 @@ +//===- NativeTypeFunctionSig.h - 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEFUNCTIONSIG_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEFUNCTIONSIG_H + +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeUDT; + +class NativeTypeFunctionSig : public NativeRawSymbol { +protected: + void initialize() override; + +public: + NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::ProcedureRecord Proc); + + NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, + codeview::MemberFunctionRecord MemberFunc); + + ~NativeTypeFunctionSig() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type) const override; + + SymIndexId getClassParentId() const override; + PDB_CallingConv getCallingConvention() const override; + uint32_t getCount() const override; + SymIndexId getTypeId() const override; + int32_t getThisAdjust() const override; + bool hasConstructor() const override; + bool isConstType() const override; + bool isConstructorVirtualBase() const override; + bool isCxxReturnUdt() const override; + bool isUnalignedType() const override; + bool isVolatileType() const override; + +private: + void initializeArgList(codeview::TypeIndex ArgListTI); + + union { + codeview::MemberFunctionRecord MemberFunc; + codeview::ProcedureRecord Proc; + }; + + SymIndexId ClassParentId = 0; + codeview::TypeIndex Index; + codeview::ArgListRecord ArgList; + bool IsMemberFunction = false; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
\ No newline at end of file diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h index a2fd07ab29d..e2f25d19ef6 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h @@ -1,5 +1,4 @@ -//===- NativeTypePointer.h - info about pointer type ------------------*- C++ -//-*-===// +//===- NativeTypePointer.h - info about pointer type -------------*- C++-*-===// // // The LLVM Compiler Infrastructure // diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h index c0ffff70c62..6b1c3c27973 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h @@ -68,9 +68,18 @@ public: SymIndexId createSymbol(Args &&... ConstructorArgs) { SymIndexId Id = Cache.size(); + // Initial construction must not access the cache, since it must be done + // atomically. auto Result = llvm::make_unique<ConcreteSymbolT>( Session, Id, std::forward<Args>(ConstructorArgs)...); + Result->SymbolId = Id; + + NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get()); Cache.push_back(std::move(Result)); + + // After the item is in the cache, we can do further initialization which + // is then allowed to access the cache. + NRS->initialize(); return Id; } @@ -89,13 +98,11 @@ public: SymIndexId SymId = Cache.size(); std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index}; auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId); - if (Result.second) { - auto NewSymbol = llvm::make_unique<ConcreteSymbolT>( - Session, SymId, std::forward<Args>(ConstructorArgs)...); - Cache.push_back(std::move(NewSymbol)); - } else { + if (Result.second) + SymId = + createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...); + else SymId = Result.first->second; - } return SymId; } diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index db39ba3b0ee..3ec5d0519ef 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -54,6 +54,7 @@ add_pdb_impl_folder(Native Native/NativeSymbolEnumerator.cpp Native/NativeTypeBuiltin.cpp Native/NativeTypeEnum.cpp + Native/NativeTypeFunctionSig.cpp Native/NativeTypePointer.cpp Native/NativeTypeUDT.cpp Native/NamedStreamMap.cpp diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp index 9ec2f742933..5fa783d7134 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp @@ -245,7 +245,7 @@ void DIARawSymbol::dump(raw_ostream &OS, int Indent, RAW_METHOD_DUMP(OS, baseSymbolId); RAW_METHOD_DUMP_AS(OS, baseType, PDB_BuiltinType); RAW_METHOD_DUMP(OS, bitPosition); - RAW_METHOD_DUMP(OS, callingConvention); + RAW_METHOD_DUMP_AS(OS, callingConvention, PDB_CallingConv); RAW_ID_METHOD_DUMP(OS, classParentId, Session, PdbSymbolIdField::ClassParent, ShowIdFields, RecurseIdFields); RAW_METHOD_DUMP(OS, compilerName); 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; } diff --git a/llvm/test/DebugInfo/PDB/Inputs/every-function.cpp b/llvm/test/DebugInfo/PDB/Inputs/every-function.cpp new file mode 100644 index 00000000000..71e8f08f4ce --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Inputs/every-function.cpp @@ -0,0 +1,80 @@ +// Build with "cl.exe /Zi /GR- /GS- -EHs-c- every-function.cpp /link /debug /nodefaultlib /incremental:no /entry:main" +// Getting functions with the correct calling conventions requires building in x86. + +// clang-format off +void *__purecall = 0; + +void __cdecl operator delete(void *,unsigned int) {} +void __cdecl operator delete(void *,unsigned __int64) {} + +// All calling conventions that appear in normal code. +int __cdecl cc_cdecl() { return 42; } +int __stdcall cc_stdcall() { return 42; } +int __fastcall cc_fastcall() { return 42; } +int __vectorcall cc_vectorcall() { return 42; } + + +struct Struct { + Struct() {} // constructor + + int __thiscall cc_thiscall() { return 42; } + + void M() { } + void CM() const { } + void VM() volatile { } + void CVM() const volatile { } +}; + +int builtin_one_param(int x) { return 42; } +int builtin_two_params(int x, char y) { return 42; } + +void struct_one_param(Struct S) { } + +void modified_builtin_param(const int X) { } +void modified_struct_param(const Struct S) { } + +void pointer_builtin_param(int *X) { } +void pointer_struct_param(Struct *S) { } + + +void modified_pointer_builtin_param(const int *X) { } +void modified_pointer_struct_param(const Struct *S) { } + +Struct rvo() { return Struct(); } + +struct Base1 { + virtual ~Base1() {} +}; + +struct Base2 : public virtual Base1 { }; + +struct Derived : public virtual Base1, public Base2 { +}; + + +int main() { + cc_cdecl(); + cc_stdcall(); + cc_fastcall(); + Struct().cc_thiscall(); + cc_vectorcall(); + + builtin_one_param(42); + builtin_two_params(42, 'x'); + struct_one_param(Struct{}); + + modified_builtin_param(42); + modified_struct_param(Struct()); + + pointer_builtin_param(nullptr); + pointer_struct_param(nullptr); + + + modified_pointer_builtin_param(nullptr); + modified_pointer_struct_param(nullptr); + + Struct S = rvo(); + + Derived D; + return 42; +} diff --git a/llvm/test/DebugInfo/PDB/Inputs/every-function.pdb b/llvm/test/DebugInfo/PDB/Inputs/every-function.pdb Binary files differnew file mode 100644 index 00000000000..35eaa6e23bc --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Inputs/every-function.pdb diff --git a/llvm/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test b/llvm/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test new file mode 100644 index 00000000000..63fd9d92ca1 --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test @@ -0,0 +1,865 @@ +; Test that the native PDB reader can enumerate pointer types. The output +; being checked against is golden output generated by llvm-pdbutil without +; the -native flag. Then we check that we generate the same output. + +; RUN: llvm-pdbutil pretty -native -funcsigs %p/../Inputs/every-function.pdb \ +; RUN: | FileCheck -check-prefix=PRETTY %s + +; RUN: llvm-pdbutil diadump -native -funcsigs %p/../Inputs/every-function.pdb \ +; RUN: | FileCheck -check-prefix=DUMP %s + + +; PRETTY: void __cdecl (void*, unsigned int) +; PRETTY-NEXT: void __cdecl (void*, unsigned __int64) +; PRETTY-NEXT: int __cdecl () +; PRETTY-NEXT: int () +; PRETTY-NEXT: int __fastcall () +; PRETTY-NEXT: int __vectorcall () +; PRETTY-NEXT: int __cdecl (int) +; PRETTY-NEXT: int __cdecl (int, char) +; PRETTY-NEXT: void __cdecl (Struct) +; PRETTY-NEXT: void (Struct::)() +; PRETTY-NEXT: int (Struct::)() +; PRETTY-NEXT: void (Struct::)() +; PRETTY-NEXT: void (Struct::)() +; PRETTY-NEXT: void (Struct::)() +; PRETTY-NEXT: void (Struct::)() +; PRETTY-NEXT: void __cdecl (const int) +; PRETTY-NEXT: void __cdecl (Struct) +; PRETTY-NEXT: void __cdecl (int*) +; PRETTY-NEXT: void __cdecl (Struct*) +; PRETTY-NEXT: void __cdecl (const int*) +; PRETTY-NEXT: void __cdecl (Struct*) +; PRETTY-NEXT: Struct __cdecl () +; PRETTY-NEXT: void (Derived::)(Derived*) +; PRETTY-NEXT: void (Derived::)(Derived&) +; PRETTY-NEXT: void (Derived::)() +; PRETTY-NEXT: void (Derived::)() +; PRETTY-NEXT: Derived& (Derived::)(Derived*) +; PRETTY-NEXT: Derived& (Derived::)(Derived&) +; PRETTY-NEXT: void (Derived::)() +; PRETTY-NEXT: void* (Derived::)(unsigned int) +; PRETTY-NEXT: void (__vc_attributes::event_sourceAttribute::)(__vc_attributes::event_sourceAttribute::type_e) +; PRETTY-NEXT: void (__vc_attributes::event_sourceAttribute::)() +; PRETTY-NEXT: void (__vc_attributes::helper_attributes::v1_alttypeAttribute::)(__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e) +; PRETTY-NEXT: void (__vc_attributes::helper_attributes::usageAttribute::)(unsigned int) +; PRETTY-NEXT: void (__vc_attributes::threadingAttribute::)(__vc_attributes::threadingAttribute::threading_e) +; PRETTY-NEXT: void (__vc_attributes::threadingAttribute::)() +; PRETTY-NEXT: void (__vc_attributes::aggregatableAttribute::)(__vc_attributes::aggregatableAttribute::type_e) +; PRETTY-NEXT: void (__vc_attributes::aggregatableAttribute::)() +; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)(__vc_attributes::event_receiverAttribute::type_e, bool) +; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)(__vc_attributes::event_receiverAttribute::type_e) +; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)() +; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)(__vc_attributes::moduleAttribute::type_e, const char*, const char*, const char*, int, bool, const char*, int, const char*, const char*, int, bool, bool, const char*, const char*) +; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)(__vc_attributes::moduleAttribute::type_e) +; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)() +; PRETTY-NEXT: void (Base1::)() +; PRETTY-NEXT: void (Base1::)(Base1&) +; PRETTY-NEXT: void (Base1::)() +; PRETTY-NEXT: Base1& (Base1::)(Base1&) +; PRETTY-NEXT: void* (Base1::)(unsigned int) +; PRETTY-NEXT: void (Base2::)(Base2*) +; PRETTY-NEXT: void (Base2::)(Base2&) +; PRETTY-NEXT: void (Base2::)() +; PRETTY-NEXT: void (Base2::)() +; PRETTY-NEXT: Base2& (Base2::)(Base2*) +; PRETTY-NEXT: Base2& (Base2::)(Base2&) +; PRETTY-NEXT: void (Base2::)() +; PRETTY-NEXT: void* (Base2::)(unsigned int) +; PRETTY-NEXT: void __cdecl () + +; DUMP: { +; DUMP-NEXT: symIndexId: 2 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 4 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 5 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 7 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __stdcall +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 8 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __fastcall +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 9 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __vectorcall +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 10 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 11 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 12 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 13 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 15 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 6 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 16 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 17 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 18 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 19 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 20 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 21 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 22 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 23 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 24 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 25 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 26 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 14 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 1 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 27 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 29 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 30 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 31 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 4 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 32 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 33 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 34 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 33 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 35 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 36 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 37 +; DUMP-NEXT: thisAdjust: 4 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 38 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 40 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 41 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 43 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 45 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 47 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 48 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 50 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 51 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 3 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 53 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 54 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 55 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 16 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 57 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 58 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 59 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 61 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 62 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 63 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 64 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 65 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 37 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 66 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 68 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 69 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 1 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 1 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 70 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 4 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 71 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 72 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 73 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 72 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 74 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 1 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: thisAdjust: 0 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 75 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __thiscall +; DUMP-NEXT: count: 2 +; DUMP-NEXT: typeId: 37 +; DUMP-NEXT: thisAdjust: 4 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } +; DUMP-NEXT: { +; DUMP-NEXT: symIndexId: 76 +; DUMP-NEXT: symTag: FunctionSig +; DUMP-NEXT: callingConvention: __cdecl +; DUMP-NEXT: count: 0 +; DUMP-NEXT: typeId: 3 +; DUMP-NEXT: constructor: 0 +; DUMP-NEXT: constType: 0 +; DUMP-NEXT: isConstructorVirtualBase: 0 +; DUMP-NEXT: isCxxReturnUdt: 0 +; DUMP-NEXT: unalignedType: 0 +; DUMP-NEXT: volatileType: 0 +; DUMP-NEXT: } diff --git a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp index 8eea4c2fb20..a5a88aa1071 100644 --- a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp +++ b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.cpp @@ -13,6 +13,7 @@ #include "PrettyBuiltinDumper.h" #include "PrettyClassDefinitionDumper.h" #include "PrettyEnumDumper.h" +#include "PrettyFunctionDumper.h" #include "PrettyTypedefDumper.h" #include "llvm-pdbutil.h" @@ -20,6 +21,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "llvm/DebugInfo/PDB/UDTLayout.h" @@ -147,6 +149,19 @@ void TypeDumper::start(const PDBSymbolExe &Exe) { } } + if (opts::pretty::Funcsigs) { + if (auto Funcsigs = Exe.findAllChildren<PDBSymbolTypeFunctionSig>()) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() + << "Function Signatures"; + Printer << ": (" << Funcsigs->getChildCount() << " items)"; + Printer.Indent(); + while (auto FS = Funcsigs->getNext()) + FS->dump(*this); + Printer.Unindent(); + } + } + if (opts::pretty::Typedefs) { if (auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>()) { Printer.NewLine(); @@ -251,6 +266,12 @@ void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) { Dumper.start(Symbol); } +void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) { + Printer.NewLine(); + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, nullptr, FunctionDumper::PointerType::None); +} + void TypeDumper::dumpClassLayout(const ClassLayout &Class) { assert(opts::pretty::Classes); diff --git a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.h b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.h index 68a2f0246eb..b94c4feef5f 100644 --- a/llvm/tools/llvm-pdbutil/PrettyTypeDumper.h +++ b/llvm/tools/llvm-pdbutil/PrettyTypeDumper.h @@ -25,6 +25,7 @@ public: void dump(const PDBSymbolTypeEnum &Symbol) override; void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeFunctionSig &Symbol) override; void dumpClassLayout(const ClassLayout &Class); diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp index 4ce1922a006..e90783c80aa 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -70,6 +70,8 @@ #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "llvm/Support/BinaryByteStream.h" @@ -188,6 +190,9 @@ static cl::opt<bool> UDTs("udts", cl::desc("Dump udt types"), static cl::opt<bool> Compilands("compilands", cl::desc("Dump compiland information"), cl::sub(DiaDumpSubcommand)); +static cl::opt<bool> Funcsigs("funcsigs", + cl::desc("Dump function signature information"), + cl::sub(DiaDumpSubcommand)); } // namespace diadump namespace pretty { @@ -236,6 +241,8 @@ cl::opt<bool> Enums("enums", cl::desc("Display enum types"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt<bool> Typedefs("typedefs", cl::desc("Display typedef types"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); +cl::opt<bool> Funcsigs("funcsigs", cl::desc("Display function signatures"), + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt<SymbolSortMode> SymbolOrder( "symbol-order", cl::desc("symbol sort order"), cl::init(SymbolSortMode::None), @@ -969,6 +976,21 @@ static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) { } } +template <typename OuterT, typename ChildT> +void diaDumpChildren(PDBSymbol &Outer, PdbSymbolIdField Ids, + PdbSymbolIdField Recurse) { + OuterT *ConcreteOuter = dyn_cast<OuterT>(&Outer); + if (!ConcreteOuter) + return; + + auto Children = ConcreteOuter->template findAllChildren<ChildT>(); + while (auto Child = Children->getNext()) { + outs() << " {"; + Child->defaultDump(outs(), 4, Ids, Recurse); + outs() << "\n }\n"; + } +} + static void dumpDia(StringRef Path) { std::unique_ptr<IPDBSession> Session; @@ -988,6 +1010,8 @@ static void dumpDia(StringRef Path) { SymTypes.push_back(PDB_SymType::PointerType); if (opts::diadump::UDTs) SymTypes.push_back(PDB_SymType::UDT); + if (opts::diadump::Funcsigs) + SymTypes.push_back(PDB_SymType::FunctionSig); PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None : PdbSymbolIdField::All; @@ -1002,19 +1026,11 @@ static void dumpDia(StringRef Path) { while (auto Child = Children->getNext()) { outs() << "{"; Child->defaultDump(outs(), 2, Ids, Recurse); - if (auto Enum = dyn_cast<PDBSymbolTypeEnum>(Child.get())) { - auto Enumerators = Enum->findAllChildren<PDBSymbolData>(); - while (auto Enumerator = Enumerators->getNext()) { - outs() << " {"; - Enumerator->defaultDump(outs(), 4, Ids, Recurse); - outs() << "\n }\n"; - } - } + + diaDumpChildren<PDBSymbolTypeEnum, PDBSymbolData>(*Child, Ids, Recurse); outs() << "\n}\n"; } } - auto Child = Session->getSymbolById(3); - Child->defaultDump(outs(), 2, PdbSymbolIdField::All, PdbSymbolIdField::None); } static void dumpPretty(StringRef Path) { @@ -1162,7 +1178,8 @@ static void dumpPretty(StringRef Path) { } } - if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs) { + if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs || + opts::pretty::Funcsigs) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; Printer.Indent(); diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h index d25b0b6e8eb..234beb36e03 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h @@ -82,6 +82,7 @@ extern llvm::cl::opt<bool> Symbols; extern llvm::cl::opt<bool> Globals; extern llvm::cl::opt<bool> Classes; extern llvm::cl::opt<bool> Enums; +extern llvm::cl::opt<bool> Funcsigs; extern llvm::cl::opt<bool> Typedefs; extern llvm::cl::opt<bool> All; extern llvm::cl::opt<bool> ExcludeCompilerGenerated; |