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