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 visitUnknownType(CVRecord<TypeLeafKind> & Record)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 visitUnknownMember(CVMemberRecord & Record)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 visitTypeBegin(CVType & Record)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 visitTypeBegin(CVType & Record,TypeIndex Index)50 Error visitTypeBegin(CVType &Record, TypeIndex Index) override { 51 for (auto Visitor : Pipeline) { 52 if (auto EC = Visitor->visitTypeBegin(Record, Index)) 53 return EC; 54 } 55 return Error::success(); 56 } 57 visitTypeEnd(CVType & Record)58 Error visitTypeEnd(CVType &Record) override { 59 for (auto Visitor : Pipeline) { 60 if (auto EC = Visitor->visitTypeEnd(Record)) 61 return EC; 62 } 63 return Error::success(); 64 } 65 visitMemberBegin(CVMemberRecord & Record)66 Error visitMemberBegin(CVMemberRecord &Record) override { 67 for (auto Visitor : Pipeline) { 68 if (auto EC = Visitor->visitMemberBegin(Record)) 69 return EC; 70 } 71 return Error::success(); 72 } 73 visitMemberEnd(CVMemberRecord & Record)74 Error visitMemberEnd(CVMemberRecord &Record) override { 75 for (auto Visitor : Pipeline) { 76 if (auto EC = Visitor->visitMemberEnd(Record)) 77 return EC; 78 } 79 return Error::success(); 80 } 81 addCallbackToPipeline(TypeVisitorCallbacks & Callbacks)82 void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks) { 83 Pipeline.push_back(&Callbacks); 84 } 85 86 #define TYPE_RECORD(EnumName, EnumVal, Name) \ 87 Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \ 88 return visitKnownRecordImpl(CVR, Record); \ 89 } 90 #define MEMBER_RECORD(EnumName, EnumVal, Name) \ 91 Error visitKnownMember(CVMemberRecord &CVMR, Name##Record &Record) \ 92 override { \ 93 return visitKnownMemberImpl(CVMR, Record); \ 94 } 95 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 96 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 97 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 98 99 private: visitKnownRecordImpl(CVType & CVR,T & Record)100 template <typename T> Error visitKnownRecordImpl(CVType &CVR, T &Record) { 101 for (auto Visitor : Pipeline) { 102 if (auto EC = Visitor->visitKnownRecord(CVR, Record)) 103 return EC; 104 } 105 return Error::success(); 106 } 107 108 template <typename T> visitKnownMemberImpl(CVMemberRecord & CVMR,T & Record)109 Error visitKnownMemberImpl(CVMemberRecord &CVMR, T &Record) { 110 for (auto Visitor : Pipeline) { 111 if (auto EC = Visitor->visitKnownMember(CVMR, Record)) 112 return EC; 113 } 114 return Error::success(); 115 } 116 std::vector<TypeVisitorCallbacks *> Pipeline; 117 }; 118 119 } // end namespace codeview 120 } // end namespace llvm 121 122 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPEVISITORCALLBACKPIPELINE_H 123