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