MultiplexConsumer.cpp revision 263508
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#include "clang/AST/ASTMutationListener.h" 18#include "clang/AST/DeclGroup.h" 19#include "clang/Serialization/ASTDeserializationListener.h" 20 21using namespace clang; 22 23namespace clang { 24 25// This ASTDeserializationListener forwards its notifications to a set of 26// child listeners. 27class MultiplexASTDeserializationListener 28 : public ASTDeserializationListener { 29public: 30 // Does NOT take ownership of the elements in L. 31 MultiplexASTDeserializationListener( 32 const std::vector<ASTDeserializationListener*>& L); 33 virtual void ReaderInitialized(ASTReader *Reader); 34 virtual void IdentifierRead(serialization::IdentID ID, 35 IdentifierInfo *II); 36 virtual void TypeRead(serialization::TypeIdx Idx, QualType T); 37 virtual void DeclRead(serialization::DeclID ID, const Decl *D); 38 virtual void SelectorRead(serialization::SelectorID iD, Selector Sel); 39 virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, 40 MacroDefinition *MD); 41private: 42 std::vector<ASTDeserializationListener*> Listeners; 43}; 44 45MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( 46 const std::vector<ASTDeserializationListener*>& L) 47 : Listeners(L) { 48} 49 50void MultiplexASTDeserializationListener::ReaderInitialized( 51 ASTReader *Reader) { 52 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 53 Listeners[i]->ReaderInitialized(Reader); 54} 55 56void MultiplexASTDeserializationListener::IdentifierRead( 57 serialization::IdentID ID, IdentifierInfo *II) { 58 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 59 Listeners[i]->IdentifierRead(ID, II); 60} 61 62void MultiplexASTDeserializationListener::TypeRead( 63 serialization::TypeIdx Idx, QualType T) { 64 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 65 Listeners[i]->TypeRead(Idx, T); 66} 67 68void MultiplexASTDeserializationListener::DeclRead( 69 serialization::DeclID ID, const Decl *D) { 70 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 71 Listeners[i]->DeclRead(ID, D); 72} 73 74void MultiplexASTDeserializationListener::SelectorRead( 75 serialization::SelectorID ID, Selector Sel) { 76 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 77 Listeners[i]->SelectorRead(ID, Sel); 78} 79 80void MultiplexASTDeserializationListener::MacroDefinitionRead( 81 serialization::PreprocessedEntityID ID, MacroDefinition *MD) { 82 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 83 Listeners[i]->MacroDefinitionRead(ID, MD); 84} 85 86// This ASTMutationListener forwards its notifications to a set of 87// child listeners. 88class MultiplexASTMutationListener : public ASTMutationListener { 89public: 90 // Does NOT take ownership of the elements in L. 91 MultiplexASTMutationListener(ArrayRef<ASTMutationListener*> L); 92 virtual void CompletedTagDefinition(const TagDecl *D); 93 virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D); 94 virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); 95 virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 96 const ClassTemplateSpecializationDecl *D); 97 virtual void 98 AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, 99 const VarTemplateSpecializationDecl *D); 100 virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 101 const FunctionDecl *D); 102 virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType); 103 virtual void CompletedImplicitDefinition(const FunctionDecl *D); 104 virtual void StaticDataMemberInstantiated(const VarDecl *D); 105 virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 106 const ObjCInterfaceDecl *IFD); 107 virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, 108 const ObjCPropertyDecl *OrigProp, 109 const ObjCCategoryDecl *ClassExt); 110 void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE; 111 112private: 113 std::vector<ASTMutationListener*> Listeners; 114}; 115 116MultiplexASTMutationListener::MultiplexASTMutationListener( 117 ArrayRef<ASTMutationListener*> L) 118 : Listeners(L.begin(), L.end()) { 119} 120 121void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 122 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 123 Listeners[i]->CompletedTagDefinition(D); 124} 125 126void MultiplexASTMutationListener::AddedVisibleDecl( 127 const DeclContext *DC, const Decl *D) { 128 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 129 Listeners[i]->AddedVisibleDecl(DC, D); 130} 131 132void MultiplexASTMutationListener::AddedCXXImplicitMember( 133 const CXXRecordDecl *RD, const Decl *D) { 134 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 135 Listeners[i]->AddedCXXImplicitMember(RD, D); 136} 137void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 138 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 139 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 140 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 141} 142void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 143 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { 144 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 145 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 146} 147void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 148 const FunctionTemplateDecl *TD, const FunctionDecl *D) { 149 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 150 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 151} 152void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, 153 QualType ReturnType) { 154 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 155 Listeners[i]->DeducedReturnType(FD, ReturnType); 156} 157void MultiplexASTMutationListener::CompletedImplicitDefinition( 158 const FunctionDecl *D) { 159 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 160 Listeners[i]->CompletedImplicitDefinition(D); 161} 162void MultiplexASTMutationListener::StaticDataMemberInstantiated( 163 const VarDecl *D) { 164 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 165 Listeners[i]->StaticDataMemberInstantiated(D); 166} 167void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 168 const ObjCCategoryDecl *CatD, 169 const ObjCInterfaceDecl *IFD) { 170 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 171 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 172} 173void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( 174 const ObjCPropertyDecl *Prop, 175 const ObjCPropertyDecl *OrigProp, 176 const ObjCCategoryDecl *ClassExt) { 177 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 178 Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt); 179} 180void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 181 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 182 Listeners[i]->DeclarationMarkedUsed(D); 183} 184 185} // end namespace clang 186 187 188MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer*> C) 189 : Consumers(C.begin(), C.end()), 190 MutationListener(0), DeserializationListener(0) { 191 // Collect the mutation listeners and deserialization listeners of all 192 // children, and create a multiplex listener each if so. 193 std::vector<ASTMutationListener*> mutationListeners; 194 std::vector<ASTDeserializationListener*> serializationListeners; 195 for (size_t i = 0, e = Consumers.size(); i != e; ++i) { 196 ASTMutationListener* mutationListener = 197 Consumers[i]->GetASTMutationListener(); 198 if (mutationListener) 199 mutationListeners.push_back(mutationListener); 200 ASTDeserializationListener* serializationListener = 201 Consumers[i]->GetASTDeserializationListener(); 202 if (serializationListener) 203 serializationListeners.push_back(serializationListener); 204 } 205 if (mutationListeners.size()) { 206 MutationListener.reset(new MultiplexASTMutationListener(mutationListeners)); 207 } 208 if (serializationListeners.size()) { 209 DeserializationListener.reset( 210 new MultiplexASTDeserializationListener(serializationListeners)); 211 } 212} 213 214MultiplexConsumer::~MultiplexConsumer() { 215 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 216 delete Consumers[i]; 217} 218 219void MultiplexConsumer::Initialize(ASTContext &Context) { 220 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 221 Consumers[i]->Initialize(Context); 222} 223 224bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 225 bool Continue = true; 226 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 227 Continue = Continue && Consumers[i]->HandleTopLevelDecl(D); 228 return Continue; 229} 230 231void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 232 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 233 Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD); 234} 235 236void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 237 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 238 Consumers[i]->HandleInterestingDecl(D); 239} 240 241void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 242 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 243 Consumers[i]->HandleTranslationUnit(Ctx); 244} 245 246void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 247 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 248 Consumers[i]->HandleTagDeclDefinition(D); 249} 250 251void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 252 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 253 Consumers[i]->HandleCXXImplicitFunctionInstantiation(D); 254} 255 256void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 257 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 258 Consumers[i]->HandleTopLevelDeclInObjCContainer(D); 259} 260 261void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 262 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 263 Consumers[i]->CompleteTentativeDefinition(D); 264} 265 266void MultiplexConsumer::HandleVTable( 267 CXXRecordDecl *RD, bool DefinitionRequired) { 268 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 269 Consumers[i]->HandleVTable(RD, DefinitionRequired); 270} 271 272ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 273 return MutationListener.get(); 274} 275 276ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 277 return DeserializationListener.get(); 278} 279 280void MultiplexConsumer::PrintStats() { 281 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 282 Consumers[i]->PrintStats(); 283} 284 285void MultiplexConsumer::InitializeSema(Sema &S) { 286 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 287 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 288 SC->InitializeSema(S); 289} 290 291void MultiplexConsumer::ForgetSema() { 292 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 293 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 294 SC->ForgetSema(); 295} 296