Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
39654 views
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:
33
ExternalASTSourceWrapper(ExternalASTSource *Source) : m_Source(Source) {
34
assert(m_Source && "Can't wrap nullptr ExternalASTSource");
35
}
36
37
~ExternalASTSourceWrapper() override;
38
39
clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override {
40
return m_Source->GetExternalDecl(ID);
41
}
42
43
clang::Selector GetExternalSelector(uint32_t ID) override {
44
return m_Source->GetExternalSelector(ID);
45
}
46
47
uint32_t GetNumExternalSelectors() override {
48
return m_Source->GetNumExternalSelectors();
49
}
50
51
clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override {
52
return m_Source->GetExternalDeclStmt(Offset);
53
}
54
55
clang::CXXCtorInitializer **
56
GetExternalCXXCtorInitializers(uint64_t Offset) override {
57
return m_Source->GetExternalCXXCtorInitializers(Offset);
58
}
59
60
clang::CXXBaseSpecifier *
61
GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
62
return m_Source->GetExternalCXXBaseSpecifiers(Offset);
63
}
64
65
void updateOutOfDateIdentifier(const clang::IdentifierInfo &II) override {
66
m_Source->updateOutOfDateIdentifier(II);
67
}
68
69
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
70
clang::DeclarationName Name) override {
71
return m_Source->FindExternalVisibleDeclsByName(DC, Name);
72
}
73
74
void completeVisibleDeclsMap(const clang::DeclContext *DC) override {
75
m_Source->completeVisibleDeclsMap(DC);
76
}
77
78
clang::Module *getModule(unsigned ID) override {
79
return m_Source->getModule(ID);
80
}
81
82
std::optional<clang::ASTSourceDescriptor>
83
getSourceDescriptor(unsigned ID) override {
84
return m_Source->getSourceDescriptor(ID);
85
}
86
87
ExtKind hasExternalDefinitions(const clang::Decl *D) override {
88
return m_Source->hasExternalDefinitions(D);
89
}
90
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
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
104
void CompleteRedeclChain(const clang::Decl *D) override {
105
m_Source->CompleteRedeclChain(D);
106
}
107
108
void CompleteType(clang::TagDecl *Tag) override {
109
m_Source->CompleteType(Tag);
110
}
111
112
void CompleteType(clang::ObjCInterfaceDecl *Class) override {
113
m_Source->CompleteType(Class);
114
}
115
116
void ReadComments() override { m_Source->ReadComments(); }
117
118
void StartedDeserializing() override { m_Source->StartedDeserializing(); }
119
120
void FinishedDeserializing() override { m_Source->FinishedDeserializing(); }
121
122
void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
123
m_Source->StartTranslationUnit(Consumer);
124
}
125
126
void PrintStats() override;
127
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:
148
ASTConsumerForwarder(clang::ASTConsumer *c) : m_c(c) {
149
m_sc = llvm::dyn_cast<clang::SemaConsumer>(m_c);
150
}
151
152
~ASTConsumerForwarder() override;
153
154
void Initialize(clang::ASTContext &Context) override {
155
m_c->Initialize(Context);
156
}
157
158
bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
159
return m_c->HandleTopLevelDecl(D);
160
}
161
162
void HandleInlineFunctionDefinition(clang::FunctionDecl *D) override {
163
m_c->HandleInlineFunctionDefinition(D);
164
}
165
166
void HandleInterestingDecl(clang::DeclGroupRef D) override {
167
m_c->HandleInterestingDecl(D);
168
}
169
170
void HandleTranslationUnit(clang::ASTContext &Ctx) override {
171
m_c->HandleTranslationUnit(Ctx);
172
}
173
174
void HandleTagDeclDefinition(clang::TagDecl *D) override {
175
m_c->HandleTagDeclDefinition(D);
176
}
177
178
void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override {
179
m_c->HandleTagDeclRequiredDefinition(D);
180
}
181
182
void HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl *D) override {
183
m_c->HandleCXXImplicitFunctionInstantiation(D);
184
}
185
186
void HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D) override {
187
m_c->HandleTopLevelDeclInObjCContainer(D);
188
}
189
190
void HandleImplicitImportDecl(clang::ImportDecl *D) override {
191
m_c->HandleImplicitImportDecl(D);
192
}
193
194
void CompleteTentativeDefinition(clang::VarDecl *D) override {
195
m_c->CompleteTentativeDefinition(D);
196
}
197
198
void AssignInheritanceModel(clang::CXXRecordDecl *RD) override {
199
m_c->AssignInheritanceModel(RD);
200
}
201
202
void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override {
203
m_c->HandleCXXStaticMemberVarInstantiation(D);
204
}
205
206
void HandleVTable(clang::CXXRecordDecl *RD) override {
207
m_c->HandleVTable(RD);
208
}
209
210
clang::ASTMutationListener *GetASTMutationListener() override {
211
return m_c->GetASTMutationListener();
212
}
213
214
clang::ASTDeserializationListener *GetASTDeserializationListener() override {
215
return m_c->GetASTDeserializationListener();
216
}
217
218
void PrintStats() override;
219
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.
226
void ForgetSema() override {
227
if (m_sc)
228
m_sc->ForgetSema();
229
}
230
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.
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
267
void addSource(clang::ExternalSemaSource &source) {
268
Sources.push_back(&source);
269
}
270
271
//===--------------------------------------------------------------------===//
272
// ExternalASTSource.
273
//===--------------------------------------------------------------------===//
274
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
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
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
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
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 *
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 **
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
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
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
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
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
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
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
377
void CompleteType(clang::ObjCInterfaceDecl *Class) override {
378
for (size_t i = 0; i < Sources.size(); ++i)
379
Sources[i]->CompleteType(Class);
380
}
381
382
void ReadComments() override {
383
for (size_t i = 0; i < Sources.size(); ++i)
384
Sources[i]->ReadComments();
385
}
386
387
void StartedDeserializing() override {
388
for (size_t i = 0; i < Sources.size(); ++i)
389
Sources[i]->StartedDeserializing();
390
}
391
392
void FinishedDeserializing() override {
393
for (size_t i = 0; i < Sources.size(); ++i)
394
Sources[i]->FinishedDeserializing();
395
}
396
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
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
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
425
void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {
426
for (auto &Source : Sources)
427
Source->getMemoryBufferSizes(sizes);
428
}
429
430
//===--------------------------------------------------------------------===//
431
// ExternalSemaSource.
432
//===--------------------------------------------------------------------===//
433
434
void InitializeSema(clang::Sema &S) override {
435
for (auto &Source : Sources)
436
Source->InitializeSema(S);
437
}
438
439
void ForgetSema() override {
440
for (auto &Source : Sources)
441
Source->ForgetSema();
442
}
443
444
void ReadMethodPool(clang::Selector Sel) override {
445
for (auto &Source : Sources)
446
Source->ReadMethodPool(Sel);
447
}
448
449
void updateOutOfDateSelector(clang::Selector Sel) override {
450
for (auto &Source : Sources)
451
Source->updateOutOfDateSelector(Sel);
452
}
453
454
void ReadKnownNamespaces(
455
llvm::SmallVectorImpl<clang::NamespaceDecl *> &Namespaces) override {
456
for (auto &Source : Sources)
457
Source->ReadKnownNamespaces(Namespaces);
458
}
459
460
void ReadUndefinedButUsed(
461
llvm::MapVector<clang::NamedDecl *, clang::SourceLocation> &Undefined)
462
override {
463
for (auto &Source : Sources)
464
Source->ReadUndefinedButUsed(Undefined);
465
}
466
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
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
485
void ReadTentativeDefinitions(
486
llvm::SmallVectorImpl<clang::VarDecl *> &Defs) override {
487
for (auto &Source : Sources)
488
Source->ReadTentativeDefinitions(Defs);
489
}
490
491
void ReadUnusedFileScopedDecls(
492
llvm::SmallVectorImpl<const clang::DeclaratorDecl *> &Decls) override {
493
for (auto &Source : Sources)
494
Source->ReadUnusedFileScopedDecls(Decls);
495
}
496
497
void ReadDelegatingConstructors(
498
llvm::SmallVectorImpl<clang::CXXConstructorDecl *> &Decls) override {
499
for (auto &Source : Sources)
500
Source->ReadDelegatingConstructors(Decls);
501
}
502
503
void ReadExtVectorDecls(
504
llvm::SmallVectorImpl<clang::TypedefNameDecl *> &Decls) override {
505
for (auto &Source : Sources)
506
Source->ReadExtVectorDecls(Decls);
507
}
508
509
void ReadUnusedLocalTypedefNameCandidates(
510
llvm::SmallSetVector<const clang::TypedefNameDecl *, 4> &Decls) override {
511
for (auto &Source : Sources)
512
Source->ReadUnusedLocalTypedefNameCandidates(Decls);
513
}
514
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
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
529
void ReadUsedVTables(
530
llvm::SmallVectorImpl<clang::ExternalVTableUse> &VTables) override {
531
for (auto &Source : Sources)
532
Source->ReadUsedVTables(VTables);
533
}
534
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
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
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
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
579