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