[llvm] r280293 - [codeview] Add TypeVisitorCallbackPipeline.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 31 14:42:26 PDT 2016


Author: zturner
Date: Wed Aug 31 16:42:26 2016
New Revision: 280293

URL: http://llvm.org/viewvc/llvm-project?rev=280293&view=rev
Log:
[codeview] Add TypeVisitorCallbackPipeline.

We were kind of hacking this together before by embedding the
ability to forward requests into the TypeDeserializer.  When
we want to start adding more different kinds of visitor callback
interfaces though, this doesn't scale well and is very inflexible.

So introduce the notion of a pipeline, which itself implements
the TypeVisitorCallbacks interface, but which contains an internal
list of other callbacks to invoke in sequence.

Also update the existing uses of CVTypeVisitor to use this new
pipeline class for deserializing records before visiting them
with another visitor.

Added:
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
    llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Wed Aug 31 16:42:26 2016
@@ -17,16 +17,7 @@ namespace llvm {
 namespace codeview {
 class TypeDeserializer : public TypeVisitorCallbacks {
 public:
-  explicit TypeDeserializer(TypeVisitorCallbacks &Recipient)
-      : Recipient(Recipient) {}
-
-  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
-    return Recipient.visitTypeBegin(Record);
-  }
-
-  Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
-    return Recipient.visitTypeEnd(Record);
-  }
+  TypeDeserializer() {}
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
   Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
@@ -40,7 +31,6 @@ public:
 #include "TypeRecords.def"
 
 protected:
-  TypeVisitorCallbacks &Recipient;
 
   template <typename T>
   Error deserializeRecord(ArrayRef<uint8_t> &Data, TypeLeafKind Kind,
@@ -59,7 +49,7 @@ private:
     ArrayRef<uint8_t> RD = CVR.Data;
     if (auto EC = deserializeRecord(RD, CVR.Type, Record))
       return EC;
-    return Recipient.visitKnownRecord(CVR, Record);
+    return Error::success();
   }
 };
 }

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h?rev=280293&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h Wed Aug 31 16:42:26 2016
@@ -0,0 +1,83 @@
+//===- TypeVisitorCallbackPipeline.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_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+#include <vector>
+
+namespace llvm {
+namespace codeview {
+class TypeVisitorCallbackPipeline : public TypeVisitorCallbacks {
+public:
+  TypeVisitorCallbackPipeline() {}
+
+  virtual Error
+  visitUnknownType(const CVRecord<TypeLeafKind> &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitUnknownType(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+
+  virtual Error
+  visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitUnknownMember(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+
+  virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitTypeBegin(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+  virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitTypeEnd(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+
+  void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks) {
+    Pipeline.push_back(&Callbacks);
+  }
+
+#define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
+  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
+                         Name##Record &Record) override {                      \
+    for (auto Visitor : Pipeline) {                                            \
+      if (auto EC = Visitor->visitKnownRecord(CVR, Record))                    \
+        return EC;                                                             \
+    }                                                                          \
+    return Error::success();                                                   \
+  }
+#define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
+  TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+
+private:
+  std::vector<TypeVisitorCallbacks *> Pipeline;
+};
+}
+}
+
+#endif

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Wed Aug 31 16:42:26 2016
@@ -13,6 +13,7 @@
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/ByteStream.h"
 #include "llvm/Support/ScopedPrinter.h"
 
@@ -249,8 +250,12 @@ Error CVTypeDumper::visitTypeEnd(const C
 
 Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
                                      FieldListRecord &FieldList) {
-  TypeDeserializer Deserializer(*this);
-  CVTypeVisitor Visitor(Deserializer);
+  TypeDeserializer Deserializer;
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(*this);
+
+  CVTypeVisitor Visitor(Pipeline);
   if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data))
     return EC;
 
@@ -711,8 +716,12 @@ void CVTypeDumper::printTypeIndex(String
 
 Error CVTypeDumper::dump(const CVRecord<TypeLeafKind> &Record) {
   assert(W && "printer should not be null");
-  TypeDeserializer Deserializer(*this);
-  CVTypeVisitor Visitor(Deserializer);
+  TypeDeserializer Deserializer;
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(*this);
+
+  CVTypeVisitor Visitor(Pipeline);
 
   if (auto EC = Visitor.visitTypeRecord(Record))
     return EC;
@@ -721,8 +730,12 @@ Error CVTypeDumper::dump(const CVRecord<
 
 Error CVTypeDumper::dump(const CVTypeArray &Types) {
   assert(W && "printer should not be null");
-  TypeDeserializer Deserializer(*this);
-  CVTypeVisitor Visitor(Deserializer);
+  TypeDeserializer Deserializer;
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(*this);
+
+  CVTypeVisitor Visitor(Pipeline);
 
   if (auto EC = Visitor.visitTypeStream(Types))
     return EC;

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Wed Aug 31 16:42:26 2016
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"
@@ -84,8 +85,13 @@ private:
 
   Error visitKnownRecordImpl(FieldListRecord &Record) {
     // Don't do anything, this will get written in the call to visitTypeEnd().
-    TypeDeserializer Deserializer(*this);
-    CVTypeVisitor Visitor(Deserializer);
+    TypeVisitorCallbackPipeline Pipeline;
+    TypeDeserializer Deserializer;
+
+    Pipeline.addCallbackToPipeline(Deserializer);
+    Pipeline.addCallbackToPipeline(*this);
+
+    CVTypeVisitor Visitor(Pipeline);
 
     if (auto EC = Visitor.visitFieldListMemberStream(Record.Data))
       return EC;
@@ -160,8 +166,13 @@ Error TypeStreamMerger::visitUnknownType
 
 bool TypeStreamMerger::mergeStream(const CVTypeArray &Types) {
   assert(IndexMap.empty());
-  TypeDeserializer Deserializer(*this);
-  CVTypeVisitor Visitor(Deserializer);
+  TypeVisitorCallbackPipeline Pipeline;
+
+  TypeDeserializer Deserializer;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(*this);
+
+  CVTypeVisitor Visitor(Pipeline);
 
   if (auto EC = Visitor.visitTypeStream(Types)) {
     consumeError(std::move(EC));

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Wed Aug 31 16:42:26 2016
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/MSF/StreamReader.h"
 #include "llvm/DebugInfo/PDB/Raw/Hash.h"
@@ -160,8 +161,13 @@ private:
 // Currently we only verify SRC_LINE records.
 Error TpiStream::verifyHashValues() {
   TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
-  TypeDeserializer Deserializer(Verifier);
-  CVTypeVisitor Visitor(Deserializer);
+  TypeDeserializer Deserializer;
+
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(Verifier);
+
+  CVTypeVisitor Visitor(Pipeline);
   return Visitor.visitTypeStream(TypeRecords);
 }
 

Modified: llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp Wed Aug 31 16:42:26 2016
@@ -13,6 +13,7 @@
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
@@ -240,10 +241,14 @@ template <> struct ScalarTraits<APSInt>
 
 void MappingTraits<CVType>::mapping(IO &IO, CVType &Record) {
   if (IO.outputting()) {
+    codeview::TypeDeserializer Deserializer;
     codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO);
-    codeview::TypeDeserializer Deserializer(Callbacks);
 
-    codeview::CVTypeVisitor Visitor(Deserializer);
+    codeview::TypeVisitorCallbackPipeline Pipeline;
+    Pipeline.addCallbackToPipeline(Deserializer);
+    Pipeline.addCallbackToPipeline(Callbacks);
+
+    codeview::CVTypeVisitor Visitor(Pipeline);
     consumeError(Visitor.visitTypeRecord(Record));
   }
 }
@@ -252,8 +257,13 @@ void MappingTraits<FieldListRecord>::map
                                              FieldListRecord &FieldList) {
   if (IO.outputting()) {
     codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO);
-    codeview::TypeDeserializer Deserializer(Callbacks);
-    codeview::CVTypeVisitor Visitor(Deserializer);
+    codeview::TypeDeserializer Deserializer;
+
+    codeview::TypeVisitorCallbackPipeline Pipeline;
+    Pipeline.addCallbackToPipeline(Deserializer);
+    Pipeline.addCallbackToPipeline(Callbacks);
+
+    codeview::CVTypeVisitor Visitor(Pipeline);
     consumeError(Visitor.visitFieldListMemberStream(FieldList.Data));
   }
 }

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp?rev=280293&r1=280292&r2=280293&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp Wed Aug 31 16:42:26 2016
@@ -8,10 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "PdbYaml.h"
+
 #include "CodeViewYaml.h"
 
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/PDB/PDBExtras.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
@@ -200,11 +202,14 @@ void MappingTraits<PdbDbiModuleInfo>::ma
 void MappingTraits<PdbTpiRecord>::mapping(IO &IO,
                                           pdb::yaml::PdbTpiRecord &Obj) {
   if (IO.outputting()) {
-    // If we're going from Pdb To Yaml, deserialize the Pdb record
+    codeview::TypeDeserializer Deserializer;
     codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO);
-    codeview::TypeDeserializer Deserializer(Callbacks);
 
-    codeview::CVTypeVisitor Visitor(Deserializer);
+    codeview::TypeVisitorCallbackPipeline Pipeline;
+    Pipeline.addCallbackToPipeline(Deserializer);
+    Pipeline.addCallbackToPipeline(Callbacks);
+
+    codeview::CVTypeVisitor Visitor(Pipeline);
     consumeError(Visitor.visitTypeRecord(Obj.Record));
   } else {
     codeview::yaml::YamlTypeDumperCallbacks Callbacks(IO);




More information about the llvm-commits mailing list