1//===--- MultiplexExternalSemaSource.cpp ---------------------------------===//
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 implements the event dispatching to the subscribed clients.
10//
11//===----------------------------------------------------------------------===//
12#include "clang/Sema/MultiplexExternalSemaSource.h"
13#include "clang/Sema/Lookup.h"
14
15using namespace clang;
16
17char MultiplexExternalSemaSource::ID;
18
19/// Constructs a new multiplexing external sema source and appends the
20/// given element to it.
21///
22MultiplexExternalSemaSource::MultiplexExternalSemaSource(
23 llvm::IntrusiveRefCntPtr<ExternalSemaSource> S1,
24 llvm::IntrusiveRefCntPtr<ExternalSemaSource> S2) {
25 Sources.push_back(Elt: std::move(S1));
26 Sources.push_back(Elt: std::move(S2));
27}
28
29/// Appends new source to the source list.
30///
31///\param[in] source - An ExternalSemaSource.
32///
33void MultiplexExternalSemaSource::AddSource(
34 llvm::IntrusiveRefCntPtr<ExternalSemaSource> Source) {
35 Sources.push_back(Elt: std::move(Source));
36}
37
38//===----------------------------------------------------------------------===//
39// ExternalASTSource.
40//===----------------------------------------------------------------------===//
41
42Decl *MultiplexExternalSemaSource::GetExternalDecl(GlobalDeclID ID) {
43 for(size_t i = 0; i < Sources.size(); ++i)
44 if (Decl *Result = Sources[i]->GetExternalDecl(ID))
45 return Result;
46 return nullptr;
47}
48
49void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
50 for (size_t i = 0; i < Sources.size(); ++i)
51 Sources[i]->CompleteRedeclChain(D);
52}
53
54Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
55 Selector Sel;
56 for(size_t i = 0; i < Sources.size(); ++i) {
57 Sel = Sources[i]->GetExternalSelector(ID);
58 if (!Sel.isNull())
59 return Sel;
60 }
61 return Sel;
62}
63
64uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() {
65 uint32_t total = 0;
66 for(size_t i = 0; i < Sources.size(); ++i)
67 total += Sources[i]->GetNumExternalSelectors();
68 return total;
69}
70
71Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) {
72 for(size_t i = 0; i < Sources.size(); ++i)
73 if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
74 return Result;
75 return nullptr;
76}
77
78CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers(
79 uint64_t Offset){
80 for(size_t i = 0; i < Sources.size(); ++i)
81 if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
82 return R;
83 return nullptr;
84}
85
86CXXCtorInitializer **
87MultiplexExternalSemaSource::GetExternalCXXCtorInitializers(uint64_t Offset) {
88 for (auto &S : Sources)
89 if (auto *R = S->GetExternalCXXCtorInitializers(Offset))
90 return R;
91 return nullptr;
92}
93
94ExternalASTSource::ExtKind
95MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) {
96 for (const auto &S : Sources)
97 if (auto EK = S->hasExternalDefinitions(D))
98 if (EK != EK_ReplyHazy)
99 return EK;
100 return EK_ReplyHazy;
101}
102
103bool MultiplexExternalSemaSource::wasThisDeclarationADefinition(
104 const FunctionDecl *FD) {
105 for (const auto &S : Sources)
106 if (S->wasThisDeclarationADefinition(FD))
107 return true;
108 return false;
109}
110
111bool MultiplexExternalSemaSource::FindExternalVisibleDeclsByName(
112 const DeclContext *DC, DeclarationName Name,
113 const DeclContext *OriginalDC) {
114 bool AnyDeclsFound = false;
115 for (size_t i = 0; i < Sources.size(); ++i)
116 AnyDeclsFound |=
117 Sources[i]->FindExternalVisibleDeclsByName(DC, Name, OriginalDC);
118 return AnyDeclsFound;
119}
120
121bool MultiplexExternalSemaSource::LoadExternalSpecializations(
122 const Decl *D, bool OnlyPartial) {
123 bool Loaded = false;
124 for (size_t i = 0; i < Sources.size(); ++i)
125 Loaded |= Sources[i]->LoadExternalSpecializations(D, OnlyPartial);
126 return Loaded;
127}
128
129bool MultiplexExternalSemaSource::LoadExternalSpecializations(
130 const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
131 bool AnyNewSpecsLoaded = false;
132 for (size_t i = 0; i < Sources.size(); ++i)
133 AnyNewSpecsLoaded |=
134 Sources[i]->LoadExternalSpecializations(D, TemplateArgs);
135 return AnyNewSpecsLoaded;
136}
137
138void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
139 for(size_t i = 0; i < Sources.size(); ++i)
140 Sources[i]->completeVisibleDeclsMap(DC);
141}
142
143void MultiplexExternalSemaSource::FindExternalLexicalDecls(
144 const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
145 SmallVectorImpl<Decl *> &Result) {
146 for(size_t i = 0; i < Sources.size(); ++i)
147 Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
148}
149
150void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File,
151 unsigned Offset,
152 unsigned Length,
153 SmallVectorImpl<Decl *> &Decls){
154 for(size_t i = 0; i < Sources.size(); ++i)
155 Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
156}
157
158void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) {
159 for(size_t i = 0; i < Sources.size(); ++i)
160 Sources[i]->CompleteType(Tag);
161}
162
163void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) {
164 for(size_t i = 0; i < Sources.size(); ++i)
165 Sources[i]->CompleteType(Class);
166}
167
168void MultiplexExternalSemaSource::ReadComments() {
169 for(size_t i = 0; i < Sources.size(); ++i)
170 Sources[i]->ReadComments();
171}
172
173void MultiplexExternalSemaSource::StartedDeserializing() {
174 for(size_t i = 0; i < Sources.size(); ++i)
175 Sources[i]->StartedDeserializing();
176}
177
178void MultiplexExternalSemaSource::FinishedDeserializing() {
179 for(size_t i = 0; i < Sources.size(); ++i)
180 Sources[i]->FinishedDeserializing();
181}
182
183void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) {
184 for(size_t i = 0; i < Sources.size(); ++i)
185 Sources[i]->StartTranslationUnit(Consumer);
186}
187
188void MultiplexExternalSemaSource::PrintStats() {
189 for(size_t i = 0; i < Sources.size(); ++i)
190 Sources[i]->PrintStats();
191}
192
193Module *MultiplexExternalSemaSource::getModule(unsigned ID) {
194 for (size_t i = 0; i < Sources.size(); ++i)
195 if (auto M = Sources[i]->getModule(ID))
196 return M;
197 return nullptr;
198}
199
200bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record,
201 uint64_t &Size,
202 uint64_t &Alignment,
203 llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
204 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
205 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){
206 for(size_t i = 0; i < Sources.size(); ++i)
207 if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
208 BaseOffsets, VirtualBaseOffsets))
209 return true;
210 return false;
211}
212
213void MultiplexExternalSemaSource::
214getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
215 for(size_t i = 0; i < Sources.size(); ++i)
216 Sources[i]->getMemoryBufferSizes(sizes);
217
218}
219
220//===----------------------------------------------------------------------===//
221// ExternalSemaSource.
222//===----------------------------------------------------------------------===//
223
224
225void MultiplexExternalSemaSource::InitializeSema(Sema &S) {
226 for(size_t i = 0; i < Sources.size(); ++i)
227 Sources[i]->InitializeSema(S);
228}
229
230void MultiplexExternalSemaSource::ForgetSema() {
231 for(size_t i = 0; i < Sources.size(); ++i)
232 Sources[i]->ForgetSema();
233}
234
235void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
236 for(size_t i = 0; i < Sources.size(); ++i)
237 Sources[i]->ReadMethodPool(Sel);
238}
239
240void MultiplexExternalSemaSource::updateOutOfDateSelector(Selector Sel) {
241 for(size_t i = 0; i < Sources.size(); ++i)
242 Sources[i]->updateOutOfDateSelector(Sel);
243}
244
245void MultiplexExternalSemaSource::ReadKnownNamespaces(
246 SmallVectorImpl<NamespaceDecl*> &Namespaces){
247 for(size_t i = 0; i < Sources.size(); ++i)
248 Sources[i]->ReadKnownNamespaces(Namespaces);
249}
250
251void MultiplexExternalSemaSource::ReadUndefinedButUsed(
252 llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
253 for(size_t i = 0; i < Sources.size(); ++i)
254 Sources[i]->ReadUndefinedButUsed(Undefined);
255}
256
257void MultiplexExternalSemaSource::ReadMismatchingDeleteExpressions(
258 llvm::MapVector<FieldDecl *,
259 llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
260 Exprs) {
261 for (auto &Source : Sources)
262 Source->ReadMismatchingDeleteExpressions(Exprs);
263}
264
265bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
266 for(size_t i = 0; i < Sources.size(); ++i)
267 Sources[i]->LookupUnqualified(R, S);
268
269 return !R.empty();
270}
271
272void MultiplexExternalSemaSource::ReadTentativeDefinitions(
273 SmallVectorImpl<VarDecl*> &TentativeDefs) {
274 for(size_t i = 0; i < Sources.size(); ++i)
275 Sources[i]->ReadTentativeDefinitions(TentativeDefs);
276}
277
278void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
279 SmallVectorImpl<const DeclaratorDecl*> &Decls) {
280 for(size_t i = 0; i < Sources.size(); ++i)
281 Sources[i]->ReadUnusedFileScopedDecls(Decls);
282}
283
284void MultiplexExternalSemaSource::ReadDelegatingConstructors(
285 SmallVectorImpl<CXXConstructorDecl*> &Decls) {
286 for(size_t i = 0; i < Sources.size(); ++i)
287 Sources[i]->ReadDelegatingConstructors(Decls);
288}
289
290void MultiplexExternalSemaSource::ReadExtVectorDecls(
291 SmallVectorImpl<TypedefNameDecl*> &Decls) {
292 for(size_t i = 0; i < Sources.size(); ++i)
293 Sources[i]->ReadExtVectorDecls(Decls);
294}
295
296void MultiplexExternalSemaSource::ReadDeclsToCheckForDeferredDiags(
297 llvm::SmallSetVector<Decl *, 4> &Decls) {
298 for(size_t i = 0; i < Sources.size(); ++i)
299 Sources[i]->ReadDeclsToCheckForDeferredDiags(Decls);
300}
301
302void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates(
303 llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
304 for(size_t i = 0; i < Sources.size(); ++i)
305 Sources[i]->ReadUnusedLocalTypedefNameCandidates(Decls);
306}
307
308void MultiplexExternalSemaSource::ReadReferencedSelectors(
309 SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
310 for(size_t i = 0; i < Sources.size(); ++i)
311 Sources[i]->ReadReferencedSelectors(Sels);
312}
313
314void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
315 SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) {
316 for(size_t i = 0; i < Sources.size(); ++i)
317 Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
318}
319
320void MultiplexExternalSemaSource::ReadUsedVTables(
321 SmallVectorImpl<ExternalVTableUse> &VTables) {
322 for(size_t i = 0; i < Sources.size(); ++i)
323 Sources[i]->ReadUsedVTables(VTables);
324}
325
326void MultiplexExternalSemaSource::ReadPendingInstantiations(
327 SmallVectorImpl<std::pair<ValueDecl*,
328 SourceLocation> > &Pending) {
329 for(size_t i = 0; i < Sources.size(); ++i)
330 Sources[i]->ReadPendingInstantiations(Pending);
331}
332
333void MultiplexExternalSemaSource::ReadLateParsedTemplates(
334 llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
335 &LPTMap) {
336 for (size_t i = 0; i < Sources.size(); ++i)
337 Sources[i]->ReadLateParsedTemplates(LPTMap);
338}
339
340TypoCorrection MultiplexExternalSemaSource::CorrectTypo(
341 const DeclarationNameInfo &Typo,
342 int LookupKind, Scope *S, CXXScopeSpec *SS,
343 CorrectionCandidateCallback &CCC,
344 DeclContext *MemberContext,
345 bool EnteringContext,
346 const ObjCObjectPointerType *OPT) {
347 for (size_t I = 0, E = Sources.size(); I < E; ++I) {
348 if (TypoCorrection C = Sources[I]->CorrectTypo(Typo, LookupKind, S, SS, CCC,
349 MemberContext,
350 EnteringContext, OPT))
351 return C;
352 }
353 return TypoCorrection();
354}
355
356bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
357 SourceLocation Loc, QualType T) {
358 for (size_t I = 0, E = Sources.size(); I < E; ++I) {
359 if (Sources[I]->MaybeDiagnoseMissingCompleteType(Loc, T))
360 return true;
361 }
362 return false;
363}
364
365void MultiplexExternalSemaSource::AssignedLambdaNumbering(
366 CXXRecordDecl *Lambda) {
367 for (auto &Source : Sources)
368 Source->AssignedLambdaNumbering(Lambda);
369}
370