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 void ReaderInitialized(ASTReader *Reader) override; 34 void IdentifierRead(serialization::IdentID ID, 35 IdentifierInfo *II) override; 36 void TypeRead(serialization::TypeIdx Idx, QualType T) override; 37 void DeclRead(serialization::DeclID ID, const Decl *D) override; 38 void SelectorRead(serialization::SelectorID iD, Selector Sel) override; 39 void MacroDefinitionRead(serialization::PreprocessedEntityID, 40 MacroDefinition *MD) override; 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 void CompletedTagDefinition(const TagDecl *D) override; 93 void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; 94 void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; 95 void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 96 const ClassTemplateSpecializationDecl *D) override; 97 void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, 98 const VarTemplateSpecializationDecl *D) override; 99 void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 100 const FunctionDecl *D) override; 101 void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; 102 void CompletedImplicitDefinition(const FunctionDecl *D) override; 103 void StaticDataMemberInstantiated(const VarDecl *D) override; 104 void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 105 const ObjCInterfaceDecl *IFD) override; 106 void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, 107 const ObjCPropertyDecl *OrigProp, 108 const ObjCCategoryDecl *ClassExt) override; 109 void DeclarationMarkedUsed(const Decl *D) override; 110 111private: 112 std::vector<ASTMutationListener*> Listeners; 113}; 114 115MultiplexASTMutationListener::MultiplexASTMutationListener( 116 ArrayRef<ASTMutationListener*> L) 117 : Listeners(L.begin(), L.end()) { 118} 119 120void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 121 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 122 Listeners[i]->CompletedTagDefinition(D); 123} 124 125void MultiplexASTMutationListener::AddedVisibleDecl( 126 const DeclContext *DC, const Decl *D) { 127 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 128 Listeners[i]->AddedVisibleDecl(DC, D); 129} 130 131void MultiplexASTMutationListener::AddedCXXImplicitMember( 132 const CXXRecordDecl *RD, const Decl *D) { 133 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 134 Listeners[i]->AddedCXXImplicitMember(RD, D); 135} 136void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 137 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 138 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 139 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 140} 141void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 142 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { 143 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 144 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 145} 146void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 147 const FunctionTemplateDecl *TD, const FunctionDecl *D) { 148 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 149 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 150} 151void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, 152 QualType ReturnType) { 153 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 154 Listeners[i]->DeducedReturnType(FD, ReturnType); 155} 156void MultiplexASTMutationListener::CompletedImplicitDefinition( 157 const FunctionDecl *D) { 158 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 159 Listeners[i]->CompletedImplicitDefinition(D); 160} 161void MultiplexASTMutationListener::StaticDataMemberInstantiated( 162 const VarDecl *D) { 163 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 164 Listeners[i]->StaticDataMemberInstantiated(D); 165} 166void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 167 const ObjCCategoryDecl *CatD, 168 const ObjCInterfaceDecl *IFD) { 169 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 170 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 171} 172void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( 173 const ObjCPropertyDecl *Prop, 174 const ObjCPropertyDecl *OrigProp, 175 const ObjCCategoryDecl *ClassExt) { 176 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 177 Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt); 178} 179void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 180 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 181 Listeners[i]->DeclarationMarkedUsed(D); 182} 183 184} // end namespace clang 185 186MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer *> C) 187 : Consumers(C.begin(), C.end()), MutationListener(), 188 DeserializationListener() { 189 // Collect the mutation listeners and deserialization listeners of all 190 // children, and create a multiplex listener each if so. 191 std::vector<ASTMutationListener*> mutationListeners; 192 std::vector<ASTDeserializationListener*> serializationListeners; 193 for (size_t i = 0, e = Consumers.size(); i != e; ++i) { 194 ASTMutationListener* mutationListener = 195 Consumers[i]->GetASTMutationListener(); 196 if (mutationListener) 197 mutationListeners.push_back(mutationListener); 198 ASTDeserializationListener* serializationListener = 199 Consumers[i]->GetASTDeserializationListener(); 200 if (serializationListener) 201 serializationListeners.push_back(serializationListener); 202 } 203 if (mutationListeners.size()) { 204 MutationListener.reset(new MultiplexASTMutationListener(mutationListeners)); 205 } 206 if (serializationListeners.size()) { 207 DeserializationListener.reset( 208 new MultiplexASTDeserializationListener(serializationListeners)); 209 } 210} 211 212MultiplexConsumer::~MultiplexConsumer() { 213 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 214 delete Consumers[i]; 215} 216 217void MultiplexConsumer::Initialize(ASTContext &Context) { 218 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 219 Consumers[i]->Initialize(Context); 220} 221 222bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 223 bool Continue = true; 224 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 225 Continue = Continue && Consumers[i]->HandleTopLevelDecl(D); 226 return Continue; 227} 228 229void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) { 230 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 231 Consumers[i]->HandleInlineMethodDefinition(D); 232} 233 234void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 235 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 236 Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD); 237} 238 239void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 240 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 241 Consumers[i]->HandleInterestingDecl(D); 242} 243 244void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 245 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 246 Consumers[i]->HandleTranslationUnit(Ctx); 247} 248 249void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 250 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 251 Consumers[i]->HandleTagDeclDefinition(D); 252} 253 254void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 255 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 256 Consumers[i]->HandleCXXImplicitFunctionInstantiation(D); 257} 258 259void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 260 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 261 Consumers[i]->HandleTopLevelDeclInObjCContainer(D); 262} 263 264void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 265 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 266 Consumers[i]->CompleteTentativeDefinition(D); 267} 268 269void MultiplexConsumer::HandleVTable( 270 CXXRecordDecl *RD, bool DefinitionRequired) { 271 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 272 Consumers[i]->HandleVTable(RD, DefinitionRequired); 273} 274 275ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 276 return MutationListener.get(); 277} 278 279ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 280 return DeserializationListener.get(); 281} 282 283void MultiplexConsumer::PrintStats() { 284 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 285 Consumers[i]->PrintStats(); 286} 287 288void MultiplexConsumer::InitializeSema(Sema &S) { 289 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 290 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 291 SC->InitializeSema(S); 292} 293 294void MultiplexConsumer::ForgetSema() { 295 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 296 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 297 SC->ForgetSema(); 298} 299