1 //===- TypeVisitorCallbackPipeline.h ----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H 11 #define LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H 12 13 #include "llvm/DebugInfo/CodeView/CodeView.h" 14 #include "llvm/DebugInfo/CodeView/TypeRecord.h" 15 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" 16 #include "llvm/Support/Error.h" 17 #include <vector> 18 19 namespace llvm { 20 namespace codeview { 21 22 class TypeVisitorCallbackPipeline : public TypeVisitorCallbacks { 23 public: 24 TypeVisitorCallbackPipeline() = default; 25 26 Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override { 27 for (auto Visitor : Pipeline) { 28 if (auto EC = Visitor->visitUnknownType(Record)) 29 return EC; 30 } 31 return Error::success(); 32 } 33 34 Error visitUnknownMember(CVMemberRecord &Record) override { 35 for (auto Visitor : Pipeline) { 36 if (auto EC = Visitor->visitUnknownMember(Record)) 37 return EC; 38 } 39 return Error::success(); 40 } 41 42 Error visitTypeBegin(CVType &Record) override { 43 for (auto Visitor : Pipeline) { 44 if (auto EC = Visitor->visitTypeBegin(Record)) 45 return EC; 46 } 47 return Error::success(); 48 } 49 50 Error visitTypeEnd(CVType &Record) override { 51 for (auto Visitor : Pipeline) { 52 if (auto EC = Visitor->visitTypeEnd(Record)) 53 return EC; 54 } 55 return Error::success(); 56 } 57 58 Error visitMemberBegin(CVMemberRecord &Record) override { 59 for (auto Visitor : Pipeline) { 60 if (auto EC = Visitor->visitMemberBegin(Record)) 61 return EC; 62 } 63 return Error::success(); 64 } 65 66 Error visitMemberEnd(CVMemberRecord &Record) override { 67 for (auto Visitor : Pipeline) { 68 if (auto EC = Visitor->visitMemberEnd(Record)) 69 return EC; 70 } 71 return Error::success(); 72 } 73 74 void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks) { 75 Pipeline.push_back(&Callbacks); 76 } 77 78 #define TYPE_RECORD(EnumName, EnumVal, Name) \ 79 Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \ 80 return visitKnownRecordImpl(CVR, Record); \ 81 } 82 #define MEMBER_RECORD(EnumName, EnumVal, Name) \ 83 Error visitKnownMember(CVMemberRecord &CVMR, Name##Record &Record) \ 84 override { \ 85 return visitKnownMemberImpl(CVMR, Record); \ 86 } 87 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 88 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 89 #include "llvm/DebugInfo/CodeView/TypeRecords.def" 90 91 private: 92 template <typename T> Error visitKnownRecordImpl(CVType &CVR, T &Record) { 93 for (auto Visitor : Pipeline) { 94 if (auto EC = Visitor->visitKnownRecord(CVR, Record)) 95 return EC; 96 } 97 return Error::success(); 98 } 99 100 template <typename T> 101 Error visitKnownMemberImpl(CVMemberRecord &CVMR, T &Record) { 102 for (auto Visitor : Pipeline) { 103 if (auto EC = Visitor->visitKnownMember(CVMR, Record)) 104 return EC; 105 } 106 return Error::success(); 107 } 108 std::vector<TypeVisitorCallbacks *> Pipeline; 109 }; 110 111 } // end namespace codeview 112 } // end namespace llvm 113 114 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H 115