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 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 void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; 111 112 private: 113 std::vector<ASTMutationListener*> Listeners; 114 }; 115 116 MultiplexASTMutationListener::MultiplexASTMutationListener( 117 ArrayRef<ASTMutationListener*> L) 118 : Listeners(L.begin(), L.end()) { 119 } 120 121 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 122 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 123 Listeners[i]->CompletedTagDefinition(D); 124 } 125 126 void 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 132 void 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 } 137 void 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 } 142 void 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 } 147 void 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 } 152 void 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 } 157 void MultiplexASTMutationListener::CompletedImplicitDefinition( 158 const FunctionDecl *D) { 159 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 160 Listeners[i]->CompletedImplicitDefinition(D); 161 } 162 void MultiplexASTMutationListener::StaticDataMemberInstantiated( 163 const VarDecl *D) { 164 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 165 Listeners[i]->StaticDataMemberInstantiated(D); 166 } 167 void 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 } 173 void 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 } 180 void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 181 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 182 Listeners[i]->DeclarationMarkedUsed(D); 183 } 184 void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( 185 const Decl *D) { 186 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 187 Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); 188 } 189 190 } // end namespace clang 191 192 MultiplexConsumer::MultiplexConsumer( 193 std::vector<std::unique_ptr<ASTConsumer>> C) 194 : Consumers(std::move(C)), MutationListener(), DeserializationListener() { 195 // Collect the mutation listeners and deserialization listeners of all 196 // children, and create a multiplex listener each if so. 197 std::vector<ASTMutationListener*> mutationListeners; 198 std::vector<ASTDeserializationListener*> serializationListeners; 199 for (auto &Consumer : Consumers) { 200 if (auto *mutationListener = Consumer->GetASTMutationListener()) 201 mutationListeners.push_back(mutationListener); 202 if (auto *serializationListener = Consumer->GetASTDeserializationListener()) 203 serializationListeners.push_back(serializationListener); 204 } 205 if (!mutationListeners.empty()) { 206 MutationListener = 207 llvm::make_unique<MultiplexASTMutationListener>(mutationListeners); 208 } 209 if (!serializationListeners.empty()) { 210 DeserializationListener = 211 llvm::make_unique<MultiplexASTDeserializationListener>( 212 serializationListeners); 213 } 214 } 215 216 MultiplexConsumer::~MultiplexConsumer() {} 217 218 void MultiplexConsumer::Initialize(ASTContext &Context) { 219 for (auto &Consumer : Consumers) 220 Consumer->Initialize(Context); 221 } 222 223 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 224 bool Continue = true; 225 for (auto &Consumer : Consumers) 226 Continue = Continue && Consumer->HandleTopLevelDecl(D); 227 return Continue; 228 } 229 230 void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) { 231 for (auto &Consumer : Consumers) 232 Consumer->HandleInlineMethodDefinition(D); 233 } 234 235 void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 236 for (auto &Consumer : Consumers) 237 Consumer->HandleCXXStaticMemberVarInstantiation(VD); 238 } 239 240 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 241 for (auto &Consumer : Consumers) 242 Consumer->HandleInterestingDecl(D); 243 } 244 245 void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 246 for (auto &Consumer : Consumers) 247 Consumer->HandleTranslationUnit(Ctx); 248 } 249 250 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 251 for (auto &Consumer : Consumers) 252 Consumer->HandleTagDeclDefinition(D); 253 } 254 255 void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { 256 for (auto &Consumer : Consumers) 257 Consumer->HandleTagDeclRequiredDefinition(D); 258 } 259 260 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 261 for (auto &Consumer : Consumers) 262 Consumer->HandleCXXImplicitFunctionInstantiation(D); 263 } 264 265 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 266 for (auto &Consumer : Consumers) 267 Consumer->HandleTopLevelDeclInObjCContainer(D); 268 } 269 270 void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { 271 for (auto &Consumer : Consumers) 272 Consumer->HandleImplicitImportDecl(D); 273 } 274 275 void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) { 276 for (auto &Consumer : Consumers) 277 Consumer->HandleLinkerOptionPragma(Opts); 278 } 279 280 void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { 281 for (auto &Consumer : Consumers) 282 Consumer->HandleDetectMismatch(Name, Value); 283 } 284 285 void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) { 286 for (auto &Consumer : Consumers) 287 Consumer->HandleDependentLibrary(Lib); 288 } 289 290 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 291 for (auto &Consumer : Consumers) 292 Consumer->CompleteTentativeDefinition(D); 293 } 294 295 void MultiplexConsumer::HandleVTable( 296 CXXRecordDecl *RD, bool DefinitionRequired) { 297 for (auto &Consumer : Consumers) 298 Consumer->HandleVTable(RD, DefinitionRequired); 299 } 300 301 ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 302 return MutationListener.get(); 303 } 304 305 ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 306 return DeserializationListener.get(); 307 } 308 309 void MultiplexConsumer::PrintStats() { 310 for (auto &Consumer : Consumers) 311 Consumer->PrintStats(); 312 } 313 314 void MultiplexConsumer::InitializeSema(Sema &S) { 315 for (auto &Consumer : Consumers) 316 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 317 SC->InitializeSema(S); 318 } 319 320 void MultiplexConsumer::ForgetSema() { 321 for (auto &Consumer : Consumers) 322 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 323 SC->ForgetSema(); 324 } 325