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 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 
     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 
     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 
     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 
     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:
    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>
    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