Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
Line
Count
Source (jump to first uncovered line)
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:
27
608
  ExternalASTSourceWrapper(ExternalASTSource *Source) : m_Source(Source) {
28
608
    assert(m_Source && "Can't wrap nullptr ExternalASTSource");
29
608
  }
30
31
  ~ExternalASTSourceWrapper() override;
32
33
169k
  clang::Decl *GetExternalDecl(uint32_t ID) override {
34
169k
    return m_Source->GetExternalDecl(ID);
35
169k
  }
36
37
0
  clang::Selector GetExternalSelector(uint32_t ID) override {
38
0
    return m_Source->GetExternalSelector(ID);
39
0
  }
40
41
0
  uint32_t GetNumExternalSelectors() override {
42
0
    return m_Source->GetNumExternalSelectors();
43
0
  }
44
45
46.6k
  clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override {
46
46.6k
    return m_Source->GetExternalDeclStmt(Offset);
47
46.6k
  }
48
49
  clang::CXXCtorInitializer **
50
4.04k
  GetExternalCXXCtorInitializers(uint64_t Offset) override {
51
4.04k
    return m_Source->GetExternalCXXCtorInitializers(Offset);
52
4.04k
  }
53
54
  clang::CXXBaseSpecifier *
55
7.32k
  GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
56
7.32k
    return m_Source->GetExternalCXXBaseSpecifiers(Offset);
57
7.32k
  }
58
59
0
  void updateOutOfDateIdentifier(clang::IdentifierInfo &II) override {
60
0
    m_Source->updateOutOfDateIdentifier(II);
61
0
  }
62
63
  bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
64
109k
                                      clang::DeclarationName Name) override {
65
109k
    return m_Source->FindExternalVisibleDeclsByName(DC, Name);
66
109k
  }
67
68
0
  void completeVisibleDeclsMap(const clang::DeclContext *DC) override {
69
0
    m_Source->completeVisibleDeclsMap(DC);
70
0
  }
71
72
367k
  clang::Module *getModule(unsigned ID) override {
73
367k
    return m_Source->getModule(ID);
74
367k
  }
75
76
  std::optional<clang::ASTSourceDescriptor>
77
0
  getSourceDescriptor(unsigned ID) override {
78
0
    return m_Source->getSourceDescriptor(ID);
79
0
  }
80
81
2.76M
  ExtKind hasExternalDefinitions(const clang::Decl *D) override {
82
2.76M
    return m_Source->hasExternalDefinitions(D);
83
2.76M
  }
84
85
  void FindExternalLexicalDecls(
86
      const clang::DeclContext *DC,
87
      llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
88
16.9k
      llvm::SmallVectorImpl<clang::Decl *> &Result) override {
89
16.9k
    m_Source->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
90
16.9k
  }
91
92
  void
93
  FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length,
94
0
                      llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
95
0
    m_Source->FindFileRegionDecls(File, Offset, Length, Decls);
96
0
  }
97
98
754k
  void CompleteRedeclChain(const clang::Decl *D) override {
99
754k
    m_Source->CompleteRedeclChain(D);
100
754k
  }
101
102
6.11k
  void CompleteType(clang::TagDecl *Tag) override {
103
6.11k
    m_Source->CompleteType(Tag);
104
6.11k
  }
105
106
0
  void CompleteType(clang::ObjCInterfaceDecl *Class) override {
107
0
    m_Source->CompleteType(Class);
108
0
  }
109
110
0
  void ReadComments() override { m_Source->ReadComments(); }
111
112
31.3k
  void StartedDeserializing() override { m_Source->StartedDeserializing(); }
113
114
31.3k
  void FinishedDeserializing() override { m_Source->FinishedDeserializing(); }
115
116
608
  void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
117
608
    m_Source->StartTranslationUnit(Consumer);
118
608
  }
119
120
  void PrintStats() override;
121
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
4.21k
          &VirtualBaseOffsets) override {
129
4.21k
    return m_Source->layoutRecordType(Record, Size, Alignment, FieldOffsets,
130
4.21k
                                      BaseOffsets, VirtualBaseOffsets);
131
4.21k
  }
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:
142
11.9k
  ASTConsumerForwarder(clang::ASTConsumer *c) : m_c(c) {
143
11.9k
    m_sc = llvm::dyn_cast<clang::SemaConsumer>(m_c);
144
11.9k
  }
145
146
  ~ASTConsumerForwarder() override;
147
148
11.9k
  void Initialize(clang::ASTContext &Context) override {
149
11.9k
    m_c->Initialize(Context);
150
11.9k
  }
151
152
173k
  bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
153
173k
    return m_c->HandleTopLevelDecl(D);
154
173k
  }
155
156
40
  void HandleInlineFunctionDefinition(clang::FunctionDecl *D) override {
157
40
    m_c->HandleInlineFunctionDefinition(D);
158
40
  }
159
160
96.4k
  void HandleInterestingDecl(clang::DeclGroupRef D) override {
161
96.4k
    m_c->HandleInterestingDecl(D);
162
96.4k
  }
163
164
11.9k
  void HandleTranslationUnit(clang::ASTContext &Ctx) override {
165
11.9k
    m_c->HandleTranslationUnit(Ctx);
166
11.9k
  }
167
168
23.2k
  void HandleTagDeclDefinition(clang::TagDecl *D) override {
169
23.2k
    m_c->HandleTagDeclDefinition(D);
170
23.2k
  }
171
172
29.7k
  void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override {
173
29.7k
    m_c->HandleTagDeclRequiredDefinition(D);
174
29.7k
  }
175
176
1.18k
  void HandleCXXImplicitFunctionInstantiation(clang::FunctionDecl *D) override {
177
1.18k
    m_c->HandleCXXImplicitFunctionInstantiation(D);
178
1.18k
  }
179
180
0
  void HandleTopLevelDeclInObjCContainer(clang::DeclGroupRef D) override {
181
0
    m_c->HandleTopLevelDeclInObjCContainer(D);
182
0
  }
183
184
0
  void HandleImplicitImportDecl(clang::ImportDecl *D) override {
185
0
    m_c->HandleImplicitImportDecl(D);
186
0
  }
187
188
0
  void CompleteTentativeDefinition(clang::VarDecl *D) override {
189
0
    m_c->CompleteTentativeDefinition(D);
190
0
  }
191
192
0
  void AssignInheritanceModel(clang::CXXRecordDecl *RD) override {
193
0
    m_c->AssignInheritanceModel(RD);
194
0
  }
195
196
9.83k
  void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override {
197
9.83k
    m_c->HandleCXXStaticMemberVarInstantiation(D);
198
9.83k
  }
199
200
0
  void HandleVTable(clang::CXXRecordDecl *RD) override {
201
0
    m_c->HandleVTable(RD);
202
0
  }
203
204
16.2k
  clang::ASTMutationListener *GetASTMutationListener() override {
205
16.2k
    return m_c->GetASTMutationListener();
206
16.2k
  }
207
208
304
  clang::ASTDeserializationListener *GetASTDeserializationListener() override {
209
304
    return m_c->GetASTDeserializationListener();
210
304
  }
211
212
  void PrintStats() override;
213
214
11.9k
  void InitializeSema(clang::Sema &S) override {
215
11.9k
    if (m_sc)
216
9.26k
      m_sc->InitializeSema(S);
217
11.9k
  }
218
219
  /// Inform the semantic consumer that Sema is no longer available.
220
11.9k
  void ForgetSema() override {
221
11.9k
    if (m_sc)
222
9.26k
      m_sc->ForgetSema();
223
11.9k
  }
224
225
53
  bool shouldSkipFunctionBody(clang::Decl *D) override {
226
53
    return m_c->shouldSkipFunctionBody(D);
227
53
  }
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.
253
  SemaSourceWithPriorities(clang::ExternalSemaSource &high_quality_source,
254
304
                           clang::ExternalSemaSource &low_quality_source) {
255
304
    Sources.push_back(&high_quality_source);
256
304
    Sources.push_back(&low_quality_source);
257
304
  }
258
259
  ~SemaSourceWithPriorities() override;
260
261
0
  void addSource(clang::ExternalSemaSource &source) {
262
0
    Sources.push_back(&source);
263
0
  }
264
265
  //===--------------------------------------------------------------------===//
266
  // ExternalASTSource.
267
  //===--------------------------------------------------------------------===//
268
269
169k
  clang::Decl *GetExternalDecl(uint32_t ID) override {
270
169k
    for (size_t i = 0; i < Sources.size(); 
++i0
)
271
169k
      if (clang::Decl *Result = Sources[i]->GetExternalDecl(ID))
272
169k
        return Result;
273
0
    return nullptr;
274
169k
  }
275
276
377k
  void CompleteRedeclChain(const clang::Decl *D) override {
277
1.13M
    for (size_t i = 0; i < Sources.size(); 
++i754k
)
278
754k
      Sources[i]->CompleteRedeclChain(D);
279
377k
  }
280
281
0
  clang::Selector GetExternalSelector(uint32_t ID) override {
282
0
    clang::Selector Sel;
283
0
    for (size_t i = 0; i < Sources.size(); ++i) {
284
0
      Sel = Sources[i]->GetExternalSelector(ID);
285
0
      if (!Sel.isNull())
286
0
        return Sel;
287
0
    }
288
0
    return Sel;
289
0
  }
290
291
0
  uint32_t GetNumExternalSelectors() override {
292
0
    for (size_t i = 0; i < Sources.size(); ++i)
293
0
      if (uint32_t total = Sources[i]->GetNumExternalSelectors())
294
0
        return total;
295
0
    return 0;
296
0
  }
297
298
46.6k
  clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override {
299
46.6k
    for (size_t i = 0; i < Sources.size(); 
++i0
)
300
46.6k
      if (clang::Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
301
46.6k
        return Result;
302
0
    return nullptr;
303
46.6k
  }
304
305
  clang::CXXBaseSpecifier *
306
7.32k
  GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
307
7.32k
    for (size_t i = 0; i < Sources.size(); 
++i0
)
308
7.32k
      if (clang::CXXBaseSpecifier *R =
309
7.32k
              Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
310
7.32k
        return R;
311
0
    return nullptr;
312
7.32k
  }
313
314
  clang::CXXCtorInitializer **
315
4.04k
  GetExternalCXXCtorInitializers(uint64_t Offset) override {
316
4.04k
    for (auto *S : Sources)
317
4.04k
      if (auto *R = S->GetExternalCXXCtorInitializers(Offset))
318
4.04k
        return R;
319
0
    return nullptr;
320
4.04k
  }
321
322
1.38M
  ExtKind hasExternalDefinitions(const clang::Decl *D) override {
323
1.38M
    for (const auto &S : Sources)
324
2.76M
      if (auto EK = S->hasExternalDefinitions(D))
325
2.76M
        if (EK != EK_ReplyHazy)
326
0
          return EK;
327
1.38M
    return EK_ReplyHazy;
328
1.38M
  }
329
330
  bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
331
94.5k
                                      clang::DeclarationName Name) override {
332
122k
    for (size_t i = 0; i < Sources.size(); 
++i28.0k
)
333
109k
      if (Sources[i]->FindExternalVisibleDeclsByName(DC, Name))
334
80.9k
        return true;
335
13.5k
    return false;
336
94.5k
  }
337
338
0
  void completeVisibleDeclsMap(const clang::DeclContext *DC) override {
339
    // FIXME: Only one source should be able to complete the decls map.
340
0
    for (size_t i = 0; i < Sources.size(); ++i)
341
0
      Sources[i]->completeVisibleDeclsMap(DC);
342
0
  }
343
344
  void FindExternalLexicalDecls(
345
      const clang::DeclContext *DC,
346
      llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
347
15.6k
      llvm::SmallVectorImpl<clang::Decl *> &Result) override {
348
18.2k
    for (size_t i = 0; i < Sources.size(); 
++i2.60k
) {
349
16.9k
      Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result);
350
16.9k
      if (!Result.empty())
351
14.3k
        return;
352
16.9k
    }
353
15.6k
  }
354
355
  void
356
  FindFileRegionDecls(clang::FileID File, unsigned Offset, unsigned Length,
357
0
                      llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
358
0
    for (size_t i = 0; i < Sources.size(); ++i)
359
0
      Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
360
0
  }
361
362
6.11k
  void CompleteType(clang::TagDecl *Tag) override {
363
6.11k
    for (clang::ExternalSemaSource *S : Sources) {
364
6.11k
      S->CompleteType(Tag);
365
      // Stop after the first source completed the type.
366
6.11k
      if (Tag->isCompleteDefinition())
367
6.11k
        break;
368
6.11k
    }
369
6.11k
  }
370
371
0
  void CompleteType(clang::ObjCInterfaceDecl *Class) override {
372
0
    for (size_t i = 0; i < Sources.size(); ++i)
373
0
      Sources[i]->CompleteType(Class);
374
0
  }
375
376
0
  void ReadComments() override {
377
0
    for (size_t i = 0; i < Sources.size(); ++i)
378
0
      Sources[i]->ReadComments();
379
0
  }
380
381
15.6k
  void StartedDeserializing() override {
382
47.0k
    for (size_t i = 0; i < Sources.size(); 
++i31.3k
)
383
31.3k
      Sources[i]->StartedDeserializing();
384
15.6k
  }
385
386
15.6k
  void FinishedDeserializing() override {
387
47.0k
    for (size_t i = 0; i < Sources.size(); 
++i31.3k
)
388
31.3k
      Sources[i]->FinishedDeserializing();
389
15.6k
  }
390
391
304
  void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
392
912
    for (size_t i = 0; i < Sources.size(); 
++i608
)
393
608
      Sources[i]->StartTranslationUnit(Consumer);
394
304
  }
395
396
  void PrintStats() override;
397
398
367k
  clang::Module *getModule(unsigned ID) override {
399
367k
    for (size_t i = 0; i < Sources.size(); 
++i0
)
400
367k
      if (auto M = Sources[i]->getModule(ID))
401
367k
        return M;
402
0
    return nullptr;
403
367k
  }
404
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
2.10k
          &VirtualBaseOffsets) override {
412
6.21k
    for (size_t i = 0; i < Sources.size(); 
++i4.10k
)
413
4.21k
      if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
414
4.21k
                                       BaseOffsets, VirtualBaseOffsets))
415
112
        return true;
416
1.99k
    return false;
417
2.10k
  }
418
419
0
  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {
420
0
    for (auto &Source : Sources)
421
0
      Source->getMemoryBufferSizes(sizes);
422
0
  }
423
424
  //===--------------------------------------------------------------------===//
425
  // ExternalSemaSource.
426
  //===--------------------------------------------------------------------===//
427
428
304
  void InitializeSema(clang::Sema &S) override {
429
304
    for (auto &Source : Sources)
430
608
      Source->InitializeSema(S);
431
304
  }
432
433
304
  void ForgetSema() override {
434
304
    for (auto &Source : Sources)
435
608
      Source->ForgetSema();
436
304
  }
437
438
0
  void ReadMethodPool(clang::Selector Sel) override {
439
0
    for (auto &Source : Sources)
440
0
      Source->ReadMethodPool(Sel);
441
0
  }
442
443
0
  void updateOutOfDateSelector(clang::Selector Sel) override {
444
0
    for (auto &Source : Sources)
445
0
      Source->updateOutOfDateSelector(Sel);
446
0
  }
447
448
  void ReadKnownNamespaces(
449
0
      llvm::SmallVectorImpl<clang::NamespaceDecl *> &Namespaces) override {
450
0
    for (auto &Source : Sources)
451
0
      Source->ReadKnownNamespaces(Namespaces);
452
0
  }
453
454
  void ReadUndefinedButUsed(
455
      llvm::MapVector<clang::NamedDecl *, clang::SourceLocation> &Undefined)
456
0
      override {
457
0
    for (auto &Source : Sources)
458
0
      Source->ReadUndefinedButUsed(Undefined);
459
0
  }
460
461
  void ReadMismatchingDeleteExpressions(
462
      llvm::MapVector<clang::FieldDecl *,
463
                      llvm::SmallVector<std::pair<clang::SourceLocation, bool>,
464
0
                                        4>> &Exprs) override {
465
0
    for (auto &Source : Sources)
466
0
      Source->ReadMismatchingDeleteExpressions(Exprs);
467
0
  }
468
469
0
  bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) override {
470
0
    for (auto &Source : Sources) {
471
0
      Source->LookupUnqualified(R, S);
472
0
      if (!R.empty())
473
0
        break;
474
0
    }
475
476
0
    return !R.empty();
477
0
  }
478
479
  void ReadTentativeDefinitions(
480
0
      llvm::SmallVectorImpl<clang::VarDecl *> &Defs) override {
481
0
    for (auto &Source : Sources)
482
0
      Source->ReadTentativeDefinitions(Defs);
483
0
  }
484
485
  void ReadUnusedFileScopedDecls(
486
0
      llvm::SmallVectorImpl<const clang::DeclaratorDecl *> &Decls) override {
487
0
    for (auto &Source : Sources)
488
0
      Source->ReadUnusedFileScopedDecls(Decls);
489
0
  }
490
491
  void ReadDelegatingConstructors(
492
0
      llvm::SmallVectorImpl<clang::CXXConstructorDecl *> &Decls) override {
493
0
    for (auto &Source : Sources)
494
0
      Source->ReadDelegatingConstructors(Decls);
495
0
  }
496
497
  void ReadExtVectorDecls(
498
0
      llvm::SmallVectorImpl<clang::TypedefNameDecl *> &Decls) override {
499
0
    for (auto &Source : Sources)
500
0
      Source->ReadExtVectorDecls(Decls);
501
0
  }
502
503
  void ReadUnusedLocalTypedefNameCandidates(
504
0
      llvm::SmallSetVector<const clang::TypedefNameDecl *, 4> &Decls) override {
505
0
    for (auto &Source : Sources)
506
0
      Source->ReadUnusedLocalTypedefNameCandidates(Decls);
507
0
  }
508
509
  void ReadReferencedSelectors(
510
      llvm::SmallVectorImpl<std::pair<clang::Selector, clang::SourceLocation>>
511
0
          &Sels) override {
512
0
    for (auto &Source : Sources)
513
0
      Source->ReadReferencedSelectors(Sels);
514
0
  }
515
516
  void ReadWeakUndeclaredIdentifiers(
517
      llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *, clang::WeakInfo>>
518
0
          &WI) override {
519
0
    for (auto &Source : Sources)
520
0
      Source->ReadWeakUndeclaredIdentifiers(WI);
521
0
  }
522
523
  void ReadUsedVTables(
524
0
      llvm::SmallVectorImpl<clang::ExternalVTableUse> &VTables) override {
525
0
    for (auto &Source : Sources)
526
0
      Source->ReadUsedVTables(VTables);
527
0
  }
528
529
  void ReadPendingInstantiations(
530
      llvm::SmallVectorImpl<
531
          std::pair<clang::ValueDecl *, clang::SourceLocation>> &Pending)
532
0
      override {
533
0
    for (auto &Source : Sources)
534
0
      Source->ReadPendingInstantiations(Pending);
535
0
  }
536
537
  void ReadLateParsedTemplates(
538
      llvm::MapVector<const clang::FunctionDecl *,
539
                      std::unique_ptr<clang::LateParsedTemplate>> &LPTMap)
540
0
      override {
541
0
    for (auto &Source : Sources)
542
0
      Source->ReadLateParsedTemplates(LPTMap);
543
0
  }
544
545
  clang::TypoCorrection
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
0
              const clang::ObjCObjectPointerType *OPT) override {
551
0
    for (auto &Source : Sources) {
552
0
      if (clang::TypoCorrection C =
553
0
              Source->CorrectTypo(Typo, LookupKind, S, SS, CCC,
554
0
                                      MemberContext, EnteringContext, OPT))
555
0
        return C;
556
0
    }
557
0
    return clang::TypoCorrection();
558
0
  }
559
560
  bool MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc,
561
0
                                        clang::QualType T) override {
562
0
    for (auto &Source : Sources) {
563
0
      if (Source->MaybeDiagnoseMissingCompleteType(Loc, T))
564
0
        return true;
565
0
    }
566
0
    return false;
567
0
  }
568
};
569
570
} // namespace lldb_private
571
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H