Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Index/IndexingContext.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- IndexingContext.cpp - Indexing context data ------------------------===//
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
#include "IndexingContext.h"
10
#include "clang/AST/ASTContext.h"
11
#include "clang/AST/Attr.h"
12
#include "clang/AST/DeclObjC.h"
13
#include "clang/AST/DeclTemplate.h"
14
#include "clang/Basic/SourceLocation.h"
15
#include "clang/Basic/SourceManager.h"
16
#include "clang/Index/IndexDataConsumer.h"
17
18
using namespace clang;
19
using namespace index;
20
21
1.07k
static bool isGeneratedDecl(const Decl *D) {
22
1.07k
  if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>()) {
23
9
    return attr->getGeneratedDeclaration();
24
9
  }
25
1.07k
  return false;
26
1.07k
}
27
28
1.07k
bool IndexingContext::shouldIndex(const Decl *D) {
29
1.07k
  return !isGeneratedDecl(D);
30
1.07k
}
31
32
656
const LangOptions &IndexingContext::getLangOpts() const {
33
656
  return Ctx->getLangOpts();
34
656
}
35
36
5.76k
bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
37
5.76k
  return IndexOpts.IndexFunctionLocals;
38
5.76k
}
39
40
6
bool IndexingContext::shouldIndexImplicitInstantiation() const {
41
6
  return IndexOpts.IndexImplicitInstantiation;
42
6
}
43
44
57
bool IndexingContext::shouldIndexParametersInDeclarations() const {
45
57
  return IndexOpts.IndexParametersInDeclarations;
46
57
}
47
48
2.86k
bool IndexingContext::shouldIndexTemplateParameters() const {
49
2.86k
  return IndexOpts.IndexTemplateParameters;
50
2.86k
}
51
52
bool IndexingContext::handleDecl(const Decl *D,
53
                                 SymbolRoleSet Roles,
54
906
                                 ArrayRef<SymbolRelation> Relations) {
55
906
  return handleDecl(D, D->getLocation(), Roles, Relations);
56
906
}
57
58
bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
59
                                 SymbolRoleSet Roles,
60
                                 ArrayRef<SymbolRelation> Relations,
61
1.15k
                                 const DeclContext *DC) {
62
1.15k
  if (!DC)
63
1.10k
    DC = D->getDeclContext();
64
65
1.15k
  const Decl *OrigD = D;
66
1.15k
  if (isa<ObjCPropertyImplDecl>(D)) {
67
22
    D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl();
68
22
  }
69
1.15k
  return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
70
1.15k
                              Roles, Relations,
71
1.15k
                              nullptr, OrigD, DC);
72
1.15k
}
73
74
bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
75
                                      const NamedDecl *Parent,
76
                                      const DeclContext *DC,
77
                                      SymbolRoleSet Roles,
78
                                      ArrayRef<SymbolRelation> Relations,
79
                                      const Expr *RefE,
80
4.83k
                                      const Decl *RefD) {
81
4.83k
  if (!shouldIndexFunctionLocalSymbols() && 
isFunctionLocalSymbol(D)4.51k
)
82
2.12k
    return true;
83
84
2.71k
  if (!shouldIndexTemplateParameters() &&
85
2.71k
      
(2.71k
isa<NonTypeTemplateParmDecl>(D)2.71k
||
isa<TemplateTypeParmDecl>(D)2.71k
||
86
2.71k
       
isa<TemplateTemplateParmDecl>(D)2.62k
)) {
87
88
    return true;
88
88
  }
89
90
2.62k
  return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
91
2.62k
                              RefE, RefD, DC);
92
2.71k
}
93
94
static void reportModuleReferences(const Module *Mod,
95
                                   ArrayRef<SourceLocation> IdLocs,
96
                                   const ImportDecl *ImportD,
97
7
                                   IndexDataConsumer &DataConsumer) {
98
7
  if (!Mod)
99
3
    return;
100
4
  reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
101
4
                         DataConsumer);
102
4
  DataConsumer.handleModuleOccurrence(
103
4
      ImportD, Mod, (SymbolRoleSet)SymbolRole::Reference, IdLocs.back());
104
4
}
105
106
50
bool IndexingContext::importedModule(const ImportDecl *ImportD) {
107
50
  if (ImportD->isInvalidDecl())
108
0
    return true;
109
110
50
  SourceLocation Loc;
111
50
  auto IdLocs = ImportD->getIdentifierLocs();
112
50
  if (!IdLocs.empty())
113
10
    Loc = IdLocs.back();
114
40
  else
115
40
    Loc = ImportD->getLocation();
116
117
50
  SourceManager &SM = Ctx->getSourceManager();
118
50
  FileID FID = SM.getFileID(SM.getFileLoc(Loc));
119
50
  if (FID.isInvalid())
120
0
    return true;
121
122
50
  bool Invalid = false;
123
50
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
124
50
  if (Invalid || !SEntry.isFile())
125
0
    return true;
126
127
50
  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
128
10
    switch (IndexOpts.SystemSymbolFilter) {
129
0
    case IndexingOptions::SystemSymbolFilterKind::None:
130
0
      return true;
131
10
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
132
10
    case IndexingOptions::SystemSymbolFilterKind::All:
133
10
      break;
134
10
    }
135
10
  }
136
137
50
  const Module *Mod = ImportD->getImportedModule();
138
50
  if (!ImportD->isImplicit() && 
Mod->Parent10
&&
!IdLocs.empty()3
) {
139
3
    reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
140
3
                           DataConsumer);
141
3
  }
142
143
50
  SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration;
144
50
  if (ImportD->isImplicit())
145
40
    Roles |= (unsigned)SymbolRole::Implicit;
146
147
50
  return DataConsumer.handleModuleOccurrence(ImportD, Mod, Roles, Loc);
148
50
}
149
150
5.33k
bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
151
5.33k
  TemplateSpecializationKind TKind = TSK_Undeclared;
152
5.33k
  if (const ClassTemplateSpecializationDecl *
153
5.33k
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
154
160
    TKind = SD->getSpecializationKind();
155
5.17k
  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
156
2.28k
    TKind = FD->getTemplateSpecializationKind();
157
2.89k
  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
158
324
    TKind = VD->getTemplateSpecializationKind();
159
2.57k
  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
160
568
    if (RD->getInstantiatedFromMemberClass())
161
11
      TKind = RD->getTemplateSpecializationKind();
162
2.00k
  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
163
90
    if (ED->getInstantiatedFromMemberEnum())
164
3
      TKind = ED->getTemplateSpecializationKind();
165
1.91k
  } else if (isa<FieldDecl>(D) || 
isa<TypedefNameDecl>(D)1.73k
||
166
1.91k
             
isa<EnumConstantDecl>(D)1.58k
) {
167
372
    if (const auto *Parent = dyn_cast<Decl>(D->getDeclContext()))
168
372
      return isTemplateImplicitInstantiation(Parent);
169
372
  }
170
4.96k
  switch (TKind) {
171
4.75k
    case TSK_Undeclared:
172
      // Instantiation maybe not happen yet when we see a SpecializationDecl,
173
      // e.g. when the type doesn't need to be complete, we still treat it as an
174
      // instantiation as we'd like to keep the canonicalized result consistent.
175
4.75k
      return isa<ClassTemplateSpecializationDecl>(D);
176
159
    case TSK_ExplicitSpecialization:
177
159
      return false;
178
47
    case TSK_ImplicitInstantiation:
179
47
    case TSK_ExplicitInstantiationDeclaration:
180
52
    case TSK_ExplicitInstantiationDefinition:
181
52
      return true;
182
4.96k
  }
183
0
  llvm_unreachable("invalid TemplateSpecializationKind");
184
0
}
185
186
371
bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
187
371
  if (isa<ObjCInterfaceDecl>(D))
188
0
    return false;
189
371
  if (isa<ObjCCategoryDecl>(D))
190
0
    return false;
191
371
  if (isa<ObjCIvarDecl>(D))
192
0
    return false;
193
371
  if (isa<ObjCMethodDecl>(D))
194
85
    return false;
195
286
  if (isa<ImportDecl>(D))
196
40
    return false;
197
246
  return true;
198
286
}
199
200
static const CXXRecordDecl *
201
5
getDeclContextForTemplateInstationPattern(const Decl *D) {
202
5
  if (const auto *CTSD =
203
5
          dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
204
2
    return CTSD->getTemplateInstantiationPattern();
205
3
  else if (const auto *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()))
206
3
    return RD->getInstantiatedFromMemberClass();
207
0
  return nullptr;
208
5
}
209
210
54
static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
211
54
  if (const ClassTemplateSpecializationDecl *
212
54
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
213
29
    const auto *Template = SD->getTemplateInstantiationPattern();
214
29
    if (Template)
215
20
      return Template;
216
    // Fallback to primary template if no instantiation is available yet (e.g.
217
    // the type doesn't need to be complete).
218
9
    return SD->getSpecializedTemplate()->getTemplatedDecl();
219
29
  } else 
if (const FunctionDecl *25
FD25
= dyn_cast<FunctionDecl>(D)) {
220
7
    return FD->getTemplateInstantiationPattern();
221
18
  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
222
2
    return VD->getTemplateInstantiationPattern();
223
16
  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
224
8
    return RD->getInstantiatedFromMemberClass();
225
8
  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
226
2
    return ED->getInstantiatedFromMemberEnum();
227
6
  } else if (isa<FieldDecl>(D) || 
isa<TypedefNameDecl>(D)3
) {
228
5
    const auto *ND = cast<NamedDecl>(D);
229
5
    if (const CXXRecordDecl *Pattern =
230
5
            getDeclContextForTemplateInstationPattern(ND)) {
231
5
      for (const NamedDecl *BaseND : Pattern->lookup(ND->getDeclName())) {
232
5
        if (BaseND->isImplicit())
233
0
          continue;
234
5
        if (BaseND->getKind() == ND->getKind())
235
5
          return BaseND;
236
5
      }
237
5
    }
238
5
  } else 
if (const auto *1
ECD1
= dyn_cast<EnumConstantDecl>(D)) {
239
1
    if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
240
1
      if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
241
1
        for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
242
1
          return BaseECD;
243
1
      }
244
1
    }
245
1
  }
246
0
  return nullptr;
247
54
}
248
249
1.14k
static bool isDeclADefinition(const Decl *D, const DeclContext *ContainerDC, ASTContext &Ctx) {
250
1.14k
  if (auto VD = dyn_cast<VarDecl>(D))
251
130
    return VD->isThisDeclarationADefinition(Ctx);
252
253
1.01k
  if (auto FD = dyn_cast<FunctionDecl>(D))
254
254
    return FD->isThisDeclarationADefinition();
255
256
765
  if (auto TD = dyn_cast<TagDecl>(D))
257
224
    return TD->isThisDeclarationADefinition();
258
259
541
  if (auto MD = dyn_cast<ObjCMethodDecl>(D))
260
185
    return MD->isThisDeclarationADefinition() || 
isa<ObjCImplDecl>(ContainerDC)161
;
261
262
356
  if (isa<TypedefNameDecl>(D) ||
263
356
      
isa<EnumConstantDecl>(D)301
||
264
356
      
isa<FieldDecl>(D)284
||
265
356
      
isa<MSPropertyDecl>(D)216
||
266
356
      
isa<ObjCImplDecl>(D)215
||
267
356
      
isa<ObjCPropertyImplDecl>(D)192
)
268
186
    return true;
269
270
170
  return false;
271
356
}
272
273
/// Whether the given NamedDecl should be skipped because it has no name.
274
6.36k
static bool shouldSkipNamelessDecl(const NamedDecl *ND) {
275
6.36k
  return (ND->getDeclName().isEmpty() && 
!isa<TagDecl>(ND)38
&&
276
6.36k
          
!isa<ObjCCategoryDecl>(ND)25
) ||
isa<CXXDeductionGuideDecl>(ND)6.34k
;
277
6.36k
}
278
279
3.66k
static const Decl *adjustParent(const Decl *Parent) {
280
3.66k
  if (!Parent)
281
75
    return nullptr;
282
3.61k
  
for (;; 3.59k
Parent = cast<Decl>(Parent->getDeclContext())25
) {
283
3.61k
    if (isa<TranslationUnitDecl>(Parent))
284
514
      return nullptr;
285
3.10k
    if (isa<LinkageSpecDecl>(Parent) || 
isa<BlockDecl>(Parent)3.09k
)
286
6
      continue;
287
3.09k
    if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
288
87
      if (NS->isAnonymousNamespace())
289
0
        continue;
290
3.00k
    } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
291
330
      if (RD->isAnonymousStructOrUnion())
292
1
        continue;
293
2.67k
    } else if (auto ND = dyn_cast<NamedDecl>(Parent)) {
294
2.67k
      if (shouldSkipNamelessDecl(ND))
295
18
        continue;
296
2.67k
    }
297
3.07k
    return Parent;
298
3.09k
  }
299
3.59k
}
300
301
6.74k
static const Decl *getCanonicalDecl(const Decl *D) {
302
6.74k
  D = D->getCanonicalDecl();
303
6.74k
  if (auto TD = dyn_cast<TemplateDecl>(D)) {
304
69
    if (auto TTD = TD->getTemplatedDecl()) {
305
67
      D = TTD;
306
67
      assert(D->isCanonicalDecl());
307
67
    }
308
69
  }
309
310
0
  return D;
311
6.74k
}
312
313
static bool shouldReportOccurrenceForSystemDeclOnlyMode(
314
30
    bool IsRef, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) {
315
30
  if (!IsRef)
316
21
    return true;
317
318
9
  auto acceptForRelation = [](SymbolRoleSet roles) -> bool {
319
7
    bool accept = false;
320
7
    applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool {
321
7
      switch (r) {
322
0
      case SymbolRole::RelationChildOf:
323
6
      case SymbolRole::RelationBaseOf:
324
6
      case SymbolRole::RelationOverrideOf:
325
7
      case SymbolRole::RelationExtendedBy:
326
7
      case SymbolRole::RelationAccessorOf:
327
7
      case SymbolRole::RelationIBTypeOf:
328
7
        accept = true;
329
7
        return false;
330
0
      case SymbolRole::Declaration:
331
0
      case SymbolRole::Definition:
332
0
      case SymbolRole::Reference:
333
0
      case SymbolRole::Read:
334
0
      case SymbolRole::Write:
335
0
      case SymbolRole::Call:
336
0
      case SymbolRole::Dynamic:
337
0
      case SymbolRole::AddressOf:
338
0
      case SymbolRole::Implicit:
339
0
      case SymbolRole::Undefinition:
340
0
      case SymbolRole::RelationReceivedBy:
341
0
      case SymbolRole::RelationCalledBy:
342
0
      case SymbolRole::RelationContainedBy:
343
0
      case SymbolRole::RelationSpecializationOf:
344
0
      case SymbolRole::NameReference:
345
0
        return true;
346
7
      }
347
0
      llvm_unreachable("Unsupported SymbolRole value!");
348
0
    });
349
7
    return accept;
350
7
  };
351
352
9
  for (auto &Rel : Relations) {
353
7
    if (acceptForRelation(Rel.Roles))
354
7
      return true;
355
7
  }
356
357
2
  return false;
358
9
}
359
360
bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
361
                                           bool IsRef, const Decl *Parent,
362
                                           SymbolRoleSet Roles,
363
                                           ArrayRef<SymbolRelation> Relations,
364
                                           const Expr *OrigE,
365
                                           const Decl *OrigD,
366
3.78k
                                           const DeclContext *ContainerDC) {
367
3.78k
  if (D->isImplicit() && 
!isa<ObjCMethodDecl>(D)197
)
368
98
    return true;
369
3.69k
  if (!isa<NamedDecl>(D) || shouldSkipNamelessDecl(cast<NamedDecl>(D)))
370
9
    return true;
371
372
3.68k
  SourceManager &SM = Ctx->getSourceManager();
373
3.68k
  FileID FID = SM.getFileID(SM.getFileLoc(Loc));
374
3.68k
  if (FID.isInvalid())
375
12
    return true;
376
377
3.66k
  bool Invalid = false;
378
3.66k
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
379
3.66k
  if (Invalid || !SEntry.isFile())
380
0
    return true;
381
382
3.66k
  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
383
30
    switch (IndexOpts.SystemSymbolFilter) {
384
0
    case IndexingOptions::SystemSymbolFilterKind::None:
385
0
      return true;
386
30
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
387
30
      if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations))
388
2
        return true;
389
28
      break;
390
28
    case IndexingOptions::SystemSymbolFilterKind::All:
391
0
      break;
392
30
    }
393
30
  }
394
395
3.66k
  if (!OrigD)
396
2.51k
    OrigD = D;
397
398
3.66k
  if (isTemplateImplicitInstantiation(D)) {
399
55
    if (!IsRef)
400
1
      return true;
401
54
    D = adjustTemplateImplicitInstantiation(D);
402
54
    if (!D)
403
0
      return true;
404
54
    assert(!isTemplateImplicitInstantiation(D));
405
54
  }
406
407
3.66k
  if (IsRef)
408
2.51k
    Roles |= (unsigned)SymbolRole::Reference;
409
1.14k
  else if (isDeclADefinition(OrigD, ContainerDC, *Ctx))
410
703
    Roles |= (unsigned)SymbolRole::Definition;
411
446
  else
412
446
    Roles |= (unsigned)SymbolRole::Declaration;
413
414
3.66k
  D = getCanonicalDecl(D);
415
3.66k
  Parent = adjustParent(Parent);
416
3.66k
  if (Parent)
417
3.07k
    Parent = getCanonicalDecl(Parent);
418
419
3.66k
  SmallVector<SymbolRelation, 6> FinalRelations;
420
3.66k
  FinalRelations.reserve(Relations.size()+1);
421
422
5.18k
  auto addRelation = [&](SymbolRelation Rel) {
423
5.18k
    auto It = llvm::find_if(FinalRelations, [&](SymbolRelation Elem) -> bool {
424
2.08k
      return Elem.RelatedSymbol == Rel.RelatedSymbol;
425
2.08k
    });
426
5.18k
    if (It != FinalRelations.end()) {
427
1.90k
      It->Roles |= Rel.Roles;
428
3.28k
    } else {
429
3.28k
      FinalRelations.push_back(Rel);
430
3.28k
    }
431
5.18k
    Roles |= Rel.Roles;
432
5.18k
  };
433
434
3.66k
  if (Parent) {
435
3.07k
    if (IsRef || 
(639
!isa<ParmVarDecl>(D)639
&&
isFunctionLocalSymbol(D)614
)) {
436
2.45k
      addRelation(SymbolRelation{
437
2.45k
        (unsigned)SymbolRole::RelationContainedBy,
438
2.45k
        Parent
439
2.45k
      });
440
2.45k
    } else {
441
621
      addRelation(SymbolRelation{
442
621
        (unsigned)SymbolRole::RelationChildOf,
443
621
        Parent
444
621
      });
445
621
    }
446
3.07k
  }
447
448
3.66k
  for (auto &Rel : Relations) {
449
2.11k
    addRelation(SymbolRelation(Rel.Roles,
450
2.11k
                               Rel.RelatedSymbol->getCanonicalDecl()));
451
2.11k
  }
452
453
3.66k
  IndexDataConsumer::ASTNodeInfo Node{OrigE, OrigD, Parent, ContainerDC};
454
3.66k
  return DataConsumer.handleDeclOccurrence(D, Roles, FinalRelations, Loc, Node);
455
3.66k
}
456
457
void IndexingContext::handleMacroDefined(const IdentifierInfo &Name,
458
                                         SourceLocation Loc,
459
31.2k
                                         const MacroInfo &MI) {
460
31.2k
  if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc))
461
742
    return;
462
30.5k
  SymbolRoleSet Roles = (unsigned)SymbolRole::Definition;
463
30.5k
  DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
464
30.5k
}
465
466
void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name,
467
                                           SourceLocation Loc,
468
6
                                           const MacroInfo &MI) {
469
6
  if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc))
470
2
    return;
471
4
  SymbolRoleSet Roles = (unsigned)SymbolRole::Undefinition;
472
4
  DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
473
4
}
474
475
void IndexingContext::handleMacroReference(const IdentifierInfo &Name,
476
                                           SourceLocation Loc,
477
93
                                           const MacroInfo &MI) {
478
93
  if (!shouldIndexMacroOccurrence(/*IsRef=*/true, Loc))
479
16
    return;
480
77
  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
481
77
  DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
482
77
}
483
484
bool IndexingContext::shouldIndexMacroOccurrence(bool IsRef,
485
31.3k
                                                 SourceLocation Loc) {
486
31.3k
  if (!IndexOpts.IndexMacros)
487
758
    return false;
488
489
30.6k
  switch (IndexOpts.SystemSymbolFilter) {
490
0
  case IndexingOptions::SystemSymbolFilterKind::None:
491
0
    break;
492
30.6k
  case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
493
30.6k
    if (!IsRef)
494
30.5k
      return true;
495
79
    break;
496
79
  case IndexingOptions::SystemSymbolFilterKind::All:
497
0
    return true;
498
30.6k
  }
499
500
79
  SourceManager &SM = Ctx->getSourceManager();
501
79
  FileID FID = SM.getFileID(SM.getFileLoc(Loc));
502
79
  if (FID.isInvalid())
503
0
    return false;
504
505
79
  bool Invalid = false;
506
79
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
507
79
  if (Invalid || !SEntry.isFile())
508
0
    return false;
509
510
79
  return SEntry.getFile().getFileCharacteristic() == SrcMgr::C_User;
511
79
}