@@ -256,28 +256,96 @@ std::optional<SymbolString> SymbolFormatter::getSymbolCached(
256
256
}
257
257
ENFORCE (!optSymbol.value ().empty (),
258
258
" forgot to use nullopt to signal failure in computing symbol name" );
259
- auto [newIt, inserted] = this -> declBasedCache . insert (
260
- {canonicalDecl, std::move ( optSymbol. value ()) });
259
+ auto [newIt, inserted] =
260
+ this -> declBasedCache . insert ( {canonicalDecl, * optSymbol});
261
261
ENFORCE (inserted);
262
262
return std::string_view (newIt->second );
263
263
}
264
264
265
- std::optional<SymbolString>
266
- SymbolFormatter::getContextSymbol (const clang::DeclContext &declContext) {
265
+ std::optional<std::string_view> SymbolFormatter::getSymbolCached (
266
+ const clang::Decl *decl, clang::SourceLocation loc,
267
+ absl::FunctionRef<std::optional<SymbolString>()> getSymbol) {
268
+ auto fileId = this ->sourceManager .getFileID (loc);
269
+ if (decl) {
270
+ decl = decl->getCanonicalDecl ();
271
+ }
272
+ using KeyType =
273
+ std::pair<const clang::Decl *, llvm_ext::AbslHashAdapter<clang::FileID>>;
274
+ auto it = this ->namespacePrefixCache .find (KeyType{decl, {fileId}});
275
+ if (it != this ->namespacePrefixCache .end ()) {
276
+ return std::string_view (it->second );
277
+ }
278
+ auto optSymbol = getSymbol ();
279
+ if (!optSymbol.has_value ()) {
280
+ return {};
281
+ }
282
+ ENFORCE (!optSymbol.value ().empty (),
283
+ " forgot to use nullopt to signal failure in compute symbol name" );
284
+ auto [newIt, inserted] =
285
+ this ->namespacePrefixCache .emplace (KeyType{decl, {fileId}}, *optSymbol);
286
+ ENFORCE (inserted);
287
+ return std::string_view (newIt->second );
288
+ }
289
+
290
+ std::optional<std::string_view> SymbolFormatter::getNamespaceSymbolPrefix (
291
+ const clang::NamespaceDecl &namespaceDecl, clang::SourceLocation loc) {
292
+ return this ->getSymbolCached (
293
+ &namespaceDecl, loc, [&]() -> std::optional<SymbolString> {
294
+ auto optContextSymbol =
295
+ this ->getContextSymbol (*namespaceDecl.getDeclContext (), loc);
296
+ if (!optContextSymbol.has_value ()) {
297
+ return {};
298
+ }
299
+ auto contextSymbol = optContextSymbol.value ();
300
+ DescriptorBuilder descriptor{.suffix = scip::Descriptor::Namespace};
301
+ if (namespaceDecl.isAnonymousNamespace ()) {
302
+ auto mainFileId = this ->sourceManager .getMainFileID ();
303
+ ENFORCE (mainFileId.isValid ());
304
+ auto optStableFileId =
305
+ this ->fileMetadataMap .getStableFileId (mainFileId);
306
+ ENFORCE (optStableFileId.has_value (),
307
+ " main file always has a valid StableFileId" );
308
+ auto path = optStableFileId->path ;
309
+ descriptor.name = this ->formatTemporaryName (" $anonymous_namespace_{}" ,
310
+ path.asStringView ());
311
+ } else {
312
+ descriptor.name = this ->formatTemporaryName (namespaceDecl);
313
+ }
314
+ return this ->formatContextual (contextSymbol, descriptor);
315
+ });
316
+ }
317
+
318
+ std::optional<std::string_view>
319
+ SymbolFormatter::getLocationBasedSymbolPrefix (clang::SourceLocation loc) {
320
+ if (loc.isInvalid ()) {
321
+ return {};
322
+ }
323
+ return this ->getSymbolCached (
324
+ nullptr , loc, [&]() -> std::optional<SymbolString> {
325
+ auto fileId = this ->sourceManager .getFileID (loc);
326
+ auto *fileMetadata = this ->fileMetadataMap .getFileMetadata (fileId);
327
+ if (!fileMetadata) {
328
+ return {};
329
+ }
330
+ auto packageId = fileMetadata->packageId ();
331
+ return this ->format (SymbolBuilder{packageId, /* descriptors*/ {}});
332
+ });
333
+ }
334
+
335
+ std::optional<std::string_view>
336
+ SymbolFormatter::getContextSymbol (const clang::DeclContext &declContext,
337
+ clang::SourceLocation loc) {
338
+ loc = this ->sourceManager .getExpansionLoc (loc);
267
339
if (auto *namespaceDecl =
268
340
llvm::dyn_cast<clang::NamespaceDecl>(&declContext)) {
269
- return this ->getNamespaceSymbol (*namespaceDecl);
341
+ return this ->getNamespaceSymbolPrefix (*namespaceDecl, loc );
270
342
}
271
343
if (auto *tagDecl = llvm::dyn_cast<clang::TagDecl>(&declContext)) {
272
344
return this ->getTagSymbol (*tagDecl);
273
345
}
274
- if (llvm::isa<clang::TranslationUnitDecl>(declContext)
275
- || llvm::isa<clang::ExternCContextDecl>(declContext)) {
276
- auto decl = llvm::dyn_cast<clang::Decl>(&declContext);
277
- return this ->getSymbolCached (*decl, [&]() -> std::optional<SymbolString> {
278
- // TODO: Retrieve the correct PackageId and use that here
279
- return this ->format (SymbolBuilder{{" " , " " }, {}});
280
- });
346
+ if (llvm::isa<clang::TranslationUnitDecl>(&declContext)
347
+ || llvm::isa<clang::ExternCContextDecl>(&declContext)) {
348
+ return this ->getLocationBasedSymbolPrefix (loc);
281
349
}
282
350
if (auto *functionDecl = llvm::dyn_cast<clang::FunctionDecl>(&declContext)) {
283
351
// TODO: Strictly speaking, we should return some information marking
@@ -312,7 +380,8 @@ SymbolFormatter::getRecordSymbol(const clang::RecordDecl &recordDecl) {
312
380
std::optional<SymbolString>
313
381
SymbolFormatter::getTagSymbol (const clang::TagDecl &tagDecl) {
314
382
return this ->getSymbolCached (tagDecl, [&]() -> std::optional<SymbolString> {
315
- auto optContextSymbol = this ->getContextSymbol (*tagDecl.getDeclContext ());
383
+ auto optContextSymbol = this ->getContextSymbol (*tagDecl.getDeclContext (),
384
+ tagDecl.getLocation ());
316
385
if (!optContextSymbol.has_value ()) {
317
386
return {};
318
387
}
@@ -323,6 +392,7 @@ SymbolFormatter::getTagSymbol(const clang::TagDecl &tagDecl) {
323
392
DescriptorBuilder{.name = this ->formatTemporaryName (tagDecl),
324
393
.suffix = scip::Descriptor::Type});
325
394
}
395
+
326
396
auto *definitionTagDecl = tagDecl.getDefinition ();
327
397
if (!definitionTagDecl) {
328
398
// NOTE(def: missing-definition-for-tagdecl)
@@ -412,7 +482,8 @@ std::optional<SymbolString> SymbolFormatter::getEnumConstantSymbol(
412
482
std::optional<SymbolString> optContextSymbol =
413
483
parentEnumDecl->isScoped ()
414
484
? this ->getEnumSymbol (*parentEnumDecl)
415
- : this ->getContextSymbol (*parentEnumDecl->getDeclContext ());
485
+ : this ->getContextSymbol (*parentEnumDecl->getDeclContext (),
486
+ enumConstantDecl.getLocation ());
416
487
if (!optContextSymbol.has_value ()) {
417
488
return {};
418
489
}
@@ -468,8 +539,8 @@ std::optional<SymbolString>
468
539
SymbolFormatter::getFunctionSymbol (const clang::FunctionDecl &functionDecl) {
469
540
return this ->getSymbolCached (
470
541
functionDecl, [&]() -> std::optional<SymbolString> {
471
- auto optContextSymbol =
472
- this -> getContextSymbol ( *functionDecl.getDeclContext ());
542
+ auto optContextSymbol = this -> getContextSymbol (
543
+ *functionDecl.getDeclContext (), functionDecl. getLocation ());
473
544
if (!optContextSymbol.has_value ()) {
474
545
return {};
475
546
}
@@ -496,7 +567,8 @@ SymbolFormatter::getFieldSymbol(const clang::FieldDecl &fieldDecl) {
496
567
return {};
497
568
}
498
569
return this ->getSymbolCached (fieldDecl, [&]() -> std::optional<SymbolString> {
499
- auto optContextSymbol = this ->getContextSymbol (*fieldDecl.getDeclContext ());
570
+ auto optContextSymbol = this ->getContextSymbol (*fieldDecl.getDeclContext (),
571
+ fieldDecl.getLocation ());
500
572
if (!optContextSymbol.has_value ()) {
501
573
return {};
502
574
}
@@ -523,30 +595,8 @@ SymbolFormatter::getNamedDeclSymbol(const clang::NamedDecl &namedDecl) {
523
595
// / getCanonicalPath returns nullopt.
524
596
std::optional<SymbolString>
525
597
SymbolFormatter::getNamespaceSymbol (const clang::NamespaceDecl &namespaceDecl) {
526
- return this ->getSymbolCached (
527
- namespaceDecl, [&]() -> std::optional<SymbolString> {
528
- auto optContextSymbol =
529
- this ->getContextSymbol (*namespaceDecl.getDeclContext ());
530
- if (!optContextSymbol.has_value ()) {
531
- return {};
532
- }
533
- auto contextSymbol = optContextSymbol.value ();
534
- DescriptorBuilder descriptor{.suffix = scip::Descriptor::Namespace};
535
- if (namespaceDecl.isAnonymousNamespace ()) {
536
- auto mainFileId = this ->sourceManager .getMainFileID ();
537
- ENFORCE (mainFileId.isValid ());
538
- auto optStableFileId =
539
- this ->fileMetadataMap .getStableFileId (mainFileId);
540
- ENFORCE (optStableFileId.has_value (),
541
- " main file always has a valid StableFileId" );
542
- auto path = optStableFileId->path ;
543
- descriptor.name = this ->formatTemporaryName (" $anonymous_namespace_{}" ,
544
- path.asStringView ());
545
- } else {
546
- descriptor.name = this ->formatTemporaryName (namespaceDecl);
547
- }
548
- return this ->formatContextual (contextSymbol, descriptor);
549
- });
598
+ return this ->getNamespaceSymbolPrefix (namespaceDecl,
599
+ namespaceDecl.getLocation ());
550
600
}
551
601
552
602
std::optional<SymbolString>
@@ -567,8 +617,8 @@ std::optional<SymbolString> SymbolFormatter::getTypedefNameSymbol(
567
617
const clang::TypedefNameDecl &typedefNameDecl) {
568
618
return this ->getSymbolCached (
569
619
typedefNameDecl, [&]() -> std::optional<SymbolString> {
570
- auto optContextSymbol =
571
- this -> getContextSymbol ( *typedefNameDecl.getDeclContext ());
620
+ auto optContextSymbol = this -> getContextSymbol (
621
+ *typedefNameDecl.getDeclContext (), typedefNameDecl. getLocation ());
572
622
if (!optContextSymbol.has_value ()) {
573
623
return {};
574
624
}
@@ -592,8 +642,8 @@ std::optional<SymbolString> SymbolFormatter::getUsingShadowSymbol(
592
642
}
593
643
return this ->getSymbolCached (
594
644
usingShadowDecl, [&]() -> std::optional<SymbolString> {
595
- auto optContextSymbol =
596
- this -> getContextSymbol ( *usingShadowDecl.getDeclContext ());
645
+ auto optContextSymbol = this -> getContextSymbol (
646
+ *usingShadowDecl.getDeclContext (), usingShadowDecl. getLocation ());
597
647
if (!optContextSymbol) {
598
648
return {};
599
649
}
@@ -669,8 +719,8 @@ SymbolFormatter::getVarSymbol(const clang::VarDecl &varDecl) {
669
719
case Kind::VarTemplatePartialSpecialization:
670
720
case Kind::VarTemplateSpecialization:
671
721
case Kind::Var: {
672
- if (auto optContextSymbol =
673
- this -> getContextSymbol ( *varDecl.getDeclContext ())) {
722
+ if (auto optContextSymbol = this -> getContextSymbol (
723
+ *varDecl.getDeclContext (), varDecl. getLocation ())) {
674
724
auto descriptor = DescriptorBuilder{
675
725
.name = llvm_ext::toStringView (varDecl.getName ()),
676
726
.suffix = scip::Descriptor::Term,
0 commit comments