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 19using namespace clang; 20 21namespace clang { 22 23MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( 24 const std::vector<ASTDeserializationListener*>& L) 25 : Listeners(L) { 26} 27 28void MultiplexASTDeserializationListener::ReaderInitialized( 29 ASTReader *Reader) { 30 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 31 Listeners[i]->ReaderInitialized(Reader); 32} 33 34void 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 40void MultiplexASTDeserializationListener::MacroRead( 41 serialization::MacroID ID, MacroInfo *MI) { 42 for (auto &Listener : Listeners) 43 Listener->MacroRead(ID, MI); 44} 45 46void 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 52void 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 58void 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 64void 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 70void MultiplexASTDeserializationListener::ModuleRead( 71 serialization::SubmoduleID ID, Module *Mod) { 72 for (auto &Listener : Listeners) 73 Listener->ModuleRead(ID, Mod); 74} 75 76void MultiplexASTDeserializationListener::ModuleImportRead( 77 serialization::SubmoduleID ID, SourceLocation ImportLoc) { 78 for (auto &Listener : Listeners) 79 Listener->ModuleImportRead(ID, ImportLoc); 80} 81 82// This ASTMutationListener forwards its notifications to a set of 83// child listeners. 84class MultiplexASTMutationListener : public ASTMutationListener { 85public: 86 // Does NOT take ownership of the elements in L. 87 MultiplexASTMutationListener(ArrayRef<ASTMutationListener*> L); 88 void CompletedTagDefinition(const TagDecl *D) override; 89 void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; 90 void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; 91 void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, 92 const ClassTemplateSpecializationDecl *D) override; 93 void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, 94 const VarTemplateSpecializationDecl *D) override; 95 void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, 96 const FunctionDecl *D) override; 97 void ResolvedExceptionSpec(const FunctionDecl *FD) override; 98 void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; 99 void ResolvedOperatorDelete(const CXXDestructorDecl *DD, 100 const FunctionDecl *Delete, 101 Expr *ThisArg) override; 102 void CompletedImplicitDefinition(const FunctionDecl *D) override; 103 void InstantiationRequested(const ValueDecl *D) override; 104 void VariableDefinitionInstantiated(const VarDecl *D) override; 105 void FunctionDefinitionInstantiated(const FunctionDecl *D) override; 106 void DefaultArgumentInstantiated(const ParmVarDecl *D) override; 107 void DefaultMemberInitializerInstantiated(const FieldDecl *D) override; 108 void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, 109 const ObjCInterfaceDecl *IFD) override; 110 void DeclarationMarkedUsed(const Decl *D) override; 111 void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; 112 void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override; 113 void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, 114 const Attr *Attr) override; 115 void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; 116 void AddedAttributeToRecord(const Attr *Attr, 117 const RecordDecl *Record) override; 118 119private: 120 std::vector<ASTMutationListener*> Listeners; 121}; 122 123MultiplexASTMutationListener::MultiplexASTMutationListener( 124 ArrayRef<ASTMutationListener*> L) 125 : Listeners(L.begin(), L.end()) { 126} 127 128void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 129 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 130 Listeners[i]->CompletedTagDefinition(D); 131} 132 133void MultiplexASTMutationListener::AddedVisibleDecl( 134 const DeclContext *DC, const Decl *D) { 135 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 136 Listeners[i]->AddedVisibleDecl(DC, D); 137} 138 139void MultiplexASTMutationListener::AddedCXXImplicitMember( 140 const CXXRecordDecl *RD, const Decl *D) { 141 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 142 Listeners[i]->AddedCXXImplicitMember(RD, D); 143} 144void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 145 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { 146 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 147 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 148} 149void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 150 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { 151 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 152 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 153} 154void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( 155 const FunctionTemplateDecl *TD, const FunctionDecl *D) { 156 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 157 Listeners[i]->AddedCXXTemplateSpecialization(TD, D); 158} 159void MultiplexASTMutationListener::ResolvedExceptionSpec( 160 const FunctionDecl *FD) { 161 for (auto &Listener : Listeners) 162 Listener->ResolvedExceptionSpec(FD); 163} 164void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, 165 QualType ReturnType) { 166 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 167 Listeners[i]->DeducedReturnType(FD, ReturnType); 168} 169void MultiplexASTMutationListener::ResolvedOperatorDelete( 170 const CXXDestructorDecl *DD, const FunctionDecl *Delete, Expr *ThisArg) { 171 for (auto *L : Listeners) 172 L->ResolvedOperatorDelete(DD, Delete, ThisArg); 173} 174void MultiplexASTMutationListener::CompletedImplicitDefinition( 175 const FunctionDecl *D) { 176 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 177 Listeners[i]->CompletedImplicitDefinition(D); 178} 179void MultiplexASTMutationListener::InstantiationRequested(const ValueDecl *D) { 180 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 181 Listeners[i]->InstantiationRequested(D); 182} 183void MultiplexASTMutationListener::VariableDefinitionInstantiated( 184 const VarDecl *D) { 185 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 186 Listeners[i]->VariableDefinitionInstantiated(D); 187} 188void MultiplexASTMutationListener::FunctionDefinitionInstantiated( 189 const FunctionDecl *D) { 190 for (auto &Listener : Listeners) 191 Listener->FunctionDefinitionInstantiated(D); 192} 193void MultiplexASTMutationListener::DefaultArgumentInstantiated( 194 const ParmVarDecl *D) { 195 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 196 Listeners[i]->DefaultArgumentInstantiated(D); 197} 198void MultiplexASTMutationListener::DefaultMemberInitializerInstantiated( 199 const FieldDecl *D) { 200 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 201 Listeners[i]->DefaultMemberInitializerInstantiated(D); 202} 203void MultiplexASTMutationListener::AddedObjCCategoryToInterface( 204 const ObjCCategoryDecl *CatD, 205 const ObjCInterfaceDecl *IFD) { 206 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 207 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); 208} 209void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { 210 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 211 Listeners[i]->DeclarationMarkedUsed(D); 212} 213void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( 214 const Decl *D) { 215 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 216 Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); 217} 218void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate( 219 const Decl *D, const Attr *A) { 220 for (ASTMutationListener *L : Listeners) 221 L->DeclarationMarkedOpenMPAllocate(D, A); 222} 223void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( 224 const Decl *D, const Attr *Attr) { 225 for (auto *L : Listeners) 226 L->DeclarationMarkedOpenMPDeclareTarget(D, Attr); 227} 228void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D, 229 Module *M) { 230 for (auto *L : Listeners) 231 L->RedefinedHiddenDefinition(D, M); 232} 233 234void MultiplexASTMutationListener::AddedAttributeToRecord( 235 const Attr *Attr, 236 const RecordDecl *Record) { 237 for (auto *L : Listeners) 238 L->AddedAttributeToRecord(Attr, Record); 239} 240 241} // end namespace clang 242 243MultiplexConsumer::MultiplexConsumer( 244 std::vector<std::unique_ptr<ASTConsumer>> C) 245 : Consumers(std::move(C)) { 246 // Collect the mutation listeners and deserialization listeners of all 247 // children, and create a multiplex listener each if so. 248 std::vector<ASTMutationListener *> mutationListeners; 249 std::vector<ASTDeserializationListener*> serializationListeners; 250 for (auto &Consumer : Consumers) { 251 if (auto *mutationListener = Consumer->GetASTMutationListener()) 252 mutationListeners.push_back(mutationListener); 253 if (auto *serializationListener = Consumer->GetASTDeserializationListener()) 254 serializationListeners.push_back(serializationListener); 255 } 256 if (!mutationListeners.empty()) { 257 MutationListener = 258 std::make_unique<MultiplexASTMutationListener>(mutationListeners); 259 } 260 if (!serializationListeners.empty()) { 261 DeserializationListener = 262 std::make_unique<MultiplexASTDeserializationListener>( 263 serializationListeners); 264 } 265} 266 267MultiplexConsumer::~MultiplexConsumer() {} 268 269void MultiplexConsumer::Initialize(ASTContext &Context) { 270 for (auto &Consumer : Consumers) 271 Consumer->Initialize(Context); 272} 273 274bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 275 bool Continue = true; 276 for (auto &Consumer : Consumers) 277 Continue = Continue && Consumer->HandleTopLevelDecl(D); 278 return Continue; 279} 280 281void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { 282 for (auto &Consumer : Consumers) 283 Consumer->HandleInlineFunctionDefinition(D); 284} 285 286void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 287 for (auto &Consumer : Consumers) 288 Consumer->HandleCXXStaticMemberVarInstantiation(VD); 289} 290 291void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 292 for (auto &Consumer : Consumers) 293 Consumer->HandleInterestingDecl(D); 294} 295 296void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 297 for (auto &Consumer : Consumers) 298 Consumer->HandleTranslationUnit(Ctx); 299} 300 301void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 302 for (auto &Consumer : Consumers) 303 Consumer->HandleTagDeclDefinition(D); 304} 305 306void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { 307 for (auto &Consumer : Consumers) 308 Consumer->HandleTagDeclRequiredDefinition(D); 309} 310 311void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ 312 for (auto &Consumer : Consumers) 313 Consumer->HandleCXXImplicitFunctionInstantiation(D); 314} 315 316void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 317 for (auto &Consumer : Consumers) 318 Consumer->HandleTopLevelDeclInObjCContainer(D); 319} 320 321void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { 322 for (auto &Consumer : Consumers) 323 Consumer->HandleImplicitImportDecl(D); 324} 325 326void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 327 for (auto &Consumer : Consumers) 328 Consumer->CompleteTentativeDefinition(D); 329} 330 331void MultiplexConsumer::CompleteExternalDeclaration(VarDecl *D) { 332 for (auto &Consumer : Consumers) 333 Consumer->CompleteExternalDeclaration(D); 334} 335 336void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) { 337 for (auto &Consumer : Consumers) 338 Consumer->AssignInheritanceModel(RD); 339} 340 341void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) { 342 for (auto &Consumer : Consumers) 343 Consumer->HandleVTable(RD); 344} 345 346ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 347 return MutationListener.get(); 348} 349 350ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 351 return DeserializationListener.get(); 352} 353 354void MultiplexConsumer::PrintStats() { 355 for (auto &Consumer : Consumers) 356 Consumer->PrintStats(); 357} 358 359bool MultiplexConsumer::shouldSkipFunctionBody(Decl *D) { 360 bool Skip = true; 361 for (auto &Consumer : Consumers) 362 Skip = Skip && Consumer->shouldSkipFunctionBody(D); 363 return Skip; 364} 365 366void MultiplexConsumer::InitializeSema(Sema &S) { 367 for (auto &Consumer : Consumers) 368 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 369 SC->InitializeSema(S); 370} 371 372void MultiplexConsumer::ForgetSema() { 373 for (auto &Consumer : Consumers) 374 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) 375 SC->ForgetSema(); 376} 377