[codeview] Isolate type dumping from object file state

This isolates the state we use for type dumping from the knowledge of
object files. We can use CVTypeDumper to dump types from anywhere in
memory now.

NFC

Reviewers: zturner

Differential Revision: http://reviews.llvm.org/D19824

llvm-svn: 268300
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 67d7f9f..f5ac6e0 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -52,12 +52,33 @@
 
 namespace {
 
+class CVTypeDumper {
+public:
+  CVTypeDumper(StreamWriter &W) : W(W) {}
+
+  StringRef getTypeName(TypeIndex TI);
+  void printTypeIndex(StringRef FieldName, TypeIndex TI);
+
+  void dump(StringRef Data);
+
+private:
+  void printCodeViewFieldList(StringRef FieldData);
+  void printMemberAttributes(MemberAttributes Attrs);
+
+  StreamWriter &W;
+
+  /// All user defined type records in .debug$T live in here. Type indices
+  /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
+  /// index into this vector.
+  SmallVector<StringRef, 10> CVUDTNames;
+
+  StringSet<> TypeNames;
+};
+
 class COFFDumper : public ObjDumper {
 public:
-  COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer)
-    : ObjDumper(Writer)
-    , Obj(Obj) {
-  }
+  COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter &Writer)
+      : ObjDumper(Writer), Obj(Obj), CVTD(Writer) {}
 
   void printFileHeaders() override;
   void printSections() override;
@@ -84,11 +105,13 @@
 
   void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section);
   void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
-  void printCodeViewFieldList(StringRef FieldData);
   StringRef getTypeName(TypeIndex Ty);
   StringRef getFileNameForFileOffset(uint32_t FileOffset);
   void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
-  void printTypeIndex(StringRef FieldName, TypeIndex TI);
+  void printTypeIndex(StringRef FieldName, TypeIndex TI) {
+    // Forward to CVTypeDumper for simplicity.
+    CVTD.printTypeIndex(FieldName, TI);
+  }
   void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
                                    const coff_section *Sec,
                                    StringRef SectionContents);
@@ -102,8 +125,6 @@
 
   void printCodeViewInlineeLines(StringRef Subsection);
 
-  void printMemberAttributes(MemberAttributes Attrs);
-
   void printRelocatedField(StringRef Label, const coff_section *Sec,
                            StringRef SectionContents, const ulittle32_t *Field,
                            StringRef *RelocSym = nullptr);
@@ -136,12 +157,7 @@
   StringRef CVFileChecksumTable;
   StringRef CVStringTable;
 
-  /// All user defined type records in .debug$T live in here. Type indices
-  /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
-  /// index into this vector.
-  SmallVector<StringRef, 10> CVUDTNames;
-
-  StringSet<> TypeNames;
+  CVTypeDumper CVTD;
 };
 
 } // namespace
@@ -1866,7 +1882,7 @@
   return Leading;
 }
 
-StringRef COFFDumper::getTypeName(TypeIndex TI) {
+StringRef CVTypeDumper::getTypeName(TypeIndex TI) {
   if (TI.isNoType())
     return "<no type>";
 
@@ -1893,7 +1909,7 @@
   return "<unknown UDT>";
 }
 
-void COFFDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) {
+void CVTypeDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) {
   StringRef TypeName;
   if (!TI.isNoType())
     TypeName = getTypeName(TI);
@@ -1990,6 +2006,10 @@
 
   Data = Data.drop_front(4);
 
+  CVTD.dump(Data);
+}
+
+void CVTypeDumper::dump(StringRef Data) {
   while (!Data.empty()) {
     const TypeRecordPrefix *Rec;
     error(consumeObject(Data, Rec));
@@ -2370,7 +2390,7 @@
   return Data.drop_front(Leaf & 0x0F);
 }
 
-void COFFDumper::printMemberAttributes(MemberAttributes Attrs) {
+void CVTypeDumper::printMemberAttributes(MemberAttributes Attrs) {
   W.printEnum("AccessSpecifier", uint8_t(Attrs.getAccess()),
               makeArrayRef(MemberAccessNames));
   auto MK = Attrs.getMethodKind();
@@ -2383,7 +2403,7 @@
   }
 }
 
-void COFFDumper::printCodeViewFieldList(StringRef FieldData) {
+void CVTypeDumper::printCodeViewFieldList(StringRef FieldData) {
   while (!FieldData.empty()) {
     const ulittle16_t *LeafPtr;
     error(consumeObject(FieldData, LeafPtr));