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