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 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; 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 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 ResolvedOperatorDelete(const CXXDestructorDecl *DD, 103 const FunctionDecl *Delete) override; 104 void CompletedImplicitDefinition(const FunctionDecl *D) override; 105 void StaticDataMemberInstantiated(const VarDecl *D) override; 106 void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 107 const ObjCInterfaceDecl *IFD) override; 108 void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, 109 const ObjCPropertyDecl *OrigProp, 110 const ObjCCategoryDecl *ClassExt) override; 111 void DeclarationMarkedUsed(const Decl *D) override; 112 void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; 113 114 private: 115 std::vector<ASTMutationListener*> Listeners; 116 }; 117 118 MultiplexASTMutationListener::MultiplexASTMutationListener( 119 ArrayRef<ASTMutationListener*> L) 120 : Listeners(L.begin(), L.end()) { 121 } 122 123 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 124 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 125 Listeners[i]->CompletedTagDefinition(D); 126 } 127 128 void MultiplexASTMutationListener::AddedVisibleDecl( 129 const DeclContext *DC, const Decl *D) { 130 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 131 Listeners[i]->AddedVisibleDecl(DC, D); 132 } 133 134 void MultiplexASTMutationListener::AddedCXXImplicitMember( 135 const CXXRecordDecl *RD, const Decl *D) { 136 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 137 Listeners[i]->AddedCXXImplicitMember(RD, D); 138 } 139 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 140 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 141 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 142 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 143 } 144 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 145 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { 146 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 147 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 148 } 149 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 150 const FunctionTemplateDecl *TD, const FunctionDecl *D) { 151 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 152 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 153 } 154 void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, 155 QualType ReturnType) { 156 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 157 Listeners[i]->DeducedReturnType(FD, ReturnType); 158 } 159 void MultiplexASTMutationListener::ResolvedOperatorDelete( 160 const CXXDestructorDecl *DD, const FunctionDecl *Delete) { 161 for (auto *L : Listeners) 162 L->ResolvedOperatorDelete(DD, Delete); 163 } 164 void MultiplexASTMutationListener::CompletedImplicitDefinition( 165 const FunctionDecl *D) { 166 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 167 Listeners[i]->CompletedImplicitDefinition(D); 168 } 169 void MultiplexASTMutationListener::StaticDataMemberInstantiated( 170 const VarDecl *D) { 171 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 172 Listeners[i]->StaticDataMemberInstantiated(D); 173 } 174 void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 175 const ObjCCategoryDecl *CatD, 176 const ObjCInterfaceDecl *IFD) { 177 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 178 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 179 } 180 void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( 181 const ObjCPropertyDecl *Prop, 182 const ObjCPropertyDecl *OrigProp, 183 const ObjCCategoryDecl *ClassExt) { 184 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 185 Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt); 186 } 187 void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 188 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 189 Listeners[i]->DeclarationMarkedUsed(D); 190 } 191 void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( 192 const Decl *D) { 193 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 194 Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); 195 } 196 197 } // end namespace clang 198 199 MultiplexConsumer::MultiplexConsumer( 200 std::vector<std::unique_ptr<ASTConsumer>> C) 201 : Consumers(std::move(C)), MutationListener(), DeserializationListener() { 202 // Collect the mutation listeners and deserialization listeners of all 203 // children, and create a multiplex listener each if so. 204 std::vector<ASTMutationListener*> mutationListeners; 205 std::vector<ASTDeserializationListener*> serializationListeners; 206 for (auto &Consumer : Consumers) { 207 if (auto *mutationListener = Consumer->GetASTMutationListener()) 208 mutationListeners.push_back(mutationListener); 209 if (auto *serializationListener = Consumer->GetASTDeserializationListener()) 210 serializationListeners.push_back(serializationListener); 211 } 212 if (!mutationListeners.empty()) { 213 MutationListener = 214 llvm::make_unique<MultiplexASTMutationListener>(mutationListeners); 215 } 216 if (!serializationListeners.empty()) { 217 DeserializationListener = 218 llvm::make_unique<MultiplexASTDeserializationListener>( 219 serializationListeners); 220 } 221 } 222 223 MultiplexConsumer::~MultiplexConsumer() {} 224 225 void MultiplexConsumer::Initialize(ASTContext &Context) { 226 for (auto &Consumer : Consumers) 227 Consumer->Initialize(Context); 228 } 229 230 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 231 bool Continue = true; 232 for (auto &Consumer : Consumers) 233 Continue = Continue && Consumer->HandleTopLevelDecl(D); 234 return Continue; 235 } 236 237 void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) { 238 for (auto &Consumer : Consumers) 239 Consumer->HandleInlineMethodDefinition(D); 240 } 241 242 void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 243 for (auto &Consumer : Consumers) 244 Consumer->HandleCXXStaticMemberVarInstantiation(VD); 245 } 246 247 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 248 for (auto &Consumer : Consumers) 249 Consumer->HandleInterestingDecl(D); 250 } 251 252 void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 253 for (auto &Consumer : Consumers) 254 Consumer->HandleTranslationUnit(Ctx); 255 } 256 257 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 258 for (auto &Consumer : Consumers) 259 Consumer->HandleTagDeclDefinition(D); 260 } 261 262 void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { 263 for (auto &Consumer : Consumers) 264 Consumer->HandleTagDeclRequiredDefinition(D); 265 } 266 267 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 268 for (auto &Consumer : Consumers) 269 Consumer->HandleCXXImplicitFunctionInstantiation(D); 270 } 271 272 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 273 for (auto &Consumer : Consumers) 274 Consumer->HandleTopLevelDeclInObjCContainer(D); 275 } 276 277 void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { 278 for (auto &Consumer : Consumers) 279 Consumer->HandleImplicitImportDecl(D); 280 } 281 282 void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) { 283 for (auto &Consumer : Consumers) 284 Consumer->HandleLinkerOptionPragma(Opts); 285 } 286 287 void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { 288 for (auto &Consumer : Consumers) 289 Consumer->HandleDetectMismatch(Name, Value); 290 } 291 292 void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) { 293 for (auto &Consumer : Consumers) 294 Consumer->HandleDependentLibrary(Lib); 295 } 296 297 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 298 for (auto &Consumer : Consumers) 299 Consumer->CompleteTentativeDefinition(D); 300 } 301 302 void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) { 303 for (auto &Consumer : Consumers) 304 Consumer->HandleVTable(RD); 305 } 306 307 ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 308 return MutationListener.get(); 309 } 310 311 ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 312 return DeserializationListener.get(); 313 } 314 315 void MultiplexConsumer::PrintStats() { 316 for (auto &Consumer : Consumers) 317 Consumer->PrintStats(); 318 } 319 320 void MultiplexConsumer::InitializeSema(Sema &S) { 321 for (auto &Consumer : Consumers) 322 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 323 SC->InitializeSema(S); 324 } 325 326 void MultiplexConsumer::ForgetSema() { 327 for (auto &Consumer : Consumers) 328 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 329 SC->ForgetSema(); 330 } 331