llvm-pdbdump: Add flags controlling the type of values to dump.
authorZachary Turner <zturner@google.com>
Sun, 15 Feb 2015 20:27:53 +0000 (20:27 +0000)
committerZachary Turner <zturner@google.com>
Sun, 15 Feb 2015 20:27:53 +0000 (20:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229330 91177308-0d34-0410-b5e6-96231b3b80d8

66 files changed:
include/llvm/DebugInfo/PDB/PDBSymbol.h
include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
include/llvm/DebugInfo/PDB/PDBSymbolData.h
include/llvm/DebugInfo/PDB/PDBSymbolExe.h
include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
include/llvm/DebugInfo/PDB/PDBTypes.h
lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
lib/DebugInfo/PDB/PDBSymbolBlock.cpp
lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
lib/DebugInfo/PDB/PDBSymbolCustom.cpp
lib/DebugInfo/PDB/PDBSymbolData.cpp
lib/DebugInfo/PDB/PDBSymbolExe.cpp
lib/DebugInfo/PDB/PDBSymbolFunc.cpp
lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
lib/DebugInfo/PDB/PDBSymbolLabel.cpp
lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
lib/DebugInfo/PDB/PDBSymbolThunk.cpp
lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
tools/llvm-pdbdump/llvm-pdbdump.cpp

index 500fa7a456719944359e276edb437852110faa26..4f1ca5f627d86ce60ee053fac69235c54b8ffc3b 100644 (file)
@@ -53,7 +53,7 @@ public:
   /// call dump() on the underlying RawSymbol, which allows us to discover
   /// unknown properties, but individual implementations of PDBSymbol may
   /// override the behavior to only dump known fields.
-  virtual void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const = 0;
+  virtual void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const = 0;
   void defaultDump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const;
 
   PDB_SymType getSymTag() const;
index e5ba65ff63e833281edd2975212a1dc643ca84fd..b931b0780d8590c235dca84d47ab937303d646f3 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Annotation)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index d30ed577b60de16c46247cb1222a9815214a3140..6462159833bfaaabe2e0c22cd988af6950250772 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Block)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index 04a0712f2da9a4e4fdde36963eb4d7f16dc92621..0363c8600c37b6c3ec37edd16190841ec52518a2 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Compiland)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled)
   FORWARD_SYMBOL_METHOD(getLexicalParentId)
index d0338550d89c28fb8e1a0c5db37ac15eb6de40ab..83ca9b5bf6437be0dafafb3e6450adb40e448d8d 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandDetails)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   void getFrontEndVersion(VersionInfo &Version) const {
     RawSymbol->getFrontEndVersion(Version);
index c31a33924cc75614c550baa403eb89067fd43f78..5f621b956a91d9361046039ed73d087937b5b0d5 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandEnv)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getLexicalParentId)
   FORWARD_SYMBOL_METHOD(getName)
index eab4b08fecf1f81dcda58995204cb146f2b5dd61..741d073b942a1c1e94191dcf79b240d4fe275912 100644 (file)
@@ -28,7 +28,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Custom)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes);
   FORWARD_SYMBOL_METHOD(getSymIndexId)
index c99ef63f8e75bb16ac928992d9a0b15fd38a3a7e..f6eca3ec61bada9c0fd35fef0bc743c3cfe5ca7e 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAccess)
   FORWARD_SYMBOL_METHOD(getAddressOffset)
index cdb6a326d888d9766e490d18a49ff2cfc0f7e83a..a5327f309b7b0bd14165ec5912957d559fe89521 100644 (file)
@@ -25,7 +25,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Exe)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAge)
   FORWARD_SYMBOL_METHOD(getGuid)
index a521acff547fc03c06415bb262ff7688c082ef94..030e57fd51a034cddd562cb1d2fc0c4e61979b66 100644 (file)
@@ -22,7 +22,7 @@ public:
   PDBSymbolFunc(const IPDBSession &PDBSession,
                 std::unique_ptr<IPDBRawSymbol> FuncSymbol);
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;
 
index e974375481a698d2201578d83f1068e7ddd3ba26..9e4697ff3cf2b7082b7c5ff0328394df94cc3354 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugEnd)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index 99de8c063065e48ad06ab534e2ea3ec9e46f03eb..36bc1679d8018e2dc14e50f650c4009e686ba28b 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugStart)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index edc75d0078bf8ebdaca3997fe08dc3912842711b..21b33b0154531d2e45e92deed8f0992b5fd2b5cd 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Label)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index b99fe16116bd57f9eacd2f48673113ba4ef8fb0b..019c3e94927785fa1355fd357ad2dc91daef145c 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PublicSymbol)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
index 8cfd63bb8b39521aa0972d965a500a69adb67ed4..2ebd29cccbaee7bc52e7924d6e7afa8e6fc380d1 100644 (file)
@@ -25,7 +25,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Thunk)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAccess)
   FORWARD_SYMBOL_METHOD(getAddressOffset)
index 42d0f39341ba679bb2f4d0547f92e35b0993e9af..d9e86fd510fcc86ccf5ad3278b14cb8590debde5 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getArrayIndexTypeId)
   FORWARD_SYMBOL_METHOD(isConstType)
index e80caffaf51abb3536a98ce966669e979633d720..c0763a6f6f4e1e939a6c31ce195abe2d647dbe3e 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BaseClass)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getAccess)
   FORWARD_SYMBOL_METHOD(getClassParentId)
index 725abe76b692d724f2a4af0132be93ff14cc6f01..3c16f133f9b8db52e6be8a760c10eb92e3fbb261 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BuiltinType)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getBuiltinType)
   FORWARD_SYMBOL_METHOD(isConstType)
index 622c7824e537c60a3cb5c408533f9f7e52473bb8..0e3cff044fba7478a9dfaaa04da17e2ac78f4447 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CustomType)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getOemId)
   FORWARD_SYMBOL_METHOD(getOemSymbolId)
index 91d8b8789d11e7ee1c96249f28dfafb890597597..78a6ac35420bc57152a1c763e57eea15ef893dca 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Dimension)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getLowerBoundId)
   FORWARD_SYMBOL_METHOD(getUpperBoundId)
index a1ee01d826267c64aa228e8d9a9aacfbf8a1b31f..3266c826a703245dac9b6f90b83813098fdce189 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Enum)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getBuiltinType)
   FORWARD_SYMBOL_METHOD(getClassParentId)
index 1b835b11655d12e298ef4c61adc29ec24662c4e0..e1846decc441f75efa9346ba173aef048c63fe8b 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Friend)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getClassParentId)
   FORWARD_SYMBOL_METHOD(getName)
index 050889244a712e3a65e14dd185cd30d6f780b445..39504276eaac9fd3e0db08dcc5ba37f44196637b 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionArg)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getClassParentId)
   FORWARD_SYMBOL_METHOD(getLexicalParentId)
index e81afcbd75e14674c4668cfe36bd20fd2b3987cf..068472c92b46cb718901e06e5d2d996c2d7354c9 100644 (file)
@@ -28,7 +28,7 @@ public:
   std::unique_ptr<IPDBEnumSymbols> getArguments() const;
   std::unique_ptr<PDBSymbol> getClassParent() const;
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
   void dumpArgList(raw_ostream &OS) const;
 
   FORWARD_SYMBOL_METHOD(getCallingConvention)
index ff86f569779748a1d02f7404814c3e411fd97491..4b6fad6b58709dbf405c05e43a6a858d82e4dbe5 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ManagedType)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getName)
   FORWARD_SYMBOL_METHOD(getSymIndexId)
index f0989c1770ac33eca19205f3823b8c35a11830aa..f52c47442b8e1c3846c13a1ae28a1da1d9b47e06 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(getLength)
index 3afdbf38203c8dd4dc9227a7f59b423dfd864059..ddf4f46035c15d9a9b70885c3b8652ea57bb5a36 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Typedef)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getBuiltinType)
   FORWARD_SYMBOL_METHOD(getClassParentId)
index 2e067fa53721cff516fb08d2e42d908e3b8d4870..aea5d92f7956ff9362dd1f95cb302ad45185ef1f 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getClassParentId)
   FORWARD_SYMBOL_METHOD(hasConstructor)
index a0b26ea11f26ee0eeb59366512172151b493e655..5a2a7c3bf7e36f2cc5935a6794c0d5076fbfa529 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTable)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getClassParentId)
   FORWARD_SYMBOL_METHOD(isConstType)
index a1379a05b82f8ca5301c21753b431b038e311fc7..4676a35ad5451670e0a654342d31f68302691694 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTableShape)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(getCount)
index 1fa358c3eae49af0c44857f03de9a0fe3391e52c..dbcbf07af7420797fa244dfc00b13e8e7b60fa49 100644 (file)
@@ -21,7 +21,7 @@ public:
   PDBSymbolUnknown(const IPDBSession &PDBSession,
                    std::unique_ptr<IPDBRawSymbol> UnknownSymbol);
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   static bool classof(const PDBSymbol *S) {
     return (S->getSymTag() == PDB_SymType::None ||
index 9d94ed8f775c918a2074bdfa52d96349a9a1484e..d0d624d147044e9b6a5a6db35a8adb214ddad445 100644 (file)
@@ -24,7 +24,7 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UsingNamespace)
 
-  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;
+  void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level, PDB_DumpFlags Flags) const override;
 
   FORWARD_SYMBOL_METHOD(getLexicalParentId)
   FORWARD_SYMBOL_METHOD(getName)
index e933621729bb751b316c0abf45a0674784ba7c5c..1b44a5f21d81be77be8868140a624d2d153e2e49 100644 (file)
@@ -75,6 +75,44 @@ enum class PDB_DumpLevel {
   Detailed,
 };
 
+enum PDB_DumpFlags {
+  PDB_DF_None = 0x0,
+  PDB_DF_Functions = 0x1,  // Dump functions
+  PDB_DF_Data = 0x2,       // Dump variables and constants
+  PDB_DF_Labels = 0x4,     // Dump labels
+  PDB_DF_PublicSyms = 0x8, // Dump public symbols
+  PDB_DF_Classes = 0x10,   // Dump class types
+  PDB_DF_Enums = 0x20,     // Dump enums
+  PDB_DF_Funcsigs = 0x40,  // Dump function signatures
+  PDB_DF_VTables = 0x80,   // Dump virtual function tables
+  PDB_DF_Thunks = 0x100,   // Dump thunks
+  PDB_DF_ObjFiles = 0x200, // Dump object files (compilands)
+  PDB_DF_Typedefs = 0x400, // Dump typedefs
+  PDB_DF_Children = 0x800, // Dump children of the current symbol
+  PDB_DF_Hidden = 0x1000,  // Dump everything.  This is not simply a bitwise
+                           // or of the previous flags.  It will find symbols
+                           // that would otherwise be missed, but can lead to
+                           // much slower dumps for large input files.
+  PDB_DF_All = 0x7FF
+};
+inline PDB_DumpFlags operator|(PDB_DumpFlags LHS, PDB_DumpFlags RHS) {
+  return static_cast<PDB_DumpFlags>((int)LHS | (int)RHS);
+}
+
+inline PDB_DumpFlags operator&(PDB_DumpFlags LHS, PDB_DumpFlags RHS) {
+  return static_cast<PDB_DumpFlags>((int)LHS & (int)RHS);
+}
+
+inline PDB_DumpFlags operator~(PDB_DumpFlags LHS) {
+  return static_cast<PDB_DumpFlags>(~(int)LHS);
+}
+inline PDB_DumpFlags &operator|=(PDB_DumpFlags &LHS, PDB_DumpFlags RHS) {
+  return (LHS = (LHS | RHS));
+}
+inline PDB_DumpFlags &operator&=(PDB_DumpFlags &LHS, PDB_DumpFlags RHS) {
+  return (LHS = (LHS & RHS));
+}
+
 /// Defines a 128-bit unique identifier.  This maps to a GUID on Windows, but
 /// is abstracted here for the purposes of non-Windows platforms that don't have
 /// the GUID structure defined.
index 2baf3df0fd8b72b6dbc35e1c4ed41c25a72b7d3e..5ed1624bfd4f4ebeea90f5cc7d6b9737aae41f54 100644 (file)
@@ -352,7 +352,7 @@ DIARawSymbol::findChildren(PDB_SymType Type) const {
   enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
 
   CComPtr<IDiaEnumSymbols> DiaEnumerator;
-  if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator))
+  if (S_OK != Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator))
     return nullptr;
 
   return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
@@ -370,7 +370,7 @@ DIARawSymbol::findChildren(PDB_SymType Type, StringRef Name,
 
   CComPtr<IDiaEnumSymbols> DiaEnumerator;
   if (S_OK !=
-      Symbol->findChildren(EnumVal, Name16Str, CompareFlags, &DiaEnumerator))
+      Symbol->findChildrenEx(EnumVal, Name16Str, CompareFlags, &DiaEnumerator))
     return nullptr;
 
   return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
index 5fcc602e5a8caf2d52c0ebfbdccc8a6004fd417e..c965d1d9d6b02ab1d795080afdbc5e2021d3d958 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolAnnotation::PDBSymbolAnnotation(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolAnnotation::dump(raw_ostream &OS, int Indent,
-                               PDB_DumpLevel Level) const {}
+                               PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index f92bfca193d4be15cc843644fcfe475869009b54..2e350ad2fe91fb8a6a6f27f2b35478f6b5c17647 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolBlock::PDBSymbolBlock(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolBlock::dump(raw_ostream &OS, int Indent,
-                          PDB_DumpLevel Level) const {}
+                          PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 0ea0b185911f4de66d456ff985f2937d1e83ce4c..f014b3959b0a3de63454ca38732c5dcbf5d725fc 100644 (file)
@@ -28,75 +28,43 @@ PDBSymbolCompiland::PDBSymbolCompiland(const IPDBSession &PDBSession,
                                        std::unique_ptr<IPDBRawSymbol> Symbol)
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
+#define SKIP_SYMBOL_IF_FLAG_UNSET(Tag, Flag) \
+  case PDB_SymType::Tag: \
+    if ((Flags & Flag) == 0) \
+      continue;   \
+    break;
+
 void PDBSymbolCompiland::dump(raw_ostream &OS, int Indent,
-                              PDB_DumpLevel Level) const {
+                              PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   if (Level == PDB_DumpLevel::Detailed) {
     std::string FullName = getName();
-    StringRef Name = llvm::sys::path::filename(StringRef(FullName.c_str()));
-
-    OS.indent(Indent);
-    OS << "Compiland: " << Name << "\n";
-
-    std::string Source = getSourceFileName();
-    std::string Library = getLibraryName();
-    if (!Source.empty())
-      OS << stream_indent(Indent + 2) << "Source: " << this->getSourceFileName()
-         << "\n";
-    if (!Library.empty())
-      OS << stream_indent(Indent + 2) << "Library: " << this->getLibraryName()
-         << "\n";
-
-    TagStats Stats;
-    auto ChildrenEnum = getChildStats(Stats);
-    OS << stream_indent(Indent + 2) << "Children: " << Stats << "\n";
-    if (Level >= PDB_DumpLevel::Detailed) {
-      while (auto Child = ChildrenEnum->getNext()) {
-        if (llvm::isa<PDBSymbolCompilandDetails>(*Child))
-          continue;
-        if (llvm::isa<PDBSymbolCompilandEnv>(*Child))
-          continue;
-        PDB_DumpLevel ChildLevel = (Level == PDB_DumpLevel::Detailed)
-                                       ? PDB_DumpLevel::Normal
-                                       : PDB_DumpLevel::Compact;
-        Child->dump(OS, Indent + 4, ChildLevel);
-        OS << "\n";
+    OS << stream_indent(Indent) << FullName;
+    if (Flags & PDB_DF_Children) {
+      if (Level >= PDB_DumpLevel::Detailed) {
+        auto ChildrenEnum = findAllChildren();
+        while (auto Child = ChildrenEnum->getNext()) {
+          switch (Child->getSymTag()) {
+            SKIP_SYMBOL_IF_FLAG_UNSET(Function, PDB_DF_Functions)
+            SKIP_SYMBOL_IF_FLAG_UNSET(Data, PDB_DF_Data)
+            SKIP_SYMBOL_IF_FLAG_UNSET(Label, PDB_DF_Labels)
+            SKIP_SYMBOL_IF_FLAG_UNSET(PublicSymbol, PDB_DF_PublicSyms)
+            SKIP_SYMBOL_IF_FLAG_UNSET(UDT, PDB_DF_Classes)
+            SKIP_SYMBOL_IF_FLAG_UNSET(Enum, PDB_DF_Enums)
+            SKIP_SYMBOL_IF_FLAG_UNSET(FunctionSig, PDB_DF_Funcsigs)
+            SKIP_SYMBOL_IF_FLAG_UNSET(VTable, PDB_DF_VTables)
+            SKIP_SYMBOL_IF_FLAG_UNSET(Thunk, PDB_DF_Thunks)
+            SKIP_SYMBOL_IF_FLAG_UNSET(Compiland, PDB_DF_ObjFiles)
+            default:
+              continue;
+          }
+          PDB_DumpLevel ChildLevel = (Level == PDB_DumpLevel::Detailed)
+                                         ? PDB_DumpLevel::Normal
+                                         : PDB_DumpLevel::Compact;
+          OS << "\n";
+          Child->dump(OS, Indent + 2, ChildLevel, PDB_DF_Children);
+        }
       }
     }
-
-    auto DetailsEnum(findAllChildren<PDBSymbolCompilandDetails>());
-    if (auto CD = DetailsEnum->getNext()) {
-      VersionInfo FE;
-      VersionInfo BE;
-      CD->getFrontEndVersion(FE);
-      CD->getBackEndVersion(BE);
-      OS << stream_indent(Indent + 2) << "Compiler: " << CD->getCompilerName()
-         << "\n";
-      OS << stream_indent(Indent + 2) << "Version: " << FE << ", " << BE
-         << "\n";
-
-      OS << stream_indent(Indent + 2) << "Lang: " << CD->getLanguage() << "\n";
-      OS << stream_indent(Indent + 2) << "Attributes: ";
-      if (CD->hasDebugInfo())
-        OS << "DebugInfo ";
-      if (CD->isDataAligned())
-        OS << "DataAligned ";
-      if (CD->isLTCG())
-        OS << "LTCG ";
-      if (CD->hasSecurityChecks())
-        OS << "SecurityChecks ";
-      if (CD->isHotpatchable())
-        OS << "HotPatchable";
-
-      auto Files(Session.getSourceFilesForCompiland(*this));
-      OS << "\n";
-      OS << stream_indent(Indent + 2) << Files->getChildCount()
-         << " source files";
-    }
-    uint32_t Count = DetailsEnum->getChildCount();
-    if (Count > 1) {
-      OS << "\n";
-      OS << stream_indent(Indent + 2) << "(" << Count - 1 << " more omitted)";
-    }
   } else {
     std::string FullName = getName();
     OS << stream_indent(Indent) << "Compiland: " << FullName;
index ebda161999fb45255ad5922c98cd357cac92348d..9194376eee05da50de99f9afe7890a81dc074a30 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolCompilandDetails::PDBSymbolCompilandDetails(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolCompilandDetails::dump(raw_ostream &OS, int Indent,
-                                     PDB_DumpLevel Level) const {}
+                                     PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index e4955e2b4706bdb2855b98c1d24c32c281ef6fc3..b44dc578ea4edff7107c7a4a695c4595bbbc50c4 100644 (file)
@@ -26,4 +26,4 @@ std::string PDBSymbolCompilandEnv::getValue() const {
 }
 
 void PDBSymbolCompilandEnv::dump(raw_ostream &OS, int Indent,
-                                 PDB_DumpLevel Level) const {}
+                                 PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 4bddf562e3b6e31be0bb7a2fe597e0ddf10fa754..68f2b45194cc35e02d1c4979b76c239fcac8c2a9 100644 (file)
@@ -25,4 +25,4 @@ void PDBSymbolCustom::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) {
 }
 
 void PDBSymbolCustom::dump(raw_ostream &OS, int Indent,
-                           PDB_DumpLevel Level) const {}
\ No newline at end of file
+                           PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
\ No newline at end of file
index 516b87ec001bb3ff6866adf6e5093046f6277658..9a04ecd1f438be150cc3a6526df22046cbcfcd0f 100644 (file)
@@ -24,58 +24,56 @@ PDBSymbolData::PDBSymbolData(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(DataSymbol)) {}
 
 void PDBSymbolData::dump(raw_ostream &OS, int Indent,
-                         PDB_DumpLevel Level) const {
+                         PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   PDB_LocType Loc = getLocationType();
   PDB_DataKind Kind = getDataKind();
-  if (Level >= PDB_DumpLevel::Normal) {
-    switch (Loc) {
-    case PDB_LocType::Static: {
-      uint32_t RVA = getRelativeVirtualAddress();
-      OS << Kind << " data[";
-      if (RVA != 0)
-        OS << format_hex(RVA, 10);
-      else
-        OS << "???";
-      break;
-    }
-    case PDB_LocType::TLS:
-      OS << "threadlocal " << Kind << " data[";
-      OS << getAddressSection() << ":" << format_hex(getAddressOffset(), 10);
-      break;
-    case PDB_LocType::RegRel:
-      OS << "regrel " << Kind << " data[";
-      OS << getRegisterId() << " + " << getOffset();
-      break;
-    case PDB_LocType::ThisRel: {
-      uint32_t Offset = getOffset();
-      OS << Kind << " data[this + " << format_hex(Offset, 4);
-      break;
-    }
-    case PDB_LocType::Enregistered:
-      OS << "register " << Kind << " data[" << getRegisterId();
-      break;
-    case PDB_LocType::BitField: {
-      OS << "bitfield data[this + ";
-      uint32_t Offset = getOffset();
-      uint32_t BitPos = getBitPosition();
-      uint32_t Length = getLength();
-      OS << format_hex(Offset, 4) << ":" << BitPos << "," << Length;
-      break;
-    }
-    case PDB_LocType::Slot:
-      OS << getSlot();
-      break;
-    case PDB_LocType::Constant: {
-      OS << "constant data[";
-      OS << getValue();
-      break;
-    }
-    case PDB_LocType::IlRel:
-    case PDB_LocType::MetaData:
-    default:
+  switch (Loc) {
+  case PDB_LocType::Static: {
+    uint32_t RVA = getRelativeVirtualAddress();
+    OS << Kind << " data[";
+    if (RVA != 0)
+      OS << format_hex(RVA, 10);
+    else
       OS << "???";
-    }
+    break;
+  }
+  case PDB_LocType::TLS:
+    OS << "threadlocal " << Kind << " data[";
+    OS << getAddressSection() << ":" << format_hex(getAddressOffset(), 10);
+    break;
+  case PDB_LocType::RegRel:
+    OS << "regrel " << Kind << " data[";
+    OS << getRegisterId() << " + " << getOffset();
+    break;
+  case PDB_LocType::ThisRel: {
+    uint32_t Offset = getOffset();
+    OS << Kind << " data[this + " << format_hex(Offset, 4);
+    break;
+  }
+  case PDB_LocType::Enregistered:
+    OS << "register " << Kind << " data[" << getRegisterId();
+    break;
+  case PDB_LocType::BitField: {
+    OS << "bitfield data[this + ";
+    uint32_t Offset = getOffset();
+    uint32_t BitPos = getBitPosition();
+    uint32_t Length = getLength();
+    OS << format_hex(Offset, 4) << ":" << BitPos << "," << Length;
+    break;
+  }
+  case PDB_LocType::Slot:
+    OS << getSlot();
+    break;
+  case PDB_LocType::Constant: {
+    OS << "constant data[";
+    OS << getValue();
+    break;
+  }
+  case PDB_LocType::IlRel:
+  case PDB_LocType::MetaData:
+  default:
+    OS << "???";
   }
 
   OS << "] ";
index 6555b814a6827e8ea16d5e4cf3bf4485c1dbf62b..5d3da2169575e29faf4100be036e9f86c2154b82 100644 (file)
 
 using namespace llvm;
 
+#define SKIP_SYMBOL_IF_FLAG_UNSET(Tag, Flag)                                   \
+  case PDB_SymType::Tag:                                                       \
+    if ((Flags & Flag) == 0)                                                   \
+      continue;                                                                \
+    break;
+
 PDBSymbolExe::PDBSymbolExe(const IPDBSession &PDBSession,
                            std::unique_ptr<IPDBRawSymbol> Symbol)
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolExe::dump(raw_ostream &OS, int Indent,
-                        PDB_DumpLevel Level) const {
+                        PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   std::string FileName(getSymbolsFileName());
 
   OS << stream_indent(Indent) << "Summary for " << FileName << "\n";
@@ -46,25 +52,76 @@ void PDBSymbolExe::dump(raw_ostream &OS, int Indent,
     OS << "HasPrivateSymbols ";
   OS << "\n";
 
-  auto ChildrenEnum = findAllChildren();
-  OS << stream_indent(Indent + 2) << ChildrenEnum->getChildCount()
-     << " children\n";
-#if 0
-  dumpChildren(OS, PDB_SymType::None, Indent+4);
-#else
-  dumpChildren(OS, "Compilands", PDB_SymType::Compiland, Indent + 4);
-  dumpChildren(OS, "Functions", PDB_SymType::Function, Indent + 4);
-  dumpChildren(OS, "Blocks", PDB_SymType::Block, Indent + 4);
-  dumpChildren(OS, "Data", PDB_SymType::Data, Indent + 4);
-  dumpChildren(OS, "Labels", PDB_SymType::Label, Indent + 4);
-  dumpChildren(OS, "Public Symbols", PDB_SymType::PublicSymbol, Indent + 4);
-  dumpChildren(OS, "UDTs", PDB_SymType::UDT, Indent + 4);
-  dumpChildren(OS, "Enums", PDB_SymType::Enum, Indent + 4);
-  dumpChildren(OS, "Function Signatures", PDB_SymType::FunctionSig, Indent + 4);
-  dumpChildren(OS, "Typedefs", PDB_SymType::Typedef, Indent + 4);
-  dumpChildren(OS, "VTables", PDB_SymType::VTable, Indent + 4);
-  dumpChildren(OS, "Thunks", PDB_SymType::Thunk, Indent + 4);
-#endif
+  if (Flags & PDB_DF_Children) {
+    if (Flags & PDB_DF_Hidden) {
+      // For some reason, for each SymTag T, this dumps more items of type T
+      // than are dumped by calling dumpChildren(T).  In other words, there are
+      // "hidden" symbols.  For example, it causes functions to be dumped which
+      // have no address information, whereas specifically dumping only
+      // functions will not find those symbols.
+      //
+      // My suspicion is that in the underlying DIA call, when you call
+      // findChildren, passing a value of SymTagNone means all children
+      // recursively, whereas passing a concrete tag value means only immediate
+      // children of the global scope.  So perhaps we need to find these
+      // mysterious missing values by recursing through the hierarchy.
+      //
+      // On the other hand, there may just be some symbols that DIA tries to
+      // hide from you because it thinks you don't care about them.  However
+      // experimentation shows that even vtables, for example, can't be found
+      // without an exhaustive search.
+      auto ChildrenEnum = findAllChildren();
+      OS << stream_indent(Indent + 2) << ChildrenEnum->getChildCount()
+         << " symbols";
+
+      while (auto Child = ChildrenEnum->getNext()) {
+        switch (Child->getSymTag()) {
+          SKIP_SYMBOL_IF_FLAG_UNSET(Function, PDB_DF_Functions)
+          SKIP_SYMBOL_IF_FLAG_UNSET(Data, PDB_DF_Data)
+          SKIP_SYMBOL_IF_FLAG_UNSET(Label, PDB_DF_Labels)
+          SKIP_SYMBOL_IF_FLAG_UNSET(PublicSymbol, PDB_DF_PublicSyms)
+          SKIP_SYMBOL_IF_FLAG_UNSET(UDT, PDB_DF_Classes)
+          SKIP_SYMBOL_IF_FLAG_UNSET(Enum, PDB_DF_Enums)
+          SKIP_SYMBOL_IF_FLAG_UNSET(FunctionSig, PDB_DF_Funcsigs)
+          SKIP_SYMBOL_IF_FLAG_UNSET(VTable, PDB_DF_VTables)
+          SKIP_SYMBOL_IF_FLAG_UNSET(Thunk, PDB_DF_Thunks)
+          SKIP_SYMBOL_IF_FLAG_UNSET(Compiland, PDB_DF_ObjFiles)
+        default:
+          continue;
+        }
+        PDB_DumpLevel ChildLevel = (Level == PDB_DumpLevel::Detailed)
+                                       ? PDB_DumpLevel::Normal
+                                       : PDB_DumpLevel::Compact;
+        OS << "\n";
+        Child->dump(OS, Indent + 4, ChildLevel, PDB_DF_Children);
+      }
+    } else {
+      if (Flags & PDB_DF_ObjFiles)
+        dumpChildren(OS, "Compilands", PDB_SymType::Compiland, Indent + 4);
+      if (Flags & PDB_DF_Functions)
+        dumpChildren(OS, "Functions", PDB_SymType::Function, Indent + 4);
+      if (Flags & PDB_DF_Data)
+        dumpChildren(OS, "Data", PDB_SymType::Data, Indent + 4);
+      if (Flags & PDB_DF_Labels)
+        dumpChildren(OS, "Labels", PDB_SymType::Label, Indent + 4);
+      if (Flags & PDB_DF_PublicSyms)
+        dumpChildren(OS, "Public Symbols", PDB_SymType::PublicSymbol,
+                     Indent + 4);
+      if (Flags & PDB_DF_Classes)
+        dumpChildren(OS, "UDTs", PDB_SymType::UDT, Indent + 4);
+      if (Flags & PDB_DF_Enums)
+        dumpChildren(OS, "Enums", PDB_SymType::Enum, Indent + 4);
+      if (Flags & PDB_DF_Funcsigs)
+        dumpChildren(OS, "Function Signatures", PDB_SymType::FunctionSig,
+                     Indent + 4);
+      if (Flags & PDB_DF_Typedefs)
+        dumpChildren(OS, "Typedefs", PDB_SymType::Typedef, Indent + 4);
+      if (Flags & PDB_DF_VTables)
+        dumpChildren(OS, "VTables", PDB_SymType::VTable, Indent + 4);
+      if (Flags & PDB_DF_Thunks)
+        dumpChildren(OS, "Thunks", PDB_SymType::Thunk, Indent + 4);
+    }
+  }
 }
 
 void PDBSymbolExe::dumpChildren(raw_ostream &OS, StringRef Label,
@@ -73,7 +130,7 @@ void PDBSymbolExe::dumpChildren(raw_ostream &OS, StringRef Label,
   OS << stream_indent(Indent) << Label << ": (" << ChildrenEnum->getChildCount()
      << " items)\n";
   while (auto Child = ChildrenEnum->getNext()) {
-    Child->dump(OS, Indent + 2, PDB_DumpLevel::Normal);
+    Child->dump(OS, Indent + 2, PDB_DumpLevel::Normal, PDB_DF_None);
     OS << "\n";
   }
 }
index 817279bc3db819671d15200e6fd0bc9a77c4b697..cd01423c9b7f4333d70bf3ee9f28119992a4141c 100644 (file)
@@ -29,66 +29,58 @@ std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const {
 }
 
 void PDBSymbolFunc::dump(raw_ostream &OS, int Indent,
-                         PDB_DumpLevel Level) const {
+                         PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
+  uint32_t FuncStart = getRelativeVirtualAddress();
+  uint32_t FuncEnd = FuncStart + getLength();
   OS << stream_indent(Indent);
-  // if (getName() == "__crtCreateThreadpoolWait") {
-  //  RawSymbol->dump(OS, Indent+2, Level);
-  //  OS.flush();
-  //}
-  if (Level >= PDB_DumpLevel::Normal) {
-    uint32_t FuncStart = getRelativeVirtualAddress();
-    uint32_t FuncEnd = FuncStart + getLength();
-    if (FuncStart == 0 && FuncEnd == 0) {
-      OS << "func [???] ";
-    } else {
-      OS << "func ";
-      OS << "[" << format_hex(FuncStart, 8);
-      if (auto DebugStart = findOneChild<PDBSymbolFuncDebugStart>())
-        OS << "+" << DebugStart->getRelativeVirtualAddress() - FuncStart;
-      OS << " - " << format_hex(FuncEnd, 8);
-      if (auto DebugEnd = findOneChild<PDBSymbolFuncDebugEnd>())
-        OS << "-" << FuncEnd - DebugEnd->getRelativeVirtualAddress();
-      OS << "] ";
-    }
+  if (FuncStart == 0 && FuncEnd == 0) {
+    OS << "func [???] ";
+  } else {
+    OS << "func ";
+    OS << "[" << format_hex(FuncStart, 8);
+    if (auto DebugStart = findOneChild<PDBSymbolFuncDebugStart>())
+      OS << "+" << DebugStart->getRelativeVirtualAddress() - FuncStart;
+    OS << " - " << format_hex(FuncEnd, 8);
+    if (auto DebugEnd = findOneChild<PDBSymbolFuncDebugEnd>())
+      OS << "-" << FuncEnd - DebugEnd->getRelativeVirtualAddress();
+    OS << "] ";
+  }
 
-    PDB_RegisterId Reg = getLocalBasePointerRegisterId();
-    if (Reg == PDB_RegisterId::VFrame)
-      OS << "(VFrame)";
-    else if (hasFramePointer())
-      OS << "(" << Reg << ")";
-    else
-      OS << "(FPO)";
+  PDB_RegisterId Reg = getLocalBasePointerRegisterId();
+  if (Reg == PDB_RegisterId::VFrame)
+    OS << "(VFrame)";
+  else if (hasFramePointer())
+    OS << "(" << Reg << ")";
+  else
+    OS << "(FPO)";
 
-    OS << " ";
-    if (auto FuncSig = getSignature()) {
-      // If we have a signature, dump the name with the signature.
-      if (auto ReturnType = FuncSig->getReturnType()) {
-        ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
-        OS << " ";
-      }
+  OS << " ";
+  if (isVirtual() || isPureVirtual())
+    OS << "virtual ";
 
-      OS << FuncSig->getCallingConvention() << " ";
+  if (auto FuncSig = getSignature()) {
+    // If we have a signature, dump the name with the signature.
+    if (auto ReturnType = FuncSig->getReturnType()) {
+      ReturnType->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
+      OS << " ";
+    }
 
-      if (auto ClassParent = FuncSig->getClassParent()) {
-        ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
-        OS << "::";
-      }
+    OS << FuncSig->getCallingConvention() << " ";
 
-      OS << getName();
-      FuncSig->dumpArgList(OS);
-    } else {
-      uint32_t ClassId = getClassParentId();
-      if (ClassId != 0) {
-        if (auto Class = Session.getSymbolById(ClassId)) {
-          if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))
-            OS << UDT->getName() << "::";
-          else
-            OS << "{class " << Class->getSymTag() << "}::";
-        }
+    OS << getName();
+    FuncSig->dumpArgList(OS);
+    if (isPureVirtual())
+      OS << " = 0";
+  } else {
+    uint32_t ClassId = getClassParentId();
+    if (ClassId != 0) {
+      if (auto Class = Session.getSymbolById(ClassId)) {
+        if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))
+          OS << UDT->getName() << "::";
+        else
+          OS << "{class " << Class->getSymTag() << "}::";
       }
-      OS << getName();
     }
-  } else {
     OS << getName();
   }
 }
index bd4d88834aeddc74ca112c0bfb612ff50a6fe737..8658be951fa20effec7a88a186435932427f4fa1 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolFuncDebugEnd::PDBSymbolFuncDebugEnd(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolFuncDebugEnd::dump(raw_ostream &OS, int Indent,
-                                 PDB_DumpLevel Level) const {}
+                                 PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 704e7ca0168440f7af00705baf79bc8c833a548f..64cd3e36705aabbcffdbccad58de2fa961172ecd 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolFuncDebugStart::PDBSymbolFuncDebugStart(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolFuncDebugStart::dump(raw_ostream &OS, int Indent,
-                                   PDB_DumpLevel Level) const {}
+                                   PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 5f2dedf2e3033a4657cb88b1969dd2ab329e2532..abb516330deadd54257c479d1e196bd9f27eeb9d 100644 (file)
@@ -21,7 +21,7 @@ PDBSymbolLabel::PDBSymbolLabel(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolLabel::dump(raw_ostream &OS, int Indent,
-                          PDB_DumpLevel Level) const {
+                          PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   OS << "label [" << format_hex(getRelativeVirtualAddress(), 10) << "] "
      << getName();
index 5d53a3a130ea957a9d7cccf3d2a876077eb1820e..a2cea8be82c343a342d578386af5b4b8a1128f3c 100644 (file)
@@ -20,7 +20,7 @@ PDBSymbolPublicSymbol::PDBSymbolPublicSymbol(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolPublicSymbol::dump(raw_ostream &OS, int Indent,
-                                 PDB_DumpLevel Level) const {
+                                 PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   OS << "public symbol: " << getName();
 }
index 985b87ef9d21cf76619afe420a207f5296aebb29..c62c96b6ae49b84baf1662f523bf48451e2ac895 100644 (file)
@@ -21,7 +21,7 @@ PDBSymbolThunk::PDBSymbolThunk(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolThunk::dump(raw_ostream &OS, int Indent,
-                          PDB_DumpLevel Level) const {
+                          PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS.indent(Indent);
   OS << "thunk ";
   PDB_ThunkOrdinal Ordinal = getThunkOrdinal();
index ef6bb137a9009585efb92924b482611fcbfd3a3a..b418e3343f6c89fa8c80dcf4a5c909e96d210555 100644 (file)
@@ -21,10 +21,10 @@ PDBSymbolTypeArray::PDBSymbolTypeArray(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeArray::dump(raw_ostream &OS, int Indent,
-                              PDB_DumpLevel Level) const {
+                              PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   if (auto ElementType = Session.getSymbolById(getTypeId()))
-    ElementType->dump(OS, 0, PDB_DumpLevel::Compact);
+    ElementType->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
   else
     OS << "<unknown-element-type>";
   OS << "[" << getLength() << "]";
index c312d9f3bcb7085831da86b307c356e4d32cf7ec..532e8b8178f30c9bda7be12c1f50280f41c28517 100644 (file)
@@ -20,7 +20,7 @@ PDBSymbolTypeBaseClass::PDBSymbolTypeBaseClass(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeBaseClass::dump(raw_ostream &OS, int Indent,
-                                  PDB_DumpLevel Level) const {
+                                  PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   OS << "<base class> " << getName();
 }
index d51f6530f91c52406d2c47909c33ffaf74c9f22b..b7afdcddeb0d595ebaa5c33b9f5dd023c6ae91d5 100644 (file)
@@ -20,7 +20,7 @@ PDBSymbolTypeBuiltin::PDBSymbolTypeBuiltin(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeBuiltin::dump(raw_ostream &OS, int Indent,
-                                PDB_DumpLevel Level) const {
+                                PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   PDB_BuiltinType Type = getBuiltinType();
   OS << Type;
index f09d0a08680a75dc59c755dc838d87f5d08a4b42..0bfa8eb4e7413f761fac6dd8af73796d48fa7282 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolTypeCustom::PDBSymbolTypeCustom(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeCustom::dump(raw_ostream &OS, int Indent,
-                               PDB_DumpLevel Level) const {}
+                               PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index d36d0cf36e8e1c6e4fc8a888d3f1e0a4f021f4e1..84f48ea4310b10a0718f166a1a729e432a3b3fb2 100644 (file)
@@ -21,4 +21,4 @@ PDBSymbolTypeDimension::PDBSymbolTypeDimension(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeDimension::dump(raw_ostream &OS, int Indent,
-                                  PDB_DumpLevel Level) const {}
+                                  PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index a44acc00915acf82d7b92e991c38ee40525244d5..512b602244f5f59ee43c7ec8b0658db91ec15755 100644 (file)
@@ -21,7 +21,7 @@ PDBSymbolTypeEnum::PDBSymbolTypeEnum(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeEnum::dump(raw_ostream &OS, int Indent,
-                             PDB_DumpLevel Level) const {
+                             PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   if (Level >= PDB_DumpLevel::Normal)
     OS << "enum ";
@@ -29,7 +29,7 @@ void PDBSymbolTypeEnum::dump(raw_ostream &OS, int Indent,
   uint32_t ClassId = getClassParentId();
   if (ClassId != 0) {
     if (auto ClassParent = Session.getSymbolById(ClassId)) {
-      ClassParent->dump(OS, 0, Level);
+      ClassParent->dump(OS, 0, Level, PDB_DF_Children);
       OS << "::";
     }
   }
index 405f49a7dbb7d6f34fdb0c850ad90208b2f5b2d9..236304eb478b964f3e16b00f8188059b0aa6eb19 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolTypeFriend::PDBSymbolTypeFriend(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeFriend::dump(raw_ostream &OS, int Indent,
-                               PDB_DumpLevel Level) const {}
+                               PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 30db55ab31526f5dde1863332d80f5816f2c46d8..4b8cc26d9f74e43ed3583235f9e0ddd7a44105fb 100644 (file)
@@ -21,10 +21,10 @@ PDBSymbolTypeFunctionArg::PDBSymbolTypeFunctionArg(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeFunctionArg::dump(raw_ostream &OS, int Indent,
-                                    PDB_DumpLevel Level) const {
+                                    PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   uint32_t TypeId = getTypeId();
   if (auto Type = Session.getSymbolById(TypeId)) {
-    Type->dump(OS, 0, Level);
+    Type->dump(OS, 0, Level, PDB_DF_Children);
   }
 }
index f9a1bbf74e637d22f217688533bead93978ac190..13b89b235ddc996b820053be70451b58093c49f9 100644 (file)
@@ -87,7 +87,7 @@ void PDBSymbolTypeFunctionSig::dumpArgList(raw_ostream &OS) const {
   if (auto ChildEnum = getArguments()) {
     uint32_t Index = 0;
     while (auto Arg = ChildEnum->getNext()) {
-      Arg->dump(OS, 0, PDB_DumpLevel::Compact);
+      Arg->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
       if (++Index < ChildEnum->getChildCount())
         OS << ", ";
     }
@@ -100,18 +100,18 @@ void PDBSymbolTypeFunctionSig::dumpArgList(raw_ostream &OS) const {
 }
 
 void PDBSymbolTypeFunctionSig::dump(raw_ostream &OS, int Indent,
-                                    PDB_DumpLevel Level) const {
+                                    PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
 
   if (auto ReturnType = getReturnType()) {
-    ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
+    ReturnType->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
     OS << " ";
   }
 
   OS << getCallingConvention() << " ";
   if (auto ClassParent = getClassParent()) {
     OS << "(";
-    ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
+    ClassParent->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
     OS << "::*)";
   }
 
index 4cce8e1c34baffd1a276567d58fe8c0c478e351e..32602dc022b0c981b7271ab9eb990bbac1a89158 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolTypeManaged::PDBSymbolTypeManaged(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeManaged::dump(raw_ostream &OS, int Indent,
-                                PDB_DumpLevel Level) const {}
+                                PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 0a4dd230ab42c521ca489746a60724c30f53f0dd..3461928993adce9667fa4dbc00c936f1c25644cd 100644 (file)
@@ -22,7 +22,7 @@ PDBSymbolTypePointer::PDBSymbolTypePointer(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypePointer::dump(raw_ostream &OS, int Indent,
-                                PDB_DumpLevel Level) const {
+                                PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   if (isConstType())
     OS << "const ";
@@ -34,12 +34,12 @@ void PDBSymbolTypePointer::dump(raw_ostream &OS, int Indent,
     // the middle of the signature.
     if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
       if (auto ReturnType = FuncSig->getReturnType())
-        ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
+        ReturnType->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
       OS << " (" << FuncSig->getCallingConvention() << " ";
       OS << ((isReference()) ? "&" : "*") << ")";
       FuncSig->dumpArgList(OS);
     } else {
-      PointeeType->dump(OS, 0, PDB_DumpLevel::Compact);
+      PointeeType->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
       OS << ((isReference()) ? "&" : "*");
     }
   }
index 32e5446feef67aa7224d8f43beee0039c215a926..9554d7082227e17068f190e283e706ca1ef11c00 100644 (file)
@@ -22,7 +22,7 @@ PDBSymbolTypeTypedef::PDBSymbolTypeTypedef(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeTypedef::dump(raw_ostream &OS, int Indent,
-                                PDB_DumpLevel Level) const {
+                                PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS.indent(Indent);
   if (Level >= PDB_DumpLevel::Normal) {
     std::string Name = getName();
@@ -30,7 +30,7 @@ void PDBSymbolTypeTypedef::dump(raw_ostream &OS, int Indent,
     std::string TargetTypeName;
     uint32_t TargetId = getTypeId();
     if (auto TypeSymbol = Session.getSymbolById(TargetId)) {
-      TypeSymbol->dump(OS, 0, PDB_DumpLevel::Compact);
+      TypeSymbol->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
     }
     OS << TargetTypeName;
   } else {
index 96786a2668b895a348290f4ccf89704d15d4a035..ea884bdac516f1d567efee211ef7bfba87688f17 100644 (file)
@@ -21,7 +21,7 @@ PDBSymbolTypeUDT::PDBSymbolTypeUDT(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeUDT::dump(raw_ostream &OS, int Indent,
-                            PDB_DumpLevel Level) const {
+                            PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   if (Level >= PDB_DumpLevel::Normal)
     OS << "class ";
@@ -30,7 +30,7 @@ void PDBSymbolTypeUDT::dump(raw_ostream &OS, int Indent,
     uint32_t ClassId = getClassParentId();
     if (ClassId != 0) {
       if (auto ClassParent = Session.getSymbolById(ClassId)) {
-        ClassParent->dump(OS, 0, Level);
+        ClassParent->dump(OS, 0, Level, PDB_DF_Children);
         OS << "::";
       }
     }
index 7002008841d74f9656df9f1c17c5893b5b247cd8..4c1f05ea0d3489b57cfcc5c35a79f4316dd71c80 100644 (file)
@@ -23,11 +23,11 @@ PDBSymbolTypeVTable::PDBSymbolTypeVTable(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeVTable::dump(raw_ostream &OS, int Indent,
-                               PDB_DumpLevel Level) const {
+                               PDB_DumpLevel Level, PDB_DumpFlags Flags) const {
   OS << stream_indent(Indent);
   uint32_t ClassId = getClassParentId();
   if (auto ClassParent = Session.getSymbolById(ClassId)) {
-    ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
+    ClassParent->dump(OS, 0, PDB_DumpLevel::Compact, PDB_DF_Children);
     OS << "::";
   }
   OS << "<vtbl> ";
@@ -38,5 +38,4 @@ void PDBSymbolTypeVTable::dump(raw_ostream &OS, int Indent,
                 VtblPointer->getTypeId()))
       OS << "(" << VtblShape->getCount() << " entries)";
   }
-  OS.flush();
 }
index 7ea4da2f741e5ee114294649566ce7accdd2f7fd..cff0d03c4cf4cfa0532c109087758c1547da2cc7 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolTypeVTableShape::PDBSymbolTypeVTableShape(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolTypeVTableShape::dump(raw_ostream &OS, int Indent,
-                                    PDB_DumpLevel Level) const {}
+                                    PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 97e4a9156ef2f10a5ceb5827a1ae1984d1dea7b1..b7b4c38f24d664904d43da905649709ca6a0ae79 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolUnknown::PDBSymbolUnknown(const IPDBSession &PDBSession,
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolUnknown::dump(raw_ostream &OS, int Indent,
-                            PDB_DumpLevel Level) const {}
+                            PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index fea984408a995ad9219de59782a7fbd8a531c968..077d2b3a3ae0637cf7658324a2c18c406d84b073 100644 (file)
@@ -20,4 +20,4 @@ PDBSymbolUsingNamespace::PDBSymbolUsingNamespace(
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
 void PDBSymbolUsingNamespace::dump(raw_ostream &OS, int Indent,
-                                   PDB_DumpLevel Level) const {}
+                                   PDB_DumpLevel Level, PDB_DumpFlags Flags) const {}
index 49a7c8147fc71f3ebaf5ae4311816495594cae11..1254a53a8d1aa42823e6fa66ec1ec35616ee530c 100644 (file)
 using namespace llvm;
 
 namespace opts {
+
+enum class PDB_DumpType { ByType, ByObjFile, Both };
+
 cl::list<std::string> InputFilenames(cl::Positional,
                                      cl::desc("<input PDB files>"),
                                      cl::OneOrMore);
 
-cl::opt<bool> Compilands("compilands",
-                         cl::desc("Display a list of compilands (e.g. object "
-                                  "files) and symbols for each one."));
-cl::alias CompilandsShort("c", cl::desc("Alias for --compilands"),
-                          cl::aliasopt(Compilands));
+cl::opt<bool> DumpHidden(
+    "hidden",
+    cl::desc("Attempt to find hidden symbols.  This can find additional\n"
+             "symbols that cannot be found otherwise.  For example, vtables\n"
+             "can only be found with an exhaustive search such as this.  Be\n"
+             "warned that the performance can be prohibitive on large PDB "
+             "files."));
+
+cl::opt<bool> DumpAll(
+    "all",
+    cl::desc("Specifies all other options except -hidden and -group-by"));
+cl::opt<bool> DumpObjFiles("compilands", cl::desc("Display object files"));
+cl::opt<bool> DumpFuncs("functions", cl::desc("Display function information"));
+cl::opt<bool> DumpData(
+    "data",
+    cl::desc("Display global, class, and constant variable information."));
+cl::opt<bool> DumpLabels("labels", cl::desc("Display labels"));
+cl::opt<bool> DumpPublic("public", cl::desc("Display public symbols"));
+cl::opt<bool> DumpClasses("classes", cl::desc("Display class type information"));
+cl::opt<bool> DumpEnums("enums", cl::desc("Display enum information"));
+cl::opt<bool> DumpFuncsigs("funcsigs",
+                           cl::desc("Display unique function signatures"));
+cl::opt<bool> DumpTypedefs("typedefs", cl::desc("Display typedefs"));
+cl::opt<bool> DumpThunks("thunks", cl::desc("Display thunks"));
+cl::opt<bool> DumpVtables(
+    "vtables",
+    cl::desc("Display virtual function tables (only with --exhaustive)"));
+
+static cl::opt<PDB_DumpType> DumpMode(
+    "group-by", cl::init(PDB_DumpType::ByType), cl::desc("Dump mode:"),
+    cl::values(
+        clEnumValN(PDB_DumpType::ByType, "type",
+                   "(Default) Display symbols grouped by type"),
+        clEnumValN(PDB_DumpType::ByObjFile, "compiland",
+                   "Display symbols grouped under their containing object "
+                   "file."),
+        clEnumValN(
+            PDB_DumpType::Both, "both",
+            "Display symbols grouped by type, and then by object file.")));
+}
+
+#define SET_DUMP_FLAG_FROM_OPT(Var, Flag, Opt) \
+  if (opts::Opt) \
+    Var |= Flag;
+
+PDB_DumpFlags CalculateDumpFlags() {
+  PDB_DumpFlags Flags = PDB_DF_None;
+
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Hidden, DumpHidden)
+
+  if (opts::DumpAll)
+    return Flags | PDB_DF_All;
+
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_ObjFiles, DumpObjFiles)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Functions, DumpFuncs)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Data, DumpData)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Labels, DumpLabels)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_PublicSyms, DumpPublic)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Classes, DumpClasses)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Enums, DumpEnums)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Funcsigs, DumpFuncsigs)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Typedefs, DumpTypedefs)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_Thunks, DumpThunks)
+  SET_DUMP_FLAG_FROM_OPT(Flags, PDB_DF_VTables, DumpVtables)
+  return Flags;
 }
 
 static void dumpInput(StringRef Path) {
@@ -57,15 +120,19 @@ static void dumpInput(StringRef Path) {
     outs() << " is available for your platform.";
     return;
   }
+  PDB_DumpFlags Flags = CalculateDumpFlags();
 
+  if (opts::DumpMode != opts::PDB_DumpType::ByObjFile)
+    Flags |= PDB_DF_Children;
   auto GlobalScope(Session->getGlobalScope());
-  GlobalScope->dump(outs(), 0, PDB_DumpLevel::Normal);
-  outs().flush();
+  GlobalScope->dump(outs(), 0, PDB_DumpLevel::Normal, Flags);
+  outs() << "\n";
 
-  if (opts::Compilands) {
+  if (opts::DumpMode != opts::PDB_DumpType::ByType) {
     auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>();
     while (auto Compiland = Compilands->getNext()) {
-      Compiland->dump(outs(), 0, PDB_DumpLevel::Detailed);
+      Compiland->dump(outs(), 0, PDB_DumpLevel::Detailed,
+                      Flags | PDB_DF_Children);
       outs() << "\n";
     }
   }