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 DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
124 const Attr *Attr) override;
125 void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
126 void AddedAttributeToRecord(const Attr *Attr,
127 const RecordDecl *Record) override;
128 void EnteringModulePurview() override;
129 void AddedManglingNumber(const Decl *D, unsigned) override;
130 void AddedStaticLocalNumbers(const Decl *D, unsigned) override;
131 void AddedAnonymousNamespace(const TranslationUnitDecl *,
132 NamespaceDecl *AnonNamespace) override;
133
134private:
135 std::vector<ASTMutationListener*> Listeners;
136};
137
138MultiplexASTMutationListener::MultiplexASTMutationListener(
139 ArrayRef<ASTMutationListener*> L)
140 : Listeners(L.begin(), L.end()) {
141}
142
143void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) {
144 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
145 Listeners[i]->CompletedTagDefinition(D);
146}
147
148void MultiplexASTMutationListener::AddedVisibleDecl(
149 const DeclContext *DC, const Decl *D) {
150 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
151 Listeners[i]->AddedVisibleDecl(DC, D);
152}
153
154void MultiplexASTMutationListener::AddedCXXImplicitMember(
155 const CXXRecordDecl *RD, const Decl *D) {
156 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
157 Listeners[i]->AddedCXXImplicitMember(RD, D);
158}
159void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
160 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
161 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
162 Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
163}
164void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
165 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
166 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
167 Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
168}
169void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
170 const FunctionTemplateDecl *TD, const FunctionDecl *D) {
171 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
172 Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
173}
174void MultiplexASTMutationListener::ResolvedExceptionSpec(
175 const FunctionDecl *FD) {
176 for (auto &Listener : Listeners)
177 Listener->ResolvedExceptionSpec(FD);
178}
179void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD,
180 QualType ReturnType) {
181 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
182 Listeners[i]->DeducedReturnType(FD, ReturnType);
183}
184void MultiplexASTMutationListener::ResolvedOperatorDelete(
185 const CXXDestructorDecl *DD, const FunctionDecl *Delete, Expr *ThisArg) {
186 for (auto *L : Listeners)
187 L->ResolvedOperatorDelete(DD, Delete, ThisArg);
188}
189void MultiplexASTMutationListener::ResolvedOperatorGlobDelete(
190 const CXXDestructorDecl *DD, const FunctionDecl *GlobDelete) {
191 for (auto *L : Listeners)
192 L->ResolvedOperatorGlobDelete(DD, GlobDelete);
193}
194void MultiplexASTMutationListener::CompletedImplicitDefinition(
195 const FunctionDecl *D) {
196 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
197 Listeners[i]->CompletedImplicitDefinition(D);
198}
199void MultiplexASTMutationListener::InstantiationRequested(const ValueDecl *D) {
200 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
201 Listeners[i]->InstantiationRequested(D);
202}
203void MultiplexASTMutationListener::VariableDefinitionInstantiated(
204 const VarDecl *D) {
205 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
206 Listeners[i]->VariableDefinitionInstantiated(D);
207}
208void MultiplexASTMutationListener::FunctionDefinitionInstantiated(
209 const FunctionDecl *D) {
210 for (auto &Listener : Listeners)
211 Listener->FunctionDefinitionInstantiated(D);
212}
213void MultiplexASTMutationListener::DefaultArgumentInstantiated(
214 const ParmVarDecl *D) {
215 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
216 Listeners[i]->DefaultArgumentInstantiated(D);
217}
218void MultiplexASTMutationListener::DefaultMemberInitializerInstantiated(
219 const FieldDecl *D) {
220 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
221 Listeners[i]->DefaultMemberInitializerInstantiated(D);
222}
223void MultiplexASTMutationListener::AddedObjCCategoryToInterface(
224 const ObjCCategoryDecl *CatD,
225 const ObjCInterfaceDecl *IFD) {
226 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
227 Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD);
228}
229void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) {
230 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
231 Listeners[i]->DeclarationMarkedUsed(D);
232}
233void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate(
234 const Decl *D) {
235 for (size_t i = 0, e = Listeners.size(); i != e; ++i)
236 Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D);
237}
238void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate(
239 const Decl *D, const Attr *A) {
240 for (ASTMutationListener *L : Listeners)
241 L->DeclarationMarkedOpenMPAllocate(D, A);
242}
243void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget(
244 const Decl *D, const Attr *Attr) {
245 for (auto *L : Listeners)
246 L->DeclarationMarkedOpenMPDeclareTarget(D, Attr);
247}
248void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D,
249 Module *M) {
250 for (auto *L : Listeners)
251 L->RedefinedHiddenDefinition(D, M);
252}
253
254void MultiplexASTMutationListener::AddedAttributeToRecord(
255 const Attr *Attr,
256 const RecordDecl *Record) {
257 for (auto *L : Listeners)
258 L->AddedAttributeToRecord(Attr, Record);
259}
260
261void MultiplexASTMutationListener::EnteringModulePurview() {
262 for (auto *L : Listeners)
263 L->EnteringModulePurview();
264}
265
266void MultiplexASTMutationListener::AddedManglingNumber(const Decl *D,
267 unsigned Number) {
268 for (auto *L : Listeners)
269 L->AddedManglingNumber(D, Number);
270}
271void MultiplexASTMutationListener::AddedStaticLocalNumbers(const Decl *D,
272 unsigned Number) {
273 for (auto *L : Listeners)
274 L->AddedStaticLocalNumbers(D, Number);
275}
276void MultiplexASTMutationListener::AddedAnonymousNamespace(
277 const TranslationUnitDecl *TU, NamespaceDecl *AnonNamespace) {
278 for (auto *L : Listeners)
279 L->AddedAnonymousNamespace(TU, AnonNamespace);
280}
281
282} // end namespace clang
283
284MultiplexConsumer::MultiplexConsumer(
285 std::vector<std::unique_ptr<ASTConsumer>> C)
286 : Consumers(std::move(C)) {
287 // Collect the mutation listeners and deserialization listeners of all
288 // children, and create a multiplex listener each if so.
289 std::vector<ASTMutationListener *> mutationListeners;
290 std::vector<ASTDeserializationListener*> serializationListeners;
291 for (auto &Consumer : Consumers) {
292 if (auto *mutationListener = Consumer->GetASTMutationListener())
293 mutationListeners.push_back(x: mutationListener);
294 if (auto *serializationListener = Consumer->GetASTDeserializationListener())
295 serializationListeners.push_back(x: serializationListener);
296 }
297 if (!mutationListeners.empty()) {
298 MutationListener =
299 std::make_unique<MultiplexASTMutationListener>(args&: mutationListeners);
300 }
301 if (!serializationListeners.empty()) {
302 DeserializationListener =
303 std::make_unique<MultiplexASTDeserializationListener>(
304 args&: serializationListeners);
305 }
306}
307
308MultiplexConsumer::MultiplexConsumer(std::unique_ptr<ASTConsumer> C)
309 : MultiplexConsumer([](std::unique_ptr<ASTConsumer> Consumer) {
310 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
311 Consumers.push_back(x: std::move(Consumer));
312 return Consumers;
313 }(std::move(C))) {}
314
315MultiplexConsumer::~MultiplexConsumer() {}
316
317void MultiplexConsumer::Initialize(ASTContext &Context) {
318 for (auto &Consumer : Consumers)
319 Consumer->Initialize(Context);
320}
321
322bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
323 bool Continue = true;
324 for (auto &Consumer : Consumers)
325 Continue = Continue && Consumer->HandleTopLevelDecl(D);
326 return Continue;
327}
328
329void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) {
330 for (auto &Consumer : Consumers)
331 Consumer->HandleInlineFunctionDefinition(D);
332}
333
334void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
335 for (auto &Consumer : Consumers)
336 Consumer->HandleCXXStaticMemberVarInstantiation(D: VD);
337}
338
339void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
340 for (auto &Consumer : Consumers)
341 Consumer->HandleInterestingDecl(D);
342}
343
344void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) {
345 for (auto &Consumer : Consumers)
346 Consumer->HandleTranslationUnit(Ctx);
347}
348
349void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
350 for (auto &Consumer : Consumers)
351 Consumer->HandleTagDeclDefinition(D);
352}
353
354void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) {
355 for (auto &Consumer : Consumers)
356 Consumer->HandleTagDeclRequiredDefinition(D);
357}
358
359void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){
360 for (auto &Consumer : Consumers)
361 Consumer->HandleCXXImplicitFunctionInstantiation(D);
362}
363
364void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
365 for (auto &Consumer : Consumers)
366 Consumer->HandleTopLevelDeclInObjCContainer(D);
367}
368
369void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) {
370 for (auto &Consumer : Consumers)
371 Consumer->HandleImplicitImportDecl(D);
372}
373
374void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
375 for (auto &Consumer : Consumers)
376 Consumer->CompleteTentativeDefinition(D);
377}
378
379void MultiplexConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) {
380 for (auto &Consumer : Consumers)
381 Consumer->CompleteExternalDeclaration(D);
382}
383
384void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) {
385 for (auto &Consumer : Consumers)
386 Consumer->AssignInheritanceModel(RD);
387}
388
389void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) {
390 for (auto &Consumer : Consumers)
391 Consumer->HandleVTable(RD);
392}
393
394ASTMutationListener *MultiplexConsumer::GetASTMutationListener() {
395 return MutationListener.get();
396}
397
398ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() {
399 return DeserializationListener.get();
400}
401
402void MultiplexConsumer::PrintStats() {
403 for (auto &Consumer : Consumers)
404 Consumer->PrintStats();
405}
406
407bool MultiplexConsumer::shouldSkipFunctionBody(Decl *D) {
408 bool Skip = true;
409 for (auto &Consumer : Consumers)
410 Skip = Skip && Consumer->shouldSkipFunctionBody(D);
411 return Skip;
412}
413
414void MultiplexConsumer::InitializeSema(Sema &S) {
415 for (auto &Consumer : Consumers)
416 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Val: Consumer.get()))
417 SC->InitializeSema(S);
418}
419
420void MultiplexConsumer::ForgetSema() {
421 for (auto &Consumer : Consumers)
422 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Val: Consumer.get()))
423 SC->ForgetSema();
424}
425