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, \
#include "TypeRecords.def"
protected:
- TypeVisitorCallbacks &Recipient;
template <typename T>
Error deserializeRecord(ArrayRef<uint8_t> &Data, TypeLeafKind Kind,
ArrayRef<uint8_t> RD = CVR.Data;
if (auto EC = deserializeRecord(RD, CVR.Type, Record))
return EC;
- return Recipient.visitKnownRecord(CVR, Record);
+ return Error::success();
}
};
}
--- /dev/null
+//===- 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
#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"
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;
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;
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;
#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"
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;
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));
#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"
// 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);
}
#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;
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));
}
}
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));
}
}
//===----------------------------------------------------------------------===//
#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"
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);