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