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