void dump(PDBSymDumper &Dumper) const override;
+ std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
+ std::unique_ptr<PDBSymbolTypeBuiltin> getUnderlyingType() const;
+
FORWARD_SYMBOL_METHOD(getBuiltinType)
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
OS << Value.Int64;
break;
case PDB_VariantType::Int8:
- OS << Value.Int8;
+ OS << static_cast<int>(Value.Int8);
break;
case PDB_VariantType::Single:
OS << Value.Single;
OS << Value.UInt64;
break;
case PDB_VariantType::UInt8:
- OS << Value.UInt8;
+ OS << static_cast<unsigned>(Value.UInt8);
break;
default:
OS << Value.Type;
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include <utility>
std::unique_ptr<IPDBRawSymbol> Symbol)
: PDBSymbol(PDBSession, std::move(Symbol)) {}
+std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolTypeEnum::getClassParent() const {
+ return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
+}
+
+std::unique_ptr<PDBSymbolTypeBuiltin>
+PDBSymbolTypeEnum::getUnderlyingType() const {
+ return Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(getTypeId());
+}
+
void PDBSymbolTypeEnum::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
; RUN: llvm-pdbdump -symbols %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s
; RUN: llvm-pdbdump -types %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=TYPES_FORMAT %s
-; RUN: llvm-pdbdump -types -class-definitions %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=FULL_CLASS %s
; RUN: llvm-pdbdump -globals %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=GLOBALS %s
; The format is func [0x<rva_start>+<prologue_length> - 0x<rva_end>-<epilogue_length>]
; TYPES_FORMAT-DAG: typedef int IntType
; TYPES_FORMAT-DAG: typedef class A ClassAType
; TYPES_FORMAT: Classes
-; TYPES_FORMAT-DAG: class A
-; TYPES_FORMAT-DAG: class B
-
-; FULL_CLASS: ---TYPES---
-; FULL_CLASS: Classes
-; FULL_CLASS-DAG: struct A {
-; FULL_CLASS: public:
-; FULL_CLASS: virtual void PureFunc() = 0
-; FULL_CLASS: virtual void VirtualFunc()
-; FULL_CLASS: void RegularFunc()
-; FULL_CLASS: }
-; FULL_CLASS-DAG: struct MemberTest {
-; FULL_CLASS: data +0x00 MemberTest::NestedEnum m_nested_enum
-; FULL_CLASS: data +0x04 int m_typedef
-; FULL_CLASS: data +0x08 bool m_bool
-; FULL_CLASS: data +0x09 char m_char
-; FULL_CLASS: data +0x0a wchar_t m_wchar_t
-; FULL_CLASS: data +0x0c int m_int
-; FULL_CLASS: data +0x10 unsigned m_unsigned
-; FULL_CLASS: data +0x14 long m_long
-; FULL_CLASS: data +0x18 unsigned long m_unsigned_long
-; FULL_CLASS: data +0x20 __int64 m_int64
-; FULL_CLASS: data +0x28 unsigned __int64 m_unsigned_int64
-; FULL_CLASS: data +0x30 float m_float
-; FULL_CLASS: data +0x38 double m_double
-; FULL_CLASS: data +0x40 void (__cdecl *m_pfn_2_args)(int, double)
-; FULL_CLASS: }
+; TYPES_FORMAT: struct A {
+; TYPES_FORMAT: public:
+; TYPES_FORMAT: virtual void PureFunc() = 0
+; TYPES_FORMAT: virtual void VirtualFunc()
+; TYPES_FORMAT: void RegularFunc()
+; TYPES_FORMAT: }
+; TYPES_FORMAT-DAG: struct MemberTest {
+; TYPES_FORMAT: data +0x00 MemberTest::NestedEnum m_nested_enum
+; TYPES_FORMAT: data +0x04 int m_typedef
+; TYPES_FORMAT: data +0x08 bool m_bool
+; TYPES_FORMAT: data +0x09 char m_char
+; TYPES_FORMAT: data +0x0a wchar_t m_wchar_t
+; TYPES_FORMAT: data +0x0c int m_int
+; TYPES_FORMAT: data +0x10 unsigned m_unsigned
+; TYPES_FORMAT: data +0x14 long m_long
+; TYPES_FORMAT: data +0x18 unsigned long m_unsigned_long
+; TYPES_FORMAT: data +0x20 __int64 m_int64
+; TYPES_FORMAT: data +0x28 unsigned __int64 m_unsigned_int64
+; TYPES_FORMAT: data +0x30 float m_float
+; TYPES_FORMAT: data +0x38 double m_double
+; TYPES_FORMAT: data +0x40 void (__cdecl *m_pfn_2_args)(int, double)
+; TYPES_FORMAT: }
; GLOBALS: ---GLOBALS---
; GLOBALS-DAG: func [{{.*}}] (FPO) unsigned __cdecl fpo_func(unsigned n)
--- /dev/null
+; RUN: llvm-pdbdump -types %p/Inputs/ClassLayoutTest.pdb > %t\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=GLOBAL_ENUM\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=MEMBER_ENUM\r
+\r
+; GLOBAL_ENUM: ---TYPES---\r
+; GLOBAL_ENUM: Enums:\r
+; GLOBAL_ENUM: enum GlobalsTest::Enum {\r
+; GLOBAL_ENUM-NEXT: Val1 = 0\r
+; GLOBAL_ENUM-NEXT: }\r
+\r
+; MEMBER_ENUM: ---TYPES---\r
+; MEMBER_ENUM: Classes:\r
+; MEMBER_ENUM: struct __vc_attributes::threadingAttribute {\r
+; MEMBER_ENUM-NEXT: enum threading_e {\r
+; MEMBER_ENUM-NEXT: apartment = 1\r
+; MEMBER_ENUM-NEXT: single = 2\r
+; MEMBER_ENUM-NEXT: free = 3\r
+; MEMBER_ENUM-NEXT: neutral = 4\r
+; MEMBER_ENUM-NEXT: both = 5\r
+; MEMBER_ENUM-NEXT: }\r
-; RUN: llvm-pdbdump -symbols -globals -class-definitions -types %p/Inputs/FilterTest.pdb \
+; RUN: llvm-pdbdump -symbols -globals -types %p/Inputs/FilterTest.pdb \
; RUN: | FileCheck --check-prefix=NO_FILTER %s
-; RUN: llvm-pdbdump -class-definitions -types -exclude-types="GlobalTypedef|NestedTypedef" \
+; RUN: llvm-pdbdump -types -exclude-types="GlobalTypedef|NestedTypedef" \
; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_TYPEDEFS %s
-; RUN: llvm-pdbdump -class-definitions -types -exclude-types="GlobalEnum|NestedEnum" \
+; RUN: llvm-pdbdump -types -exclude-types="GlobalEnum|NestedEnum" \
; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_ENUMS %s
-; RUN: llvm-pdbdump -class-definitions -types -symbols -globals \
-; RUN: -exclude-symbols="MemberVar|GlobalVar" %p/Inputs/FilterTest.pdb | FileCheck \
-; RUN: --check-prefix=EXCLUDE_VARS %s
-; RUN: llvm-pdbdump -types -class-definitions -exclude-types="FilterTestClass" \
+; RUN: llvm-pdbdump -types -symbols -globals -exclude-symbols="MemberVar|GlobalVar" \
+; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_VARS %s
+; RUN: llvm-pdbdump -types -exclude-types="FilterTestClass" \
; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_WHOLE_CLASS %s
; RUN: llvm-pdbdump -symbols -globals -exclude-compilands="FilterTest.obj" \
; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_COMPILAND %s
BuiltinDumper.cpp
ClassDefinitionDumper.cpp
CompilandDumper.cpp
+ EnumDumper.cpp
FunctionDumper.cpp
LinePrinter.cpp
TypeDumper.cpp
//===----------------------------------------------------------------------===//
#include "ClassDefinitionDumper.h"
+#include "EnumDumper.h"
#include "FunctionDumper.h"
#include "LinePrinter.h"
#include "llvm-pdbdump.h"
return;
Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum ";
- WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
+ EnumDumper Dumper(Printer);
+ Dumper.start(Symbol);
}
void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
--- /dev/null
+//===- EnumDumper.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EnumDumper.h"
+
+#include "BuiltinDumper.h"
+#include "LinePrinter.h"
+#include "llvm-pdbdump.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+using namespace llvm;
+
+EnumDumper::EnumDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}
+
+void EnumDumper::start(const PDBSymbolTypeEnum &Symbol) {
+ WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum ";
+ WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
+ if (!opts::NoEnumDefs) {
+ auto BuiltinType = Symbol.getUnderlyingType();
+ if (BuiltinType->getBuiltinType() != PDB_BuiltinType::Int ||
+ BuiltinType->getLength() != 4) {
+ Printer << " : ";
+ BuiltinDumper Dumper(Printer);
+ Dumper.start(*BuiltinType);
+ }
+ Printer << " {";
+ Printer.Indent();
+ auto EnumValues = Symbol.findAllChildren<PDBSymbolData>();
+ while (auto EnumValue = EnumValues->getNext()) {
+ if (EnumValue->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Identifier).get()
+ << EnumValue->getName();
+ Printer << " = ";
+ WithColor(Printer, PDB_ColorItem::LiteralValue).get()
+ << EnumValue->getValue();
+ }
+ Printer.Unindent();
+ Printer.NewLine();
+ Printer << "}";
+ }
+}
--- /dev/null
+//===- EnumDumper.h - -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_ENUMDUMPER_H
+#define LLVM_TOOLS_LLVMPDBDUMP_ENUMDUMPER_H
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+namespace llvm {
+
+class LinePrinter;
+
+class EnumDumper : public PDBSymDumper {
+public:
+ EnumDumper(LinePrinter &P);
+
+ void start(const PDBSymbolTypeEnum &Symbol);
+
+private:
+ LinePrinter &Printer;
+};
+}
+
+#endif
#include "TypeDumper.h"
+#include "BuiltinDumper.h"
#include "ClassDefinitionDumper.h"
+#include "EnumDumper.h"
#include "LinePrinter.h"
#include "llvm-pdbdump.h"
#include "TypedefDumper.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
using namespace llvm;
-TypeDumper::TypeDumper(LinePrinter &P, bool ClassDefs)
- : PDBSymDumper(true), Printer(P), FullClassDefs(ClassDefs) {}
+TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}
void TypeDumper::start(const PDBSymbolExe &Exe) {
auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>();
return;
if (Printer.IsTypeExcluded(Symbol.getName()))
return;
- Printer.NewLine();
+ // Dump member enums when dumping their class definition.
+ if (Symbol.isNested())
+ return;
- WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum ";
- WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
+ Printer.NewLine();
+ EnumDumper Dumper(Printer);
+ Dumper.start(Symbol);
}
void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
Printer.NewLine();
- if (FullClassDefs) {
- ClassDefinitionDumper Dumper(Printer);
- Dumper.start(Symbol);
- } else {
+ if (opts::NoClassDefs) {
WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
+ } else {
+ ClassDefinitionDumper Dumper(Printer);
+ Dumper.start(Symbol);
}
}
class TypeDumper : public PDBSymDumper {
public:
- TypeDumper(LinePrinter &P, bool ClassDefs);
+ TypeDumper(LinePrinter &P);
void start(const PDBSymbolExe &Exe);
private:
LinePrinter &Printer;
- bool FullClassDefs;
};
}
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
if (Printer.IsSymbolExcluded(Var.getName()))
return;
- Printer.NewLine();
- Printer << "data ";
-
auto VarType = Var.getType();
switch (auto LocType = Var.getLocationType()) {
case PDB_LocType::Static:
- Printer << "[";
+ Printer.NewLine();
+ Printer << "data [";
WithColor(Printer, PDB_ColorItem::Address).get()
<< format_hex(Var.getRelativeVirtualAddress(), 10);
Printer << "] ";
dumpSymbolTypeAndName(*VarType, Var.getName());
break;
case PDB_LocType::Constant:
+ if (isa<PDBSymbolTypeEnum>(*VarType))
+ 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();
break;
case PDB_LocType::ThisRel:
+ Printer.NewLine();
+ Printer << "data ";
WithColor(Printer, PDB_ColorItem::Offset).get()
<< "+" << format_hex(Var.getOffset(), 4) << " ";
dumpSymbolTypeAndName(*VarType, Var.getName());
break;
case PDB_LocType::BitField:
+ Printer.NewLine();
+ Printer << "data ";
WithColor(Printer, PDB_ColorItem::Offset).get()
<< "+" << format_hex(Var.getOffset(), 4) << " ";
dumpSymbolTypeAndName(*VarType, Var.getName());
WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
break;
default:
+ Printer.NewLine();
+ Printer << "data ";
Printer << "unknown(" << LocType << ") ";
WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName();
break;
cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"),
cl::cat(TypeCategory));
cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory));
-cl::opt<bool>
- ClassDefs("class-definitions",
- cl::desc("Display full class definitions (implies -types)"),
- cl::cat(TypeCategory));
cl::opt<bool>
All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
cl::cat(TypeCategory));
ExcludeSystemLibraries("no-system-libs",
cl::desc("Don't show symbols from system libraries"),
cl::cat(FilterCategory));
+cl::opt<bool> NoClassDefs("no-class-definitions",
+ cl::desc("Don't display full class definitions"),
+ cl::cat(FilterCategory));
+cl::opt<bool> NoEnumDefs("no-enum-definitions",
+ cl::desc("Don't display full enum definitions"),
+ cl::cat(FilterCategory));
}
static void dumpInput(StringRef Path) {
Printer.NewLine();
WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
Printer.Indent();
- TypeDumper Dumper(Printer, opts::ClassDefs);
+ TypeDumper Dumper(Printer);
Dumper.start(*GlobalScope);
Printer.Unindent();
}
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
- if (opts::ClassDefs)
- opts::Types = true;
if (opts::All) {
opts::Compilands = true;
opts::Symbols = true;
opts::Globals = true;
opts::Types = true;
- opts::ClassDefs = true;
}
if (opts::ExcludeCompilerGenerated) {
opts::ExcludeTypes.push_back("__vc_attributes");
extern llvm::cl::opt<bool> Symbols;
extern llvm::cl::opt<bool> Globals;
extern llvm::cl::opt<bool> Types;
-extern llvm::cl::opt<bool> ClassDefs;
extern llvm::cl::opt<bool> All;
extern llvm::cl::opt<bool> ExcludeCompilerGenerated;
+extern llvm::cl::opt<bool> NoClassDefs;
+extern llvm::cl::opt<bool> NoEnumDefs;
extern llvm::cl::list<std::string> ExcludeTypes;
extern llvm::cl::list<std::string> ExcludeSymbols;
extern llvm::cl::list<std::string> ExcludeCompilands;