/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 4.99k | : Listeners(L) { |
26 | 4.99k | } |
27 | | |
28 | | void MultiplexASTDeserializationListener::ReaderInitialized( |
29 | 3.42k | ASTReader *Reader) { |
30 | 6.85k | for (size_t i = 0, e = Listeners.size(); i != e; ++i3.42k ) |
31 | 3.42k | Listeners[i]->ReaderInitialized(Reader); |
32 | 3.42k | } |
33 | | |
34 | | void MultiplexASTDeserializationListener::IdentifierRead( |
35 | 1.62M | serialization::IdentID ID, IdentifierInfo *II) { |
36 | 3.24M | for (size_t i = 0, e = Listeners.size(); i != e; ++i1.62M ) |
37 | 1.62M | Listeners[i]->IdentifierRead(ID, II); |
38 | 1.62M | } |
39 | | |
40 | | void MultiplexASTDeserializationListener::MacroRead( |
41 | 15.9k | serialization::MacroID ID, MacroInfo *MI) { |
42 | 15.9k | for (auto &Listener : Listeners) |
43 | 15.9k | Listener->MacroRead(ID, MI); |
44 | 15.9k | } |
45 | | |
46 | | void MultiplexASTDeserializationListener::TypeRead( |
47 | 79.7k | serialization::TypeIdx Idx, QualType T) { |
48 | 159k | for (size_t i = 0, e = Listeners.size(); i != e; ++i79.7k ) |
49 | 79.7k | Listeners[i]->TypeRead(Idx, T); |
50 | 79.7k | } |
51 | | |
52 | | void MultiplexASTDeserializationListener::DeclRead( |
53 | 270k | serialization::DeclID ID, const Decl *D) { |
54 | 540k | for (size_t i = 0, e = Listeners.size(); i != e; ++i270k ) |
55 | 270k | Listeners[i]->DeclRead(ID, D); |
56 | 270k | } |
57 | | |
58 | | void MultiplexASTDeserializationListener::SelectorRead( |
59 | 2.34k | serialization::SelectorID ID, Selector Sel) { |
60 | 4.69k | for (size_t i = 0, e = Listeners.size(); i != e; ++i2.34k ) |
61 | 2.34k | Listeners[i]->SelectorRead(ID, Sel); |
62 | 2.34k | } |
63 | | |
64 | | void MultiplexASTDeserializationListener::MacroDefinitionRead( |
65 | 16 | serialization::PreprocessedEntityID ID, MacroDefinitionRecord *MD) { |
66 | 32 | for (size_t i = 0, e = Listeners.size(); i != e; ++i16 ) |
67 | 16 | Listeners[i]->MacroDefinitionRead(ID, MD); |
68 | 16 | } |
69 | | |
70 | | void MultiplexASTDeserializationListener::ModuleRead( |
71 | 115k | serialization::SubmoduleID ID, Module *Mod) { |
72 | 115k | for (auto &Listener : Listeners) |
73 | 115k | Listener->ModuleRead(ID, Mod); |
74 | 115k | } |
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 DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override; |
107 | | void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, |
108 | | const Attr *Attr) override; |
109 | | void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; |
110 | | void AddedAttributeToRecord(const Attr *Attr, |
111 | | const RecordDecl *Record) override; |
112 | | |
113 | | private: |
114 | | std::vector<ASTMutationListener*> Listeners; |
115 | | }; |
116 | | |
117 | | MultiplexASTMutationListener::MultiplexASTMutationListener( |
118 | | ArrayRef<ASTMutationListener*> L) |
119 | 4.99k | : Listeners(L.begin(), L.end()) { |
120 | 4.99k | } |
121 | | |
122 | 156k | void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { |
123 | 312k | for (size_t i = 0, e = Listeners.size(); i != e; ++i156k ) |
124 | 156k | Listeners[i]->CompletedTagDefinition(D); |
125 | 156k | } |
126 | | |
127 | | void MultiplexASTMutationListener::AddedVisibleDecl( |
128 | 912k | const DeclContext *DC, const Decl *D) { |
129 | 1.82M | for (size_t i = 0, e = Listeners.size(); i != e; ++i912k ) |
130 | 912k | Listeners[i]->AddedVisibleDecl(DC, D); |
131 | 912k | } |
132 | | |
133 | | void MultiplexASTMutationListener::AddedCXXImplicitMember( |
134 | 16.7k | const CXXRecordDecl *RD, const Decl *D) { |
135 | 33.5k | for (size_t i = 0, e = Listeners.size(); i != e; ++i16.7k ) |
136 | 16.7k | Listeners[i]->AddedCXXImplicitMember(RD, D); |
137 | 16.7k | } |
138 | | void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( |
139 | 45.1k | const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) { |
140 | 90.3k | for (size_t i = 0, e = Listeners.size(); i != e; ++i45.1k ) |
141 | 45.1k | Listeners[i]->AddedCXXTemplateSpecialization(TD, D); |
142 | 45.1k | } |
143 | | void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( |
144 | 145 | const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { |
145 | 290 | for (size_t i = 0, e = Listeners.size(); i != e; ++i145 ) |
146 | 145 | Listeners[i]->AddedCXXTemplateSpecialization(TD, D); |
147 | 145 | } |
148 | | void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( |
149 | 10.1k | const FunctionTemplateDecl *TD, const FunctionDecl *D) { |
150 | 20.2k | for (size_t i = 0, e = Listeners.size(); i != e; ++i10.1k ) |
151 | 10.1k | Listeners[i]->AddedCXXTemplateSpecialization(TD, D); |
152 | 10.1k | } |
153 | | void MultiplexASTMutationListener::ResolvedExceptionSpec( |
154 | 33.7k | const FunctionDecl *FD) { |
155 | 33.7k | for (auto &Listener : Listeners) |
156 | 33.7k | Listener->ResolvedExceptionSpec(FD); |
157 | 33.7k | } |
158 | | void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, |
159 | 61 | QualType ReturnType) { |
160 | 122 | for (size_t i = 0, e = Listeners.size(); i != e; ++i61 ) |
161 | 61 | Listeners[i]->DeducedReturnType(FD, ReturnType); |
162 | 61 | } |
163 | | void MultiplexASTMutationListener::ResolvedOperatorDelete( |
164 | 51 | const CXXDestructorDecl *DD, const FunctionDecl *Delete, Expr *ThisArg) { |
165 | 51 | for (auto *L : Listeners) |
166 | 51 | L->ResolvedOperatorDelete(DD, Delete, ThisArg); |
167 | 51 | } |
168 | | void MultiplexASTMutationListener::CompletedImplicitDefinition( |
169 | 3.78k | const FunctionDecl *D) { |
170 | 7.56k | for (size_t i = 0, e = Listeners.size(); i != e; ++i3.78k ) |
171 | 3.78k | Listeners[i]->CompletedImplicitDefinition(D); |
172 | 3.78k | } |
173 | 10.1k | void MultiplexASTMutationListener::InstantiationRequested(const ValueDecl *D) { |
174 | 20.3k | for (size_t i = 0, e = Listeners.size(); i != e; ++i10.1k ) |
175 | 10.1k | Listeners[i]->InstantiationRequested(D); |
176 | 10.1k | } |
177 | | void MultiplexASTMutationListener::VariableDefinitionInstantiated( |
178 | 11.2k | const VarDecl *D) { |
179 | 22.4k | for (size_t i = 0, e = Listeners.size(); i != e; ++i11.2k ) |
180 | 11.2k | Listeners[i]->VariableDefinitionInstantiated(D); |
181 | 11.2k | } |
182 | | void MultiplexASTMutationListener::FunctionDefinitionInstantiated( |
183 | 7.54k | const FunctionDecl *D) { |
184 | 7.54k | for (auto &Listener : Listeners) |
185 | 7.54k | Listener->FunctionDefinitionInstantiated(D); |
186 | 7.54k | } |
187 | | void MultiplexASTMutationListener::DefaultArgumentInstantiated( |
188 | 494 | const ParmVarDecl *D) { |
189 | 988 | for (size_t i = 0, e = Listeners.size(); i != e; ++i494 ) |
190 | 494 | Listeners[i]->DefaultArgumentInstantiated(D); |
191 | 494 | } |
192 | | void MultiplexASTMutationListener::DefaultMemberInitializerInstantiated( |
193 | 2 | const FieldDecl *D) { |
194 | 4 | for (size_t i = 0, e = Listeners.size(); i != e; ++i2 ) |
195 | 2 | Listeners[i]->DefaultMemberInitializerInstantiated(D); |
196 | 2 | } |
197 | | void MultiplexASTMutationListener::AddedObjCCategoryToInterface( |
198 | | const ObjCCategoryDecl *CatD, |
199 | 1.46k | const ObjCInterfaceDecl *IFD) { |
200 | 2.93k | for (size_t i = 0, e = Listeners.size(); i != e; ++i1.46k ) |
201 | 1.46k | Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); |
202 | 1.46k | } |
203 | 327k | void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { |
204 | 654k | for (size_t i = 0, e = Listeners.size(); i != e; ++i327k ) |
205 | 327k | Listeners[i]->DeclarationMarkedUsed(D); |
206 | 327k | } |
207 | | void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( |
208 | 205 | const Decl *D) { |
209 | 410 | for (size_t i = 0, e = Listeners.size(); i != e; ++i205 ) |
210 | 205 | Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); |
211 | 205 | } |
212 | | void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate( |
213 | 180 | const Decl *D, const Attr *A) { |
214 | 180 | for (ASTMutationListener *L : Listeners) |
215 | 180 | L->DeclarationMarkedOpenMPAllocate(D, A); |
216 | 180 | } |
217 | | void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( |
218 | 1.12k | const Decl *D, const Attr *Attr) { |
219 | 1.12k | for (auto *L : Listeners) |
220 | 1.12k | L->DeclarationMarkedOpenMPDeclareTarget(D, Attr); |
221 | 1.12k | } |
222 | | void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D, |
223 | 2.56k | Module *M) { |
224 | 2.56k | for (auto *L : Listeners) |
225 | 2.56k | L->RedefinedHiddenDefinition(D, M); |
226 | 2.56k | } |
227 | | |
228 | | void MultiplexASTMutationListener::AddedAttributeToRecord( |
229 | | const Attr *Attr, |
230 | 30 | const RecordDecl *Record) { |
231 | 30 | for (auto *L : Listeners) |
232 | 30 | L->AddedAttributeToRecord(Attr, Record); |
233 | 30 | } |
234 | | |
235 | | } // end namespace clang |
236 | | |
237 | | MultiplexConsumer::MultiplexConsumer( |
238 | | std::vector<std::unique_ptr<ASTConsumer>> C) |
239 | 5.27k | : Consumers(std::move(C)), MutationListener(), DeserializationListener() { |
240 | | // Collect the mutation listeners and deserialization listeners of all |
241 | | // children, and create a multiplex listener each if so. |
242 | 5.27k | std::vector<ASTMutationListener*> mutationListeners; |
243 | 5.27k | std::vector<ASTDeserializationListener*> serializationListeners; |
244 | 10.4k | for (auto &Consumer : Consumers) { |
245 | 10.4k | if (auto *mutationListener = Consumer->GetASTMutationListener()) |
246 | 4.99k | mutationListeners.push_back(mutationListener); |
247 | 10.4k | if (auto *serializationListener = Consumer->GetASTDeserializationListener()) |
248 | 4.99k | serializationListeners.push_back(serializationListener); |
249 | 10.4k | } |
250 | 5.27k | if (!mutationListeners.empty()) { |
251 | 4.99k | MutationListener = |
252 | 4.99k | std::make_unique<MultiplexASTMutationListener>(mutationListeners); |
253 | 4.99k | } |
254 | 5.27k | if (!serializationListeners.empty()) { |
255 | 4.99k | DeserializationListener = |
256 | 4.99k | std::make_unique<MultiplexASTDeserializationListener>( |
257 | 4.99k | serializationListeners); |
258 | 4.99k | } |
259 | 5.27k | } |
260 | | |
261 | 5.27k | MultiplexConsumer::~MultiplexConsumer() {} |
262 | | |
263 | 5.27k | void MultiplexConsumer::Initialize(ASTContext &Context) { |
264 | 5.27k | for (auto &Consumer : Consumers) |
265 | 10.4k | Consumer->Initialize(Context); |
266 | 5.27k | } |
267 | | |
268 | 298k | bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { |
269 | 298k | bool Continue = true; |
270 | 298k | for (auto &Consumer : Consumers) |
271 | 597k | Continue = Continue && Consumer->HandleTopLevelDecl(D); |
272 | 298k | return Continue; |
273 | 298k | } |
274 | | |
275 | 45.3k | void MultiplexConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { |
276 | 45.3k | for (auto &Consumer : Consumers) |
277 | 90.6k | Consumer->HandleInlineFunctionDefinition(D); |
278 | 45.3k | } |
279 | | |
280 | 31.4k | void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { |
281 | 31.4k | for (auto &Consumer : Consumers) |
282 | 62.9k | Consumer->HandleCXXStaticMemberVarInstantiation(VD); |
283 | 31.4k | } |
284 | | |
285 | 3.64k | void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { |
286 | 3.64k | for (auto &Consumer : Consumers) |
287 | 7.29k | Consumer->HandleInterestingDecl(D); |
288 | 3.64k | } |
289 | | |
290 | 5.26k | void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { |
291 | 5.26k | for (auto &Consumer : Consumers) |
292 | 10.4k | Consumer->HandleTranslationUnit(Ctx); |
293 | 5.26k | } |
294 | | |
295 | 116k | void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { |
296 | 116k | for (auto &Consumer : Consumers) |
297 | 232k | Consumer->HandleTagDeclDefinition(D); |
298 | 116k | } |
299 | | |
300 | 60.0k | void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { |
301 | 60.0k | for (auto &Consumer : Consumers) |
302 | 120k | Consumer->HandleTagDeclRequiredDefinition(D); |
303 | 60.0k | } |
304 | | |
305 | 8.94k | void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ |
306 | 8.94k | for (auto &Consumer : Consumers) |
307 | 17.8k | Consumer->HandleCXXImplicitFunctionInstantiation(D); |
308 | 8.94k | } |
309 | | |
310 | 1.34k | void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { |
311 | 1.34k | for (auto &Consumer : Consumers) |
312 | 2.69k | Consumer->HandleTopLevelDeclInObjCContainer(D); |
313 | 1.34k | } |
314 | | |
315 | 75.9k | void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { |
316 | 75.9k | for (auto &Consumer : Consumers) |
317 | 151k | Consumer->HandleImplicitImportDecl(D); |
318 | 75.9k | } |
319 | | |
320 | 514 | void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { |
321 | 514 | for (auto &Consumer : Consumers) |
322 | 1.02k | Consumer->CompleteTentativeDefinition(D); |
323 | 514 | } |
324 | | |
325 | 0 | void MultiplexConsumer::CompleteExternalDeclaration(VarDecl *D) { |
326 | 0 | for (auto &Consumer : Consumers) |
327 | 0 | Consumer->CompleteExternalDeclaration(D); |
328 | 0 | } |
329 | | |
330 | 3 | void MultiplexConsumer::AssignInheritanceModel(CXXRecordDecl *RD) { |
331 | 3 | for (auto &Consumer : Consumers) |
332 | 6 | Consumer->AssignInheritanceModel(RD); |
333 | 3 | } |
334 | | |
335 | 3 | void MultiplexConsumer::HandleVTable(CXXRecordDecl *RD) { |
336 | 3 | for (auto &Consumer : Consumers) |
337 | 6 | Consumer->HandleVTable(RD); |
338 | 3 | } |
339 | | |
340 | 50.7k | ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { |
341 | 50.7k | return MutationListener.get(); |
342 | 50.7k | } |
343 | | |
344 | 2.00k | ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { |
345 | 2.00k | return DeserializationListener.get(); |
346 | 2.00k | } |
347 | | |
348 | 0 | void MultiplexConsumer::PrintStats() { |
349 | 0 | for (auto &Consumer : Consumers) |
350 | 0 | Consumer->PrintStats(); |
351 | 0 | } |
352 | | |
353 | 32 | bool MultiplexConsumer::shouldSkipFunctionBody(Decl *D) { |
354 | 32 | bool Skip = true; |
355 | 32 | for (auto &Consumer : Consumers) |
356 | 64 | Skip = Skip && Consumer->shouldSkipFunctionBody(D); |
357 | 32 | return Skip; |
358 | 32 | } |
359 | | |
360 | 5.26k | void MultiplexConsumer::InitializeSema(Sema &S) { |
361 | 5.26k | for (auto &Consumer : Consumers) |
362 | 10.4k | if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) |
363 | 4.99k | SC->InitializeSema(S); |
364 | 5.26k | } |
365 | | |
366 | 5.23k | void MultiplexConsumer::ForgetSema() { |
367 | 5.23k | for (auto &Consumer : Consumers) |
368 | 10.3k | if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) |
369 | 4.96k | SC->ForgetSema(); |
370 | 5.23k | } |