Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymDumper.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymDumper.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymDumper.h @@ -54,6 +54,22 @@ virtual void dump(const PDBSymbolUnknown &Symbol); virtual void dump(const PDBSymbolUsingNamespace &Symbol); + virtual void dumpRight(const PDBSymbolTypeArray &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeBaseClass &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeBuiltin &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeCustom &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeDimension &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeEnum &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFriend &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFunctionArg &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFunctionSig &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeManaged &Symbol) {} + virtual void dumpRight(const PDBSymbolTypePointer &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeTypedef &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeUDT &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeVTable &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeVTableShape &Symbol) {} + private: bool RequireImpl; }; Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h @@ -74,6 +74,11 @@ /// unknown properties, but individual implementations of PDBSymbol may /// override the behavior to only dump known fields. virtual void dump(PDBSymDumper &Dumper) const = 0; + + /// For certain PDBSymbolTypes, dumps additional information for the type that + /// normally goes on the right side of the symbol. + virtual void dumpRight(PDBSymDumper &Dumper) const {} + void defaultDump(raw_ostream &OS, int Indent) const; void dumpProperties() const; void dumpChildStats() const; Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h @@ -26,6 +26,7 @@ DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType) void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_ID_METHOD(getArrayIndexType) FORWARD_SYMBOL_METHOD(isConstType) Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h @@ -28,6 +28,7 @@ std::unique_ptr getArguments() const; void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; void dumpArgList(raw_ostream &OS) const; FORWARD_SYMBOL_METHOD(getCallingConvention) Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h @@ -26,6 +26,7 @@ DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType) void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getLength) Index: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp @@ -26,3 +26,7 @@ void PDBSymbolTypeArray::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } + +void PDBSymbolTypeArray::dumpRight(PDBSymDumper &Dumper) const { + Dumper.dumpRight(*this); +} Index: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp @@ -80,3 +80,7 @@ void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } + +void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const { + Dumper.dumpRight(*this); +} Index: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp @@ -26,3 +26,7 @@ void PDBSymbolTypePointer::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } + +void PDBSymbolTypePointer::dumpRight(PDBSymDumper &Dumper) const { + Dumper.dumpRight(*this); +} Index: llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test =================================================================== --- llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test +++ llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-linenumbers.test @@ -1,12 +1,14 @@ +; RUN: llvm-pdbdump pretty -lines %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=LINE_NUMS_FPO %s ; RUN: llvm-pdbdump pretty -lines %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=LINE_NUMS %s -; LINE_NUMS: llvm\test\debuginfo\pdb\inputs\symbolformat-fpo.cpp -; LINE_NUMS: Line 5, Address: [0x000011a0 - 0x000011a5] (6 bytes) -; LINE_NUMS: Line 6, Address: [0x000011a6 - 0x000011a6] (1 bytes) +; LINE_NUMS_FPO: llvm\test\debuginfo\pdb\inputs\symbolformat-fpo.cpp +; LINE_NUMS_FPO: Line 5, Address: [0x000011a0 - 0x000011a5] (6 bytes) +; LINE_NUMS_FPO: Line 6, Address: [0x000011a6 - 0x000011a6] (1 bytes) + ; LINE_NUMS: llvm\test\debuginfo\pdb\inputs\symbolformat.cpp ; LINE_NUMS: Line 6, Address: [0x00001060 - 0x00001066] (7 bytes) -; LINE_NUMS: Line 72, Address: [0x000010d0 - 0x000010d1] (2 bytes) -; LINE_NUMS: Line 73, Address: [0x000010d2 - 0x000010d5] (4 bytes) +; LINE_NUMS: Line 80, Address: [0x000010d0 - 0x000010d1] (2 bytes) +; LINE_NUMS: Line 81, Address: [0x000010d2 - 0x000010d5] (4 bytes) ; LINE_NUMS: Line 28, Address: [0x00001170 - 0x0000117a] (11 bytes) ; LINE_NUMS: Line 21, Address: [0x00001180 - 0x0000118a] (11 bytes) -; LINE_NUMS: Line 20, Address: [0x00001190 - 0x0000119a] (11 bytes) \ No newline at end of file +; LINE_NUMS: Line 20, Address: [0x00001190 - 0x0000119a] (11 bytes) Index: llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test =================================================================== --- llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test +++ llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test @@ -1,3 +1,4 @@ +; RUN: llvm-pdbdump pretty -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT_FPO %s ; RUN: llvm-pdbdump pretty -symbols %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s ; RUN: llvm-pdbdump pretty -types %p/../Inputs/symbolformat.pdb > %t.types ; RUN: FileCheck --check-prefix=TYPES_FORMAT %s < %t.types @@ -7,9 +8,11 @@ ; RUN: llvm-pdbdump pretty -globals %p/../Inputs/symbolformat.pdb | FileCheck --check-prefix=GLOBALS %s ; The format is func [0x+ - 0x-] +; SYM_FORMAT_FPO: ---SYMBOLS--- +; SYM_FORMAT_FPO: symbolformat-fpo.obj +; SYM_FORMAT-FPO: func [{{.*}}] (FPO) unsigned int __cdecl fpo_func(unsigned int n) + ; SYM_FORMAT: ---SYMBOLS--- -; SYM_FORMAT: symbolformat-fpo.obj -; SYM_FORMAT-DAG: func [{{.*}}] (FPO) unsigned int __cdecl fpo_func(unsigned int n) ; SYM_FORMAT: symbolformat.obj ; SYM_FORMAT-DAG: func [{{.*}}] (EBP) int __cdecl _purecall() ; SYM_FORMAT-DAG: func [{{.*}}] (EBP) int __cdecl main(int argc, char** argv) @@ -50,10 +53,16 @@ ; TYPES_2: data +0x28 unsigned __int64 m_unsigned_int64 ; TYPES_2: data +0x30 float m_float ; TYPES_2: data +0x38 double m_double -; TYPES_2: data +0x40 void (__cdecl *m_pfn_2_args)(int, double) +; TYPES_2: data +0x40 void (__cdecl * m_pfn_2_args)(int, double) +; TYPES_2: data +0x44 int m_multidimensional_array[2][3] ; TYPES_2: } ; GLOBALS: ---GLOBALS--- ; GLOBALS-DAG: func [{{.*}}] (FPO) unsigned int __cdecl fpo_func(unsigned int n) ; GLOBALS-DAG: data [{{.*}}] static void* g_global_pointer ; GLOBALS-DAG: data [{{.*}}] static int g_global_int +; GLOBALS-DAG: data [{{.*}}] static int g_array[3] +; GLOBALS-DAG: data [{{.*}}] static int (* g_pointer_to_array)[3] +; GLOBALS-DAG: data [{{.*}}] static const int* g_pointer_to_const_int +; GLOBALS-DAG: data int* const g_const_pointer_to_int = 0 +; GLOBALS-DAG: data const int* const g_const_pointer_to_const_int = 0 Index: llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp =================================================================== --- llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp +++ llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp @@ -50,6 +50,7 @@ float m_float; double m_double; void (*m_pfn_2_args)(int, double); + int m_multidimensional_array[2][3]; }; typedef int IntType; @@ -58,6 +59,13 @@ int g_global_int; void *g_global_pointer = nullptr; +typedef int int_array[3]; +int_array g_array = { 1, 2, 3 }; +int_array *g_pointer_to_array = &g_array; +const int *g_pointer_to_const_int = nullptr; +int * const g_const_pointer_to_int = nullptr; +const int * const g_const_pointer_to_const_int = nullptr; + int main(int argc, char **argv) { // Force symbol references so the linker generates debug info B b; Index: llvm/trunk/tools/llvm-pdbdump/PrettyBuiltinDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbdump/PrettyBuiltinDumper.cpp +++ llvm/trunk/tools/llvm-pdbdump/PrettyBuiltinDumper.cpp @@ -20,6 +20,10 @@ : PDBSymDumper(false), Printer(P) {} void BuiltinDumper::start(const PDBSymbolTypeBuiltin &Symbol) { + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; WithColor(Printer, PDB_ColorItem::Type).get() << getTypeName(Symbol); } Index: llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h =================================================================== --- llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h +++ llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h @@ -26,6 +26,7 @@ void start(const PDBSymbolData &Var); + void dump(const PDBSymbolTypeArray &Symbol) override; void dump(const PDBSymbolTypeBuiltin &Symbol) override; void dump(const PDBSymbolTypeEnum &Symbol) override; void dump(const PDBSymbolTypeFunctionSig &Symbol) override; @@ -33,9 +34,12 @@ void dump(const PDBSymbolTypeTypedef &Symbol) override; void dump(const PDBSymbolTypeUDT &Symbol) override; + void dumpRight(const PDBSymbolTypeArray &Symbol) override; + void dumpRight(const PDBSymbolTypeFunctionSig &Symbol) override; + void dumpRight(const PDBSymbolTypePointer &Symbol) override; + private: void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name); - bool tryDumpFunctionPointer(const PDBSymbol &Type, StringRef Name); LinePrinter &Printer; }; Index: llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp +++ llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp @@ -14,6 +14,7 @@ #include "PrettyFunctionDumper.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" @@ -23,10 +24,12 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/Format.h" using namespace llvm; +using namespace llvm::codeview; using namespace llvm::pdb; VariableDumper::VariableDumper(LinePrinter &P) @@ -55,7 +58,6 @@ break; Printer.NewLine(); Printer << "data "; - WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; dumpSymbolTypeAndName(*VarType, Var.getName()); Printer << " = "; WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue(); @@ -85,6 +87,23 @@ } } +void VariableDumper::dump(const PDBSymbolTypeArray &Symbol) { + auto ElementType = Symbol.getElementType(); + assert(ElementType); + if (!ElementType) + return; + ElementType->dump(*this); +} + +void VariableDumper::dumpRight(const PDBSymbolTypeArray &Symbol) { + auto ElementType = Symbol.getElementType(); + assert(ElementType); + if (!ElementType) + return; + Printer << '[' << Symbol.getCount() << ']'; + ElementType->dumpRight(*this); +} + void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { BuiltinDumper Dumper(Printer); Dumper.start(Symbol); @@ -94,27 +113,71 @@ WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); } -void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {} +void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) { + auto ReturnType = Symbol.getReturnType(); + ReturnType->dump(*this); + Printer << " "; + + uint32_t ClassParentId = Symbol.getClassParentId(); + auto ClassParent = + Symbol.getSession().getConcreteSymbolById( + ClassParentId); + + if (ClassParent) { + WithColor(Printer, PDB_ColorItem::Identifier).get() + << ClassParent->getName(); + Printer << "::"; + } +} + +void VariableDumper::dumpRight(const PDBSymbolTypeFunctionSig &Symbol) { + Printer << "("; + if (auto Arguments = Symbol.getArguments()) { + uint32_t Index = 0; + while (auto Arg = Arguments->getNext()) { + Arg->dump(*this); + if (++Index < Arguments->getChildCount()) + Printer << ", "; + } + } + Printer << ")"; + + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const"; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile"; +} void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) { auto PointeeType = Symbol.getPointeeType(); if (!PointeeType) return; + PointeeType->dump(*this); + if (auto Func = PointeeType->cast()) { + // A hack to get the calling convention in the right spot. + Printer << " ("; + PDB_CallingConv CC = Func->getCallingConvention(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " "; + } else if (isa(PointeeType.get())) { + Printer << " ("; + } + Printer << (Symbol.isReference() ? "&" : "*"); + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const "; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile "; +} - if (auto Func = PointeeType->cast()) { - FunctionDumper NestedDumper(Printer); - FunctionDumper::PointerType Pointer = - Symbol.isReference() ? FunctionDumper::PointerType::Reference - : FunctionDumper::PointerType::Pointer; - NestedDumper.start(*Func, Pointer); - } else { - if (Symbol.isConstType()) - WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; - if (Symbol.isVolatileType()) - WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; - PointeeType->dump(*this); - Printer << (Symbol.isReference() ? "&" : "*"); +void VariableDumper::dumpRight(const PDBSymbolTypePointer &Symbol) { + auto PointeeType = Symbol.getPointeeType(); + assert(PointeeType); + if (!PointeeType) + return; + if (isa(PointeeType.get()) || + isa(PointeeType.get())) { + Printer << ")"; } + PointeeType->dumpRight(*this); } void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) { @@ -128,43 +191,7 @@ void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name) { - if (auto *ArrayType = Type.cast()) { - std::string IndexSpec; - raw_string_ostream IndexStream(IndexSpec); - std::unique_ptr ElementType = ArrayType->getElementType(); - while (auto NestedArray = ElementType->cast()) { - IndexStream << "["; - IndexStream << NestedArray->getCount(); - IndexStream << "]"; - ElementType = NestedArray->getElementType(); - } - IndexStream << "[" << ArrayType->getCount() << "]"; - ElementType->dump(*this); - WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; - Printer << IndexStream.str(); - } else { - if (!tryDumpFunctionPointer(Type, Name)) { - Type.dump(*this); - WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; - } - } -} - -bool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type, - StringRef Name) { - // Function pointers come across as pointers to function signatures. But the - // signature carries no name, so we have to handle this case separately. - if (auto *PointerType = Type.cast()) { - auto PointeeType = PointerType->getPointeeType(); - if (auto *FunctionSig = PointeeType->cast()) { - FunctionDumper Dumper(Printer); - FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer; - if (PointerType->isReference()) - PT = FunctionDumper::PointerType::Reference; - std::string NameStr(Name.begin(), Name.end()); - Dumper.start(*FunctionSig, NameStr.c_str(), PT); - return true; - } - } - return false; + Type.dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; + Type.dumpRight(*this); }