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