Coverage Report

Created: 2023-09-21 18:56

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