Home | History | Annotate | Download | only in CodeView
      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