xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- ASTUtils.h ----------------------------------------------*- 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 #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
10 #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
11 
12 #include "clang/Basic/ASTSourceDescriptor.h"
13 #include "clang/Sema/Lookup.h"
14 #include "clang/Sema/MultiplexExternalSemaSource.h"
15 #include "clang/Sema/Sema.h"
16 #include "clang/Sema/SemaConsumer.h"
17 #include <optional>
18 
19 namespace clang {
20 
21 class Module;
22 
23 } // namespace clang
24 
25 namespace lldb_private {
26 
27 /// Wraps an ExternalASTSource into an ExternalSemaSource. Doesn't take
28 /// ownership of the provided source.
29 class ExternalASTSourceWrapper : public clang::ExternalSemaSource {
30   ExternalASTSource *m_Source;
31 
32 public:
ExternalASTSourceWrapper(ExternalASTSource * Source)33   ExternalASTSourceWrapper(ExternalASTSource *Source) : m_Source(Source) {
34     assert(m_Source && "Can't wrap nullptr ExternalASTSource");
35   }
36 
37   ~ExternalASTSourceWrapper() override;
38 
GetExternalDecl(clang::GlobalDeclID ID)39   clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override {
40     return m_Source->GetExternalDecl(ID);
41   }
42 
GetExternalSelector(uint32_t ID)43   clang::Selector GetExternalSelector(uint32_t ID) override {
44     return m_Source->GetExternalSelector(ID);
45   }
46 
GetNumExternalSelectors()47   uint32_t GetNumExternalSelectors() override {
48     return m_Source->GetNumExternalSelectors();
49   }
50 
GetExternalDeclStmt(uint64_t Offset)51   clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override {
52     return m_Source->GetExternalDeclStmt(Offset);
53   }
54 
55   clang::CXXCtorInitializer **
GetExternalCXXCtorInitializers(uint64_t Offset)56   GetExternalCXXCtorInitializers(uint64_t Offset) override {
57     return m_Source->GetExternalCXXCtorInitializers(Offset);
58   }
59 
60   clang::CXXBaseSpecifier *
GetExternalCXXBaseSpecifiers(uint64_t Offset)61   GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
62     return m_Source->GetExternalCXXBaseSpecifiers(Offset);
63   }
64 
updateOutOfDateIdentifier(const clang::IdentifierInfo & II)65   void updateOutOfDateIdentifier(const clang::IdentifierInfo &II) override {
66     m_Source->updateOutOfDateIdentifier(II);
67   }
68 
FindExternalVisibleDeclsByName(const clang::DeclContext * DC,clang::DeclarationName Name)69   bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
70                                       clang::DeclarationName Name) override {
71     return m_Source->FindExternalVisibleDeclsByName(DC, Name);
72   }
73 
completeVisibleDeclsMap(const clang::DeclContext * DC)74   void completeVisibleDeclsMap(const clang::DeclContext *DC) override {
75     m_Source->completeVisibleDeclsMap(DC);
76   }
77 
getModule(unsigned ID)78   clang::Module *getModule(unsigned ID) override {
79     return m_Source->getModule(ID);
80   }
81 
82   std::optional<clang::ASTSourceDescriptor>
getSourceDescriptor(unsigned ID)83   getSourceDescriptor(unsigned ID) override {
84     return m_Source->getSourceDescriptor(ID);
85   }
86 
hasExternalDefinitions(const clang::Decl * D)87   ExtKind hasExternalDefinitions(const clang::Decl *D) override {
88     return m_Source->hasExternalDefinitions(D);
89   }
90 
FindExternalLexicalDecls(const clang::DeclContext * DC,llvm::function_ref<bool (clang::Decl::Kind)> IsKindWeWant,llvm::SmallVectorImpl<clang::Decl * > & Result)91   void FindExternalLexicalDecls(
92       const clang::DeclContext *DC,
93       llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
94       llvm::SmallVectorImpl<clang::Decl *> &Result) override {
95     m_Source->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
96   }
97 
98   void
FindFileRegionDecls(clang::FileID File,unsigned Offset,unsigned Length,llvm::SmallVectorImpl<clang::Decl * > & Decls)99   FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length,
100                       llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
101     m_Source->FindFileRegionDecls(File, Offset, Length, Decls);
102   }
103 
CompleteRedeclChain(const clang::Decl * D)104   void CompleteRedeclChain(const clang::Decl *D) override {
105     m_Source->CompleteRedeclChain(D);
106   }
107 
CompleteType(clang::TagDecl * Tag)108   void CompleteType(clang::TagDecl *Tag) override {
109     m_Source->CompleteType(Tag);
110   }
111 
CompleteType(clang::ObjCInterfaceDecl * Class)112   void CompleteType(clang::ObjCInterfaceDecl *Class) override {
113     m_Source->CompleteType(Class);
114   }
115 
ReadComments()116   void ReadComments() override { m_Source->ReadComments(); }
117 
StartedDeserializing()118   void StartedDeserializing() override { m_Source->StartedDeserializing(); }
119 
FinishedDeserializing()120   void FinishedDeserializing() override { m_Source->FinishedDeserializing(); }
121 
StartTranslationUnit(clang::ASTConsumer * Consumer)122   void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
123     m_Source->StartTranslationUnit(Consumer);
124   }
125 
126   void PrintStats() override;
127 
layoutRecordType(const clang::RecordDecl * Record,uint64_t & Size,uint64_t & Alignment,llvm::DenseMap<const clang::FieldDecl *,uint64_t> & FieldOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & BaseOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & VirtualBaseOffsets)128   bool layoutRecordType(
129       const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
130       llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
131       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
132           &BaseOffsets,
133       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
134           &VirtualBaseOffsets) override {
135     return m_Source->layoutRecordType(Record, Size, Alignment, FieldOffsets,
136                                       BaseOffsets, VirtualBaseOffsets);
137   }
138 };
139 
140 /// Wraps an ASTConsumer into an SemaConsumer. Doesn't take ownership of the
141 /// provided consumer. If the provided ASTConsumer is also a SemaConsumer,
142 /// the wrapper will also forward SemaConsumer functions.
143 class ASTConsumerForwarder : public clang::SemaConsumer {
144   clang::ASTConsumer *m_c;
145   clang::SemaConsumer *m_sc;
146 
147 public:
ASTConsumerForwarder(clang::ASTConsumer * c)148   ASTConsumerForwarder(clang::ASTConsumer *c) : m_c(c) {
149     m_sc = llvm::dyn_cast<clang::SemaConsumer>(m_c);
150   }
151 
152   ~ASTConsumerForwarder() override;
153 
Initialize(clang::ASTContext & Context)154   void Initialize(clang::ASTContext &Context) override {
155     m_c->Initialize(Context);
156   }
157 
HandleTopLevelDecl(clang::DeclGroupRef D)158   bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
159     return m_c->HandleTopLevelDecl(D);
160   }
161 
HandleInlineFunctionDefinition(clang::FunctionDecl * D)162   void HandleInlineFunctionDefinition(clang::FunctionDecl *D) override {
163     m_c->HandleInlineFunctionDefinition(D);
164   }
165 
HandleInterestingDecl(clang::DeclGroupRef D)166   void HandleInterestingDecl(clang::DeclGroupRef D) override {
167     m_c->HandleInterestingDecl(D);
168   }
169 
HandleTranslationUnit(clang::ASTContext & Ctx)170   void HandleTranslationUnit(clang::ASTContext &Ctx) override {
171     m_c->HandleTranslationUnit(Ctx);
172   }
173 
HandleTagDeclDefinition(clang::TagDecl * D)174   void HandleTagDeclDefinition(clang::TagDecl *D) override {
175     m_c->HandleTagDeclDefinition(D);
176   }
177 
HandleTagDeclRequiredDefinition(const clang::TagDecl * D)178   void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override {
179     m_c->HandleTagDeclRequiredDefinition(D);
180   }
181 
HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl * D)182   void HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl *D) override {
183     m_c->HandleCXXImplicitFunctionInstantiation(D);
184   }
185 
HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D)186   void HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D) override {
187     m_c->HandleTopLevelDeclInObjCContainer(D);
188   }
189 
HandleImplicitImportDecl(clang::ImportDecl * D)190   void HandleImplicitImportDecl(clang::ImportDecl *D) override {
191     m_c->HandleImplicitImportDecl(D);
192   }
193 
CompleteTentativeDefinition(clang::VarDecl * D)194   void CompleteTentativeDefinition(clang::VarDecl *D) override {
195     m_c->CompleteTentativeDefinition(D);
196   }
197 
AssignInheritanceModel(clang::CXXRecordDecl * RD)198   void AssignInheritanceModel(clang::CXXRecordDecl *RD) override {
199     m_c->AssignInheritanceModel(RD);
200   }
201 
HandleCXXStaticMemberVarInstantiation(clang::VarDecl * D)202   void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override {
203     m_c->HandleCXXStaticMemberVarInstantiation(D);
204   }
205 
HandleVTable(clang::CXXRecordDecl * RD)206   void HandleVTable(clang::CXXRecordDecl *RD) override {
207     m_c->HandleVTable(RD);
208   }
209 
GetASTMutationListener()210   clang::ASTMutationListener *GetASTMutationListener() override {
211     return m_c->GetASTMutationListener();
212   }
213 
GetASTDeserializationListener()214   clang::ASTDeserializationListener *GetASTDeserializationListener() override {
215     return m_c->GetASTDeserializationListener();
216   }
217 
218   void PrintStats() override;
219 
InitializeSema(clang::Sema & S)220   void InitializeSema(clang::Sema &S) override {
221     if (m_sc)
222       m_sc->InitializeSema(S);
223   }
224 
225   /// Inform the semantic consumer that Sema is no longer available.
ForgetSema()226   void ForgetSema() override {
227     if (m_sc)
228       m_sc->ForgetSema();
229   }
230 
shouldSkipFunctionBody(clang::Decl * D)231   bool shouldSkipFunctionBody(clang::Decl *D) override {
232     return m_c->shouldSkipFunctionBody(D);
233   }
234 };
235 
236 /// A ExternalSemaSource multiplexer that prioritizes its sources.
237 ///
238 /// This ExternalSemaSource will forward all requests to its attached sources.
239 /// However, unlike a normal multiplexer it will not forward a request to all
240 /// sources, but instead give priority to certain sources. If a source with a
241 /// higher priority can fulfill a request, all sources with a lower priority
242 /// will not receive the request.
243 ///
244 /// This class is mostly use to multiplex between sources of different
245 /// 'quality', e.g. a C++ modules and debug information. The C++ module will
246 /// provide more accurate replies to the requests, but might not be able to
247 /// answer all requests. The debug information will be used as a fallback then
248 /// to provide information that is not in the C++ module.
249 class SemaSourceWithPriorities : public clang::ExternalSemaSource {
250 
251 private:
252   /// The sources ordered in decreasing priority.
253   llvm::SmallVector<clang::ExternalSemaSource *, 2> Sources;
254 
255 public:
256   /// Construct a SemaSourceWithPriorities with a 'high quality' source that
257   /// has the higher priority and a 'low quality' source that will be used
258   /// as a fallback.
SemaSourceWithPriorities(clang::ExternalSemaSource & high_quality_source,clang::ExternalSemaSource & low_quality_source)259   SemaSourceWithPriorities(clang::ExternalSemaSource &high_quality_source,
260                            clang::ExternalSemaSource &low_quality_source) {
261     Sources.push_back(&high_quality_source);
262     Sources.push_back(&low_quality_source);
263   }
264 
265   ~SemaSourceWithPriorities() override;
266 
addSource(clang::ExternalSemaSource & source)267   void addSource(clang::ExternalSemaSource &source) {
268     Sources.push_back(&source);
269   }
270 
271   //===--------------------------------------------------------------------===//
272   // ExternalASTSource.
273   //===--------------------------------------------------------------------===//
274 
GetExternalDecl(clang::GlobalDeclID ID)275   clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override {
276     for (size_t i = 0; i < Sources.size(); ++i)
277       if (clang::Decl *Result = Sources[i]->GetExternalDecl(ID))
278         return Result;
279     return nullptr;
280   }
281 
CompleteRedeclChain(const clang::Decl * D)282   void CompleteRedeclChain(const clang::Decl *D) override {
283     for (size_t i = 0; i < Sources.size(); ++i)
284       Sources[i]->CompleteRedeclChain(D);
285   }
286 
GetExternalSelector(uint32_t ID)287   clang::Selector GetExternalSelector(uint32_t ID) override {
288     clang::Selector Sel;
289     for (size_t i = 0; i < Sources.size(); ++i) {
290       Sel = Sources[i]->GetExternalSelector(ID);
291       if (!Sel.isNull())
292         return Sel;
293     }
294     return Sel;
295   }
296 
GetNumExternalSelectors()297   uint32_t GetNumExternalSelectors() override {
298     for (size_t i = 0; i < Sources.size(); ++i)
299       if (uint32_t total = Sources[i]->GetNumExternalSelectors())
300         return total;
301     return 0;
302   }
303 
GetExternalDeclStmt(uint64_t Offset)304   clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override {
305     for (size_t i = 0; i < Sources.size(); ++i)
306       if (clang::Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
307         return Result;
308     return nullptr;
309   }
310 
311   clang::CXXBaseSpecifier *
GetExternalCXXBaseSpecifiers(uint64_t Offset)312   GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
313     for (size_t i = 0; i < Sources.size(); ++i)
314       if (clang::CXXBaseSpecifier *R =
315               Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
316         return R;
317     return nullptr;
318   }
319 
320   clang::CXXCtorInitializer **
GetExternalCXXCtorInitializers(uint64_t Offset)321   GetExternalCXXCtorInitializers(uint64_t Offset) override {
322     for (auto *S : Sources)
323       if (auto *R = S->GetExternalCXXCtorInitializers(Offset))
324         return R;
325     return nullptr;
326   }
327 
hasExternalDefinitions(const clang::Decl * D)328   ExtKind hasExternalDefinitions(const clang::Decl *D) override {
329     for (const auto &S : Sources)
330       if (auto EK = S->hasExternalDefinitions(D))
331         if (EK != EK_ReplyHazy)
332           return EK;
333     return EK_ReplyHazy;
334   }
335 
FindExternalVisibleDeclsByName(const clang::DeclContext * DC,clang::DeclarationName Name)336   bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
337                                       clang::DeclarationName Name) override {
338     for (size_t i = 0; i < Sources.size(); ++i)
339       if (Sources[i]->FindExternalVisibleDeclsByName(DC, Name))
340         return true;
341     return false;
342   }
343 
completeVisibleDeclsMap(const clang::DeclContext * DC)344   void completeVisibleDeclsMap(const clang::DeclContext *DC) override {
345     // FIXME: Only one source should be able to complete the decls map.
346     for (size_t i = 0; i < Sources.size(); ++i)
347       Sources[i]->completeVisibleDeclsMap(DC);
348   }
349 
FindExternalLexicalDecls(const clang::DeclContext * DC,llvm::function_ref<bool (clang::Decl::Kind)> IsKindWeWant,llvm::SmallVectorImpl<clang::Decl * > & Result)350   void FindExternalLexicalDecls(
351       const clang::DeclContext *DC,
352       llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
353       llvm::SmallVectorImpl<clang::Decl *> &Result) override {
354     for (size_t i = 0; i < Sources.size(); ++i) {
355       Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
356       if (!Result.empty())
357         return;
358     }
359   }
360 
361   void
FindFileRegionDecls(clang::FileID File,unsigned Offset,unsigned Length,llvm::SmallVectorImpl<clang::Decl * > & Decls)362   FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length,
363                       llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
364     for (size_t i = 0; i < Sources.size(); ++i)
365       Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
366   }
367 
CompleteType(clang::TagDecl * Tag)368   void CompleteType(clang::TagDecl *Tag) override {
369     for (clang::ExternalSemaSource *S : Sources) {
370       S->CompleteType(Tag);
371       // Stop after the first source completed the type.
372       if (Tag->isCompleteDefinition())
373         break;
374     }
375   }
376 
CompleteType(clang::ObjCInterfaceDecl * Class)377   void CompleteType(clang::ObjCInterfaceDecl *Class) override {
378     for (size_t i = 0; i < Sources.size(); ++i)
379       Sources[i]->CompleteType(Class);
380   }
381 
ReadComments()382   void ReadComments() override {
383     for (size_t i = 0; i < Sources.size(); ++i)
384       Sources[i]->ReadComments();
385   }
386 
StartedDeserializing()387   void StartedDeserializing() override {
388     for (size_t i = 0; i < Sources.size(); ++i)
389       Sources[i]->StartedDeserializing();
390   }
391 
FinishedDeserializing()392   void FinishedDeserializing() override {
393     for (size_t i = 0; i < Sources.size(); ++i)
394       Sources[i]->FinishedDeserializing();
395   }
396 
StartTranslationUnit(clang::ASTConsumer * Consumer)397   void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
398     for (size_t i = 0; i < Sources.size(); ++i)
399       Sources[i]->StartTranslationUnit(Consumer);
400   }
401 
402   void PrintStats() override;
403 
getModule(unsigned ID)404   clang::Module *getModule(unsigned ID) override {
405     for (size_t i = 0; i < Sources.size(); ++i)
406       if (auto M = Sources[i]->getModule(ID))
407         return M;
408     return nullptr;
409   }
410 
layoutRecordType(const clang::RecordDecl * Record,uint64_t & Size,uint64_t & Alignment,llvm::DenseMap<const clang::FieldDecl *,uint64_t> & FieldOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & BaseOffsets,llvm::DenseMap<const clang::CXXRecordDecl *,clang::CharUnits> & VirtualBaseOffsets)411   bool layoutRecordType(
412       const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
413       llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
414       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
415           &BaseOffsets,
416       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
417           &VirtualBaseOffsets) override {
418     for (size_t i = 0; i < Sources.size(); ++i)
419       if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
420                                        BaseOffsets, VirtualBaseOffsets))
421         return true;
422     return false;
423   }
424 
getMemoryBufferSizes(MemoryBufferSizes & sizes)425   void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {
426     for (auto &Source : Sources)
427       Source->getMemoryBufferSizes(sizes);
428   }
429 
430   //===--------------------------------------------------------------------===//
431   // ExternalSemaSource.
432   //===--------------------------------------------------------------------===//
433 
InitializeSema(clang::Sema & S)434   void InitializeSema(clang::Sema &S) override {
435     for (auto &Source : Sources)
436       Source->InitializeSema(S);
437   }
438 
ForgetSema()439   void ForgetSema() override {
440     for (auto &Source : Sources)
441       Source->ForgetSema();
442   }
443 
ReadMethodPool(clang::Selector Sel)444   void ReadMethodPool(clang::Selector Sel) override {
445     for (auto &Source : Sources)
446       Source->ReadMethodPool(Sel);
447   }
448 
updateOutOfDateSelector(clang::Selector Sel)449   void updateOutOfDateSelector(clang::Selector Sel) override {
450     for (auto &Source : Sources)
451       Source->updateOutOfDateSelector(Sel);
452   }
453 
ReadKnownNamespaces(llvm::SmallVectorImpl<clang::NamespaceDecl * > & Namespaces)454   void ReadKnownNamespaces(
455       llvm::SmallVectorImpl<clang::NamespaceDecl *> &Namespaces) override {
456     for (auto &Source : Sources)
457       Source->ReadKnownNamespaces(Namespaces);
458   }
459 
ReadUndefinedButUsed(llvm::MapVector<clang::NamedDecl *,clang::SourceLocation> & Undefined)460   void ReadUndefinedButUsed(
461       llvm::MapVector<clang::NamedDecl *, clang::SourceLocation> &Undefined)
462       override {
463     for (auto &Source : Sources)
464       Source->ReadUndefinedButUsed(Undefined);
465   }
466 
ReadMismatchingDeleteExpressions(llvm::MapVector<clang::FieldDecl *,llvm::SmallVector<std::pair<clang::SourceLocation,bool>,4>> & Exprs)467   void ReadMismatchingDeleteExpressions(
468       llvm::MapVector<clang::FieldDecl *,
469                       llvm::SmallVector<std::pair<clang::SourceLocation, bool>,
470                                         4>> &Exprs) override {
471     for (auto &Source : Sources)
472       Source->ReadMismatchingDeleteExpressions(Exprs);
473   }
474 
LookupUnqualified(clang::LookupResult & R,clang::Scope * S)475   bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) override {
476     for (auto &Source : Sources) {
477       Source->LookupUnqualified(R, S);
478       if (!R.empty())
479         break;
480     }
481 
482     return !R.empty();
483   }
484 
ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl * > & Defs)485   void ReadTentativeDefinitions(
486       llvm::SmallVectorImpl<clang::VarDecl *> &Defs) override {
487     for (auto &Source : Sources)
488       Source->ReadTentativeDefinitions(Defs);
489   }
490 
ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<const clang::DeclaratorDecl * > & Decls)491   void ReadUnusedFileScopedDecls(
492       llvm::SmallVectorImpl<const clang::DeclaratorDecl *> &Decls) override {
493     for (auto &Source : Sources)
494       Source->ReadUnusedFileScopedDecls(Decls);
495   }
496 
ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl * > & Decls)497   void ReadDelegatingConstructors(
498       llvm::SmallVectorImpl<clang::CXXConstructorDecl *> &Decls) override {
499     for (auto &Source : Sources)
500       Source->ReadDelegatingConstructors(Decls);
501   }
502 
ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl * > & Decls)503   void ReadExtVectorDecls(
504       llvm::SmallVectorImpl<clang::TypedefNameDecl *> &Decls) override {
505     for (auto &Source : Sources)
506       Source->ReadExtVectorDecls(Decls);
507   }
508 
ReadUnusedLocalTypedefNameCandidates(llvm::SmallSetVector<const clang::TypedefNameDecl *,4> & Decls)509   void ReadUnusedLocalTypedefNameCandidates(
510       llvm::SmallSetVector<const clang::TypedefNameDecl *, 4> &Decls) override {
511     for (auto &Source : Sources)
512       Source->ReadUnusedLocalTypedefNameCandidates(Decls);
513   }
514 
ReadReferencedSelectors(llvm::SmallVectorImpl<std::pair<clang::Selector,clang::SourceLocation>> & Sels)515   void ReadReferencedSelectors(
516       llvm::SmallVectorImpl<std::pair<clang::Selector, clang::SourceLocation>>
517           &Sels) override {
518     for (auto &Source : Sources)
519       Source->ReadReferencedSelectors(Sels);
520   }
521 
ReadWeakUndeclaredIdentifiers(llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *,clang::WeakInfo>> & WI)522   void ReadWeakUndeclaredIdentifiers(
523       llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *, clang::WeakInfo>>
524           &WI) override {
525     for (auto &Source : Sources)
526       Source->ReadWeakUndeclaredIdentifiers(WI);
527   }
528 
ReadUsedVTables(llvm::SmallVectorImpl<clang::ExternalVTableUse> & VTables)529   void ReadUsedVTables(
530       llvm::SmallVectorImpl<clang::ExternalVTableUse> &VTables) override {
531     for (auto &Source : Sources)
532       Source->ReadUsedVTables(VTables);
533   }
534 
ReadPendingInstantiations(llvm::SmallVectorImpl<std::pair<clang::ValueDecl *,clang::SourceLocation>> & Pending)535   void ReadPendingInstantiations(
536       llvm::SmallVectorImpl<
537           std::pair<clang::ValueDecl *, clang::SourceLocation>> &Pending)
538       override {
539     for (auto &Source : Sources)
540       Source->ReadPendingInstantiations(Pending);
541   }
542 
ReadLateParsedTemplates(llvm::MapVector<const clang::FunctionDecl *,std::unique_ptr<clang::LateParsedTemplate>> & LPTMap)543   void ReadLateParsedTemplates(
544       llvm::MapVector<const clang::FunctionDecl *,
545                       std::unique_ptr<clang::LateParsedTemplate>> &LPTMap)
546       override {
547     for (auto &Source : Sources)
548       Source->ReadLateParsedTemplates(LPTMap);
549   }
550 
551   clang::TypoCorrection
CorrectTypo(const clang::DeclarationNameInfo & Typo,int LookupKind,clang::Scope * S,clang::CXXScopeSpec * SS,clang::CorrectionCandidateCallback & CCC,clang::DeclContext * MemberContext,bool EnteringContext,const clang::ObjCObjectPointerType * OPT)552   CorrectTypo(const clang::DeclarationNameInfo &Typo, int LookupKind,
553               clang::Scope *S, clang::CXXScopeSpec *SS,
554               clang::CorrectionCandidateCallback &CCC,
555               clang::DeclContext *MemberContext, bool EnteringContext,
556               const clang::ObjCObjectPointerType *OPT) override {
557     for (auto &Source : Sources) {
558       if (clang::TypoCorrection C =
559               Source->CorrectTypo(Typo, LookupKind, S, SS, CCC,
560                                       MemberContext, EnteringContext, OPT))
561         return C;
562     }
563     return clang::TypoCorrection();
564   }
565 
MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc,clang::QualType T)566   bool MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc,
567                                         clang::QualType T) override {
568     for (auto &Source : Sources) {
569       if (Source->MaybeDiagnoseMissingCompleteType(Loc, T))
570         return true;
571     }
572     return false;
573   }
574 };
575 
576 } // namespace lldb_private
577 #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
578