Home | History | Annotate | Download | only in Frontend
      1 //===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- 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 //  This file defines the MultiplexConsumer class. It also declares and defines
     11 //  MultiplexASTDeserializationListener and  MultiplexASTMutationListener, which
     12 //  are implementation details of MultiplexConsumer.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "clang/Frontend/MultiplexConsumer.h"
     17 
     18 #include "clang/AST/ASTMutationListener.h"
     19 #include "clang/AST/DeclGroup.h"
     20 #include "clang/Serialization/ASTDeserializationListener.h"
     21 
     22 using namespace clang;
     23 
     24 namespace clang {
     25 
     26 // This ASTDeserializationListener forwards its notifications to a set of
     27 // child listeners.
     28 class MultiplexASTDeserializationListener
     29     : public ASTDeserializationListener {
     30 public:
     31   // Does NOT take ownership of the elements in L.
     32   MultiplexASTDeserializationListener(
     33       const std::vector<ASTDeserializationListener*>& L);
     34   virtual void ReaderInitialized(ASTReader *Reader);
     35   virtual void IdentifierRead(serialization::IdentID ID,
     36                               IdentifierInfo *II);
     37   virtual void TypeRead(serialization::TypeIdx Idx, QualType T);
     38   virtual void DeclRead(serialization::DeclID ID, const Decl *D);
     39   virtual void SelectorRead(serialization::SelectorID iD, Selector Sel);
     40   virtual void MacroDefinitionRead(serialization::PreprocessedEntityID,
     41                                    MacroDefinition *MD);
     42 private:
     43   std::vector<ASTDeserializationListener*> Listeners;
     44 };
     45 
     46 MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
     47       const std::vector<ASTDeserializationListener*>& L)
     48     : Listeners(L) {
     49 }
     50 
     51 void MultiplexASTDeserializationListener::ReaderInitialized(
     52     ASTReader *Reader) {
     53   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     54     Listeners[i]->ReaderInitialized(Reader);
     55 }
     56 
     57 void MultiplexASTDeserializationListener::IdentifierRead(
     58     serialization::IdentID ID, IdentifierInfo *II) {
     59   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     60     Listeners[i]->IdentifierRead(ID, II);
     61 }
     62 
     63 void MultiplexASTDeserializationListener::TypeRead(
     64     serialization::TypeIdx Idx, QualType T) {
     65   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     66     Listeners[i]->TypeRead(Idx, T);
     67 }
     68 
     69 void MultiplexASTDeserializationListener::DeclRead(
     70     serialization::DeclID ID, const Decl *D) {
     71   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     72     Listeners[i]->DeclRead(ID, D);
     73 }
     74 
     75 void MultiplexASTDeserializationListener::SelectorRead(
     76     serialization::SelectorID ID, Selector Sel) {
     77   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     78     Listeners[i]->SelectorRead(ID, Sel);
     79 }
     80 
     81 void MultiplexASTDeserializationListener::MacroDefinitionRead(
     82     serialization::PreprocessedEntityID ID, MacroDefinition *MD) {
     83   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     84     Listeners[i]->MacroDefinitionRead(ID, MD);
     85 }
     86 
     87 // This ASTMutationListener forwards its notifications to a set of
     88 // child listeners.
     89 class MultiplexASTMutationListener : public ASTMutationListener {
     90 public:
     91   // Does NOT take ownership of the elements in L.
     92   MultiplexASTMutationListener(const std::vector<ASTMutationListener*>& L);
     93   virtual void CompletedTagDefinition(const TagDecl *D);
     94   virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
     95   virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
     96   virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
     97                                     const ClassTemplateSpecializationDecl *D);
     98   virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
     99                                               const FunctionDecl *D);
    100   virtual void CompletedImplicitDefinition(const FunctionDecl *D);
    101   virtual void StaticDataMemberInstantiated(const VarDecl *D);
    102 private:
    103   std::vector<ASTMutationListener*> Listeners;
    104 };
    105 
    106 MultiplexASTMutationListener::MultiplexASTMutationListener(
    107     const std::vector<ASTMutationListener*>& L)
    108     : Listeners(L) {
    109 }
    110 
    111 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) {
    112   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    113     Listeners[i]->CompletedTagDefinition(D);
    114 }
    115 
    116 void MultiplexASTMutationListener::AddedVisibleDecl(
    117     const DeclContext *DC, const Decl *D) {
    118   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    119     Listeners[i]->AddedVisibleDecl(DC, D);
    120 }
    121 
    122 void MultiplexASTMutationListener::AddedCXXImplicitMember(
    123     const CXXRecordDecl *RD, const Decl *D) {
    124   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    125     Listeners[i]->AddedCXXImplicitMember(RD, D);
    126 }
    127 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
    128     const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
    129   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    130     Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
    131 }
    132 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
    133     const FunctionTemplateDecl *TD, const FunctionDecl *D) {
    134   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    135     Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
    136 }
    137 void MultiplexASTMutationListener::CompletedImplicitDefinition(
    138                                                         const FunctionDecl *D) {
    139   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    140     Listeners[i]->CompletedImplicitDefinition(D);
    141 }
    142 void MultiplexASTMutationListener::StaticDataMemberInstantiated(
    143                                                              const VarDecl *D) {
    144   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
    145     Listeners[i]->StaticDataMemberInstantiated(D);
    146 }
    147 
    148 }  // end namespace clang
    149 
    150 
    151 MultiplexConsumer::MultiplexConsumer(const std::vector<ASTConsumer*>& C)
    152     : Consumers(C), MutationListener(0), DeserializationListener(0) {
    153   // Collect the mutation listeners and deserialization listeners of all
    154   // children, and create a multiplex listener each if so.
    155   std::vector<ASTMutationListener*> mutationListeners;
    156   std::vector<ASTDeserializationListener*> serializationListeners;
    157   for (size_t i = 0, e = Consumers.size(); i != e; ++i) {
    158     ASTMutationListener* mutationListener =
    159         Consumers[i]->GetASTMutationListener();
    160     if (mutationListener)
    161       mutationListeners.push_back(mutationListener);
    162     ASTDeserializationListener* serializationListener =
    163         Consumers[i]->GetASTDeserializationListener();
    164     if (serializationListener)
    165       serializationListeners.push_back(serializationListener);
    166   }
    167   if (mutationListeners.size()) {
    168     MutationListener.reset(new MultiplexASTMutationListener(mutationListeners));
    169   }
    170   if (serializationListeners.size()) {
    171     DeserializationListener.reset(
    172         new MultiplexASTDeserializationListener(serializationListeners));
    173   }
    174 }
    175 
    176 MultiplexConsumer::~MultiplexConsumer() {
    177   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    178     delete Consumers[i];
    179 }
    180 
    181 void MultiplexConsumer::Initialize(ASTContext &Context) {
    182   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    183     Consumers[i]->Initialize(Context);
    184 }
    185 
    186 void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
    187   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    188     Consumers[i]->HandleTopLevelDecl(D);
    189 }
    190 
    191 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
    192   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    193     Consumers[i]->HandleInterestingDecl(D);
    194 }
    195 
    196 void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) {
    197   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    198     Consumers[i]->HandleTranslationUnit(Ctx);
    199 }
    200 
    201 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
    202   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    203     Consumers[i]->HandleTagDeclDefinition(D);
    204 }
    205 
    206 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
    207   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    208     Consumers[i]->CompleteTentativeDefinition(D);
    209 }
    210 
    211 void MultiplexConsumer::HandleVTable(
    212     CXXRecordDecl *RD, bool DefinitionRequired) {
    213   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    214     Consumers[i]->HandleVTable(RD, DefinitionRequired);
    215 }
    216 
    217 ASTMutationListener *MultiplexConsumer::GetASTMutationListener() {
    218   return MutationListener.get();
    219 }
    220 
    221 ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() {
    222   return DeserializationListener.get();
    223 }
    224 
    225 void MultiplexConsumer::PrintStats() {
    226   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    227     Consumers[i]->PrintStats();
    228 }
    229 
    230 void MultiplexConsumer::InitializeSema(Sema &S) {
    231   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    232     if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
    233       SC->InitializeSema(S);
    234 }
    235 
    236 void MultiplexConsumer::ForgetSema() {
    237   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
    238     if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
    239       SC->ForgetSema();
    240 }
    241