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