1 //===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the MultiplexConsumer class. It also declares and defines
10 // MultiplexASTDeserializationListener and MultiplexASTMutationListener, which
11 // are implementation details of MultiplexConsumer.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Frontend/MultiplexConsumer.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/DeclGroup.h"
19 using namespace clang
;
23 MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
24 const std::vector
<ASTDeserializationListener
*>& L
)
28 void MultiplexASTDeserializationListener::ReaderInitialized(
30 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
31 Listeners
[i
]->ReaderInitialized(Reader
);
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
);
40 void MultiplexASTDeserializationListener::MacroRead(
41 serialization::MacroID ID
, MacroInfo
*MI
) {
42 for (auto &Listener
: Listeners
)
43 Listener
->MacroRead(ID
, MI
);
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
);
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
);
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
);
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
);
70 void MultiplexASTDeserializationListener::ModuleRead(
71 serialization::SubmoduleID ID
, Module
*Mod
) {
72 for (auto &Listener
: Listeners
)
73 Listener
->ModuleRead(ID
, Mod
);
76 void MultiplexASTDeserializationListener::ModuleImportRead(
77 serialization::SubmoduleID ID
, SourceLocation ImportLoc
) {
78 for (auto &Listener
: Listeners
)
79 Listener
->ModuleImportRead(ID
, ImportLoc
);
82 // This ASTMutationListener forwards its notifications to a set of
84 class MultiplexASTMutationListener
: public ASTMutationListener
{
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
;
120 std::vector
<ASTMutationListener
*> Listeners
;
123 MultiplexASTMutationListener::MultiplexASTMutationListener(
124 ArrayRef
<ASTMutationListener
*> L
)
125 : Listeners(L
.begin(), L
.end()) {
128 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl
*D
) {
129 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
130 Listeners
[i
]->CompletedTagDefinition(D
);
133 void 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
);
139 void 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
);
144 void 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
);
149 void 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
);
154 void 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
);
159 void MultiplexASTMutationListener::ResolvedExceptionSpec(
160 const FunctionDecl
*FD
) {
161 for (auto &Listener
: Listeners
)
162 Listener
->ResolvedExceptionSpec(FD
);
164 void 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
);
169 void MultiplexASTMutationListener::ResolvedOperatorDelete(
170 const CXXDestructorDecl
*DD
, const FunctionDecl
*Delete
, Expr
*ThisArg
) {
171 for (auto *L
: Listeners
)
172 L
->ResolvedOperatorDelete(DD
, Delete
, ThisArg
);
174 void MultiplexASTMutationListener::CompletedImplicitDefinition(
175 const FunctionDecl
*D
) {
176 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
177 Listeners
[i
]->CompletedImplicitDefinition(D
);
179 void MultiplexASTMutationListener::InstantiationRequested(const ValueDecl
*D
) {
180 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
181 Listeners
[i
]->InstantiationRequested(D
);
183 void MultiplexASTMutationListener::VariableDefinitionInstantiated(
185 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
186 Listeners
[i
]->VariableDefinitionInstantiated(D
);
188 void MultiplexASTMutationListener::FunctionDefinitionInstantiated(
189 const FunctionDecl
*D
) {
190 for (auto &Listener
: Listeners
)
191 Listener
->FunctionDefinitionInstantiated(D
);
193 void MultiplexASTMutationListener::DefaultArgumentInstantiated(
194 const ParmVarDecl
*D
) {
195 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
196 Listeners
[i
]->DefaultArgumentInstantiated(D
);
198 void MultiplexASTMutationListener::DefaultMemberInitializerInstantiated(
199 const FieldDecl
*D
) {
200 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
201 Listeners
[i
]->DefaultMemberInitializerInstantiated(D
);
203 void 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
);
209 void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl
*D
) {
210 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
211 Listeners
[i
]->DeclarationMarkedUsed(D
);
213 void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate(
215 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
216 Listeners
[i
]->DeclarationMarkedOpenMPThreadPrivate(D
);
218 void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate(
219 const Decl
*D
, const Attr
*A
) {
220 for (ASTMutationListener
*L
: Listeners
)
221 L
->DeclarationMarkedOpenMPAllocate(D
, A
);
223 void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget(
224 const Decl
*D
, const Attr
*Attr
) {
225 for (auto *L
: Listeners
)
226 L
->DeclarationMarkedOpenMPDeclareTarget(D
, Attr
);
228 void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl
*D
,
230 for (auto *L
: Listeners
)
231 L
->RedefinedHiddenDefinition(D
, M
);
234 void MultiplexASTMutationListener::AddedAttributeToRecord(
236 const RecordDecl
*Record
) {
237 for (auto *L
: Listeners
)
238 L
->AddedAttributeToRecord(Attr
, Record
);
241 } // end namespace clang
243 MultiplexConsumer::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
);
256 if (!mutationListeners
.empty()) {
258 std::make_unique
<MultiplexASTMutationListener
>(mutationListeners
);
260 if (!serializationListeners
.empty()) {
261 DeserializationListener
=
262 std::make_unique
<MultiplexASTDeserializationListener
>(
263 serializationListeners
);
267 MultiplexConsumer::~MultiplexConsumer() {}
269 void MultiplexConsumer::Initialize(ASTContext
&Context
) {
270 for (auto &Consumer
: Consumers
)
271 Consumer
->Initialize(Context
);
274 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D
) {
275 bool Continue
= true;
276 for (auto &Consumer
: Consumers
)
277 Continue
= Continue
&& Consumer
->HandleTopLevelDecl(D
);
281 void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl
*D
) {
282 for (auto &Consumer
: Consumers
)
283 Consumer
->HandleInlineFunctionDefinition(D
);
286 void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl
*VD
) {
287 for (auto &Consumer
: Consumers
)
288 Consumer
->HandleCXXStaticMemberVarInstantiation(VD
);
291 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D
) {
292 for (auto &Consumer
: Consumers
)
293 Consumer
->HandleInterestingDecl(D
);
296 void MultiplexConsumer::HandleTranslationUnit(ASTContext
&Ctx
) {
297 for (auto &Consumer
: Consumers
)
298 Consumer
->HandleTranslationUnit(Ctx
);
301 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl
*D
) {
302 for (auto &Consumer
: Consumers
)
303 Consumer
->HandleTagDeclDefinition(D
);
306 void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl
*D
) {
307 for (auto &Consumer
: Consumers
)
308 Consumer
->HandleTagDeclRequiredDefinition(D
);
311 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl
*D
){
312 for (auto &Consumer
: Consumers
)
313 Consumer
->HandleCXXImplicitFunctionInstantiation(D
);
316 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D
) {
317 for (auto &Consumer
: Consumers
)
318 Consumer
->HandleTopLevelDeclInObjCContainer(D
);
321 void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl
*D
) {
322 for (auto &Consumer
: Consumers
)
323 Consumer
->HandleImplicitImportDecl(D
);
326 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl
*D
) {
327 for (auto &Consumer
: Consumers
)
328 Consumer
->CompleteTentativeDefinition(D
);
331 void MultiplexConsumer::CompleteExternalDeclaration(VarDecl
*D
) {
332 for (auto &Consumer
: Consumers
)
333 Consumer
->CompleteExternalDeclaration(D
);
336 void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl
*RD
) {
337 for (auto &Consumer
: Consumers
)
338 Consumer
->AssignInheritanceModel(RD
);
341 void MultiplexConsumer::HandleVTable(CXXRecordDecl
*RD
) {
342 for (auto &Consumer
: Consumers
)
343 Consumer
->HandleVTable(RD
);
346 ASTMutationListener
*MultiplexConsumer::GetASTMutationListener() {
347 return MutationListener
.get();
350 ASTDeserializationListener
*MultiplexConsumer::GetASTDeserializationListener() {
351 return DeserializationListener
.get();
354 void MultiplexConsumer::PrintStats() {
355 for (auto &Consumer
: Consumers
)
356 Consumer
->PrintStats();
359 bool MultiplexConsumer::shouldSkipFunctionBody(Decl
*D
) {
361 for (auto &Consumer
: Consumers
)
362 Skip
= Skip
&& Consumer
->shouldSkipFunctionBody(D
);
366 void MultiplexConsumer::InitializeSema(Sema
&S
) {
367 for (auto &Consumer
: Consumers
)
368 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumer
.get()))
369 SC
->InitializeSema(S
);
372 void MultiplexConsumer::ForgetSema() {
373 for (auto &Consumer
: Consumers
)
374 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumer
.get()))