1 //===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the MultiplexConsumer class. It also declares and defines 10 // MultiplexASTDeserializationListener and MultiplexASTMutationListener, which 11 // are implementation details of MultiplexConsumer. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Frontend/MultiplexConsumer.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/DeclGroup.h" 18 19 using namespace clang; 20 21 namespace clang { 22 23 MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( 24 const std::vector<ASTDeserializationListener*>& L) 25 : Listeners(L) { 26 } 27 28 void MultiplexASTDeserializationListener::ReaderInitialized( 29 ASTReader *Reader) { 30 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 31 Listeners[i]->ReaderInitialized(Reader); 32 } 33 34 void MultiplexASTDeserializationListener::IdentifierRead( 35 serialization::IdentID ID, IdentifierInfo *II) { 36 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 37 Listeners[i]->IdentifierRead(ID, II); 38 } 39 40 void MultiplexASTDeserializationListener::MacroRead( 41 serialization::MacroID ID, MacroInfo *MI) { 42 for (auto &Listener : Listeners) 43 Listener->MacroRead(ID, MI); 44 } 45 46 void MultiplexASTDeserializationListener::TypeRead( 47 serialization::TypeIdx Idx, QualType T) { 48 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 49 Listeners[i]->TypeRead(Idx, T); 50 } 51 52 void MultiplexASTDeserializationListener::DeclRead( 53 serialization::DeclID ID, const Decl *D) { 54 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 55 Listeners[i]->DeclRead(ID, D); 56 } 57 58 void MultiplexASTDeserializationListener::SelectorRead( 59 serialization::SelectorID ID, Selector Sel) { 60 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 61 Listeners[i]->SelectorRead(ID, Sel); 62 } 63 64 void MultiplexASTDeserializationListener::MacroDefinitionRead( 65 serialization::PreprocessedEntityID ID, MacroDefinitionRecord *MD) { 66 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 67 Listeners[i]->MacroDefinitionRead(ID, MD); 68 } 69 70 void MultiplexASTDeserializationListener::ModuleRead( 71 serialization::SubmoduleID ID, Module *Mod) { 72 for (auto &Listener : Listeners) 73 Listener->ModuleRead(ID, Mod); 74 } 75 76 // This ASTMutationListener forwards its notifications to a set of 77 // child listeners. 78 class MultiplexASTMutationListener : public ASTMutationListener { 79 public: 80 // Does NOT take ownership of the elements in L. 81 MultiplexASTMutationListener(ArrayRef<ASTMutationListener*> L); 82 void CompletedTagDefinition(const TagDecl *D) override; 83 void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; 84 void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; 85 void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 86 const ClassTemplateSpecializationDecl *D) override; 87 void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, 88 const VarTemplateSpecializationDecl *D) override; 89 void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 90 const FunctionDecl *D) override; 91 void ResolvedExceptionSpec(const FunctionDecl *FD) override; 92 void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; 93 void ResolvedOperatorDelete(const CXXDestructorDecl *DD, 94 const FunctionDecl *Delete, 95 Expr *ThisArg) override; 96 void CompletedImplicitDefinition(const FunctionDecl *D) override; 97 void InstantiationRequested(const ValueDecl *D) override; 98 void VariableDefinitionInstantiated(const VarDecl *D) override; 99 void FunctionDefinitionInstantiated(const FunctionDecl *D) override; 100 void DefaultArgumentInstantiated(const ParmVarDecl *D) override; 101 void DefaultMemberInitializerInstantiated(const FieldDecl *D) override; 102 void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 103 const ObjCInterfaceDecl *IFD) override; 104 void DeclarationMarkedUsed(const Decl *D) override; 105 void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; 106 void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, 107 const Attr *Attr) override; 108 void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; 109 void AddedAttributeToRecord(const Attr *Attr, 110 const RecordDecl *Record) 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::ResolvedExceptionSpec( 153 const FunctionDecl *FD) { 154 for (auto &Listener : Listeners) 155 Listener->ResolvedExceptionSpec(FD); 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, Expr *ThisArg) { 164 for (auto *L : Listeners) 165 L->ResolvedOperatorDelete(DD, Delete, ThisArg); 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::InstantiationRequested(const ValueDecl *D) { 173 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 174 Listeners[i]->InstantiationRequested(D); 175 } 176 void MultiplexASTMutationListener::VariableDefinitionInstantiated( 177 const VarDecl *D) { 178 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 179 Listeners[i]->VariableDefinitionInstantiated(D); 180 } 181 void MultiplexASTMutationListener::FunctionDefinitionInstantiated( 182 const FunctionDecl *D) { 183 for (auto &Listener : Listeners) 184 Listener->FunctionDefinitionInstantiated(D); 185 } 186 void MultiplexASTMutationListener::DefaultArgumentInstantiated( 187 const ParmVarDecl *D) { 188 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 189 Listeners[i]->DefaultArgumentInstantiated(D); 190 } 191 void MultiplexASTMutationListener::DefaultMemberInitializerInstantiated( 192 const FieldDecl *D) { 193 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 194 Listeners[i]->DefaultMemberInitializerInstantiated(D); 195 } 196 void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 197 const ObjCCategoryDecl *CatD, 198 const ObjCInterfaceDecl *IFD) { 199 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 200 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 201 } 202 void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 203 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 204 Listeners[i]->DeclarationMarkedUsed(D); 205 } 206 void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( 207 const Decl *D) { 208 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 209 Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); 210 } 211 void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( 212 const Decl *D, const Attr *Attr) { 213 for (auto *L : Listeners) 214 L->DeclarationMarkedOpenMPDeclareTarget(D, Attr); 215 } 216 void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D, 217 Module *M) { 218 for (auto *L : Listeners) 219 L->RedefinedHiddenDefinition(D, M); 220 } 221 222 void MultiplexASTMutationListener::AddedAttributeToRecord( 223 const Attr *Attr, 224 const RecordDecl *Record) { 225 for (auto *L : Listeners) 226 L->AddedAttributeToRecord(Attr, Record); 227 } 228 229 } // end namespace clang 230 231 MultiplexConsumer::MultiplexConsumer( 232 std::vector<std::unique_ptr<ASTConsumer>> C) 233 : Consumers(std::move(C)), MutationListener(), DeserializationListener() { 234 // Collect the mutation listeners and deserialization listeners of all 235 // children, and create a multiplex listener each if so. 236 std::vector<ASTMutationListener*> mutationListeners; 237 std::vector<ASTDeserializationListener*> serializationListeners; 238 for (auto &Consumer : Consumers) { 239 if (auto *mutationListener = Consumer->GetASTMutationListener()) 240 mutationListeners.push_back(mutationListener); 241 if (auto *serializationListener = Consumer->GetASTDeserializationListener()) 242 serializationListeners.push_back(serializationListener); 243 } 244 if (!mutationListeners.empty()) { 245 MutationListener = 246 llvm::make_unique<MultiplexASTMutationListener>(mutationListeners); 247 } 248 if (!serializationListeners.empty()) { 249 DeserializationListener = 250 llvm::make_unique<MultiplexASTDeserializationListener>( 251 serializationListeners); 252 } 253 } 254 255 MultiplexConsumer::~MultiplexConsumer() {} 256 257 void MultiplexConsumer::Initialize(ASTContext &Context) { 258 for (auto &Consumer : Consumers) 259 Consumer->Initialize(Context); 260 } 261 262 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 263 bool Continue = true; 264 for (auto &Consumer : Consumers) 265 Continue = Continue && Consumer->HandleTopLevelDecl(D); 266 return Continue; 267 } 268 269 void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { 270 for (auto &Consumer : Consumers) 271 Consumer->HandleInlineFunctionDefinition(D); 272 } 273 274 void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 275 for (auto &Consumer : Consumers) 276 Consumer->HandleCXXStaticMemberVarInstantiation(VD); 277 } 278 279 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 280 for (auto &Consumer : Consumers) 281 Consumer->HandleInterestingDecl(D); 282 } 283 284 void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 285 for (auto &Consumer : Consumers) 286 Consumer->HandleTranslationUnit(Ctx); 287 } 288 289 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 290 for (auto &Consumer : Consumers) 291 Consumer->HandleTagDeclDefinition(D); 292 } 293 294 void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { 295 for (auto &Consumer : Consumers) 296 Consumer->HandleTagDeclRequiredDefinition(D); 297 } 298 299 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 300 for (auto &Consumer : Consumers) 301 Consumer->HandleCXXImplicitFunctionInstantiation(D); 302 } 303 304 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 305 for (auto &Consumer : Consumers) 306 Consumer->HandleTopLevelDeclInObjCContainer(D); 307 } 308 309 void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { 310 for (auto &Consumer : Consumers) 311 Consumer->HandleImplicitImportDecl(D); 312 } 313 314 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 315 for (auto &Consumer : Consumers) 316 Consumer->CompleteTentativeDefinition(D); 317 } 318 319 void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) { 320 for (auto &Consumer : Consumers) 321 Consumer->AssignInheritanceModel(RD); 322 } 323 324 void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) { 325 for (auto &Consumer : Consumers) 326 Consumer->HandleVTable(RD); 327 } 328 329 ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 330 return MutationListener.get(); 331 } 332 333 ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 334 return DeserializationListener.get(); 335 } 336 337 void MultiplexConsumer::PrintStats() { 338 for (auto &Consumer : Consumers) 339 Consumer->PrintStats(); 340 } 341 342 bool MultiplexConsumer::shouldSkipFunctionBody(Decl *D) { 343 bool Skip = true; 344 for (auto &Consumer : Consumers) 345 Skip = Skip && Consumer->shouldSkipFunctionBody(D); 346 return Skip; 347 } 348 349 void MultiplexConsumer::InitializeSema(Sema &S) { 350 for (auto &Consumer : Consumers) 351 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 352 SC->InitializeSema(S); 353 } 354 355 void MultiplexConsumer::ForgetSema() { 356 for (auto &Consumer : Consumers) 357 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 358 SC->ForgetSema(); 359 } 360