MultiplexConsumer.cpp revision 6d968363877388f0a0268711d59367907b465ae1
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 22using namespace clang; 23 24namespace clang { 25 26// This ASTDeserializationListener forwards its notifications to a set of 27// child listeners. 28class MultiplexASTDeserializationListener 29 : public ASTDeserializationListener { 30public: 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); 42private: 43 std::vector<ASTDeserializationListener*> Listeners; 44}; 45 46MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( 47 const std::vector<ASTDeserializationListener*>& L) 48 : Listeners(L) { 49} 50 51void MultiplexASTDeserializationListener::ReaderInitialized( 52 ASTReader *Reader) { 53 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 54 Listeners[i]->ReaderInitialized(Reader); 55} 56 57void 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 63void 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 69void 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 75void 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 81void 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. 89class MultiplexASTMutationListener : public ASTMutationListener { 90public: 91 // Does NOT take ownership of the elements in L. 92 MultiplexASTMutationListener(ArrayRef<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 virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 103 const ObjCInterfaceDecl *IFD); 104 virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, 105 const ObjCPropertyDecl *OrigProp, 106 const ObjCCategoryDecl *ClassExt); 107private: 108 std::vector<ASTMutationListener*> Listeners; 109}; 110 111MultiplexASTMutationListener::MultiplexASTMutationListener( 112 ArrayRef<ASTMutationListener*> L) 113 : Listeners(L.begin(), L.end()) { 114} 115 116void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 117 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 118 Listeners[i]->CompletedTagDefinition(D); 119} 120 121void MultiplexASTMutationListener::AddedVisibleDecl( 122 const DeclContext *DC, const Decl *D) { 123 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 124 Listeners[i]->AddedVisibleDecl(DC, D); 125} 126 127void MultiplexASTMutationListener::AddedCXXImplicitMember( 128 const CXXRecordDecl *RD, const Decl *D) { 129 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 130 Listeners[i]->AddedCXXImplicitMember(RD, D); 131} 132void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 133 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 134 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 135 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 136} 137void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 138 const FunctionTemplateDecl *TD, const FunctionDecl *D) { 139 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 140 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 141} 142void MultiplexASTMutationListener::CompletedImplicitDefinition( 143 const FunctionDecl *D) { 144 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 145 Listeners[i]->CompletedImplicitDefinition(D); 146} 147void MultiplexASTMutationListener::StaticDataMemberInstantiated( 148 const VarDecl *D) { 149 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 150 Listeners[i]->StaticDataMemberInstantiated(D); 151} 152void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 153 const ObjCCategoryDecl *CatD, 154 const ObjCInterfaceDecl *IFD) { 155 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 156 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 157} 158void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( 159 const ObjCPropertyDecl *Prop, 160 const ObjCPropertyDecl *OrigProp, 161 const ObjCCategoryDecl *ClassExt) { 162 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 163 Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt); 164} 165 166} // end namespace clang 167 168 169MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer*> C) 170 : Consumers(C.begin(), C.end()), 171 MutationListener(0), DeserializationListener(0) { 172 // Collect the mutation listeners and deserialization listeners of all 173 // children, and create a multiplex listener each if so. 174 std::vector<ASTMutationListener*> mutationListeners; 175 std::vector<ASTDeserializationListener*> serializationListeners; 176 for (size_t i = 0, e = Consumers.size(); i != e; ++i) { 177 ASTMutationListener* mutationListener = 178 Consumers[i]->GetASTMutationListener(); 179 if (mutationListener) 180 mutationListeners.push_back(mutationListener); 181 ASTDeserializationListener* serializationListener = 182 Consumers[i]->GetASTDeserializationListener(); 183 if (serializationListener) 184 serializationListeners.push_back(serializationListener); 185 } 186 if (mutationListeners.size()) { 187 MutationListener.reset(new MultiplexASTMutationListener(mutationListeners)); 188 } 189 if (serializationListeners.size()) { 190 DeserializationListener.reset( 191 new MultiplexASTDeserializationListener(serializationListeners)); 192 } 193} 194 195MultiplexConsumer::~MultiplexConsumer() { 196 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 197 delete Consumers[i]; 198} 199 200void MultiplexConsumer::Initialize(ASTContext &Context) { 201 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 202 Consumers[i]->Initialize(Context); 203} 204 205bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 206 bool Continue = true; 207 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 208 Continue = Continue && Consumers[i]->HandleTopLevelDecl(D); 209 return Continue; 210} 211 212void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 213 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 214 Consumers[i]->HandleInterestingDecl(D); 215} 216 217void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 218 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 219 Consumers[i]->HandleTranslationUnit(Ctx); 220} 221 222void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 223 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 224 Consumers[i]->HandleTagDeclDefinition(D); 225} 226 227void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 228 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 229 Consumers[i]->HandleCXXImplicitFunctionInstantiation(D); 230} 231 232void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 233 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 234 Consumers[i]->HandleTopLevelDeclInObjCContainer(D); 235} 236 237void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 238 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 239 Consumers[i]->CompleteTentativeDefinition(D); 240} 241 242void MultiplexConsumer::HandleVTable( 243 CXXRecordDecl *RD, bool DefinitionRequired) { 244 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 245 Consumers[i]->HandleVTable(RD, DefinitionRequired); 246} 247 248ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 249 return MutationListener.get(); 250} 251 252ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 253 return DeserializationListener.get(); 254} 255 256void MultiplexConsumer::PrintStats() { 257 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 258 Consumers[i]->PrintStats(); 259} 260 261void MultiplexConsumer::InitializeSema(Sema &S) { 262 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 263 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 264 SC->InitializeSema(S); 265} 266 267void MultiplexConsumer::ForgetSema() { 268 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 269 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 270 SC->ForgetSema(); 271} 272