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