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