@@ -403,6 +403,41 @@ SymbolFormatter::getEnumSymbol(const clang::EnumDecl &enumDecl) {
403
403
return this ->getTagSymbol (enumDecl);
404
404
}
405
405
406
+ std::string_view SymbolFormatter::getFunctionDisambiguator (
407
+ const clang::FunctionDecl &functionDecl, char buf[16 ]) {
408
+ const clang::FunctionDecl *definingDecl = &functionDecl;
409
+ // clang-format off
410
+ if (functionDecl.isTemplateInstantiation ()) {
411
+ // Handle non-templated member functions
412
+ if (auto *memberFnDecl = functionDecl.getInstantiatedFromMemberFunction ()) {
413
+ definingDecl = memberFnDecl;
414
+ } else if (auto *templateInfo = functionDecl.getTemplateSpecializationInfo ()) {
415
+ // Consider code like:
416
+ // template <typename T> class C { template <typename U> void f() {} };
417
+ // void g() { C<int>().f<int>(); }
418
+ // ^ Emitting a reference
419
+ //
420
+ // The dance below gets to the original declaration in 3 steps:
421
+ // C<int>.f<int> (FunctionDecl) → C<int>.f<$U> (FunctionTemplateDecl)
422
+ // ↓
423
+ // C<$T>.f<$U> (FunctionDecl) ← C<$T>.f<$U> (FunctionTemplateDecl)
424
+ auto *instantiatedTemplateDecl = templateInfo->getTemplate ();
425
+ // For some reason, we end up on this code path for overloaded
426
+ // literal operators. In that case, uninstantiatedTemplateDecl
427
+ // can be null.
428
+ if (auto *uninstantiatedTemplateDecl = instantiatedTemplateDecl->getInstantiatedFromMemberTemplate ()) {
429
+ definingDecl = uninstantiatedTemplateDecl->getTemplatedDecl ();
430
+ }
431
+ }
432
+ }
433
+ // clang-format on
434
+ // 64-bit hash in hex should take 16 characters at most.
435
+ auto typeString = definingDecl->getType ().getCanonicalType ().getAsString ();
436
+ // char buf[16] = {0};
437
+ auto *end = fmt::format_to (buf, " {:x}" , HashValue::forText (typeString));
438
+ return std::string_view{buf, end};
439
+ }
440
+
406
441
std::optional<std::string_view>
407
442
SymbolFormatter::getFunctionSymbol (const clang::FunctionDecl &functionDecl) {
408
443
return this ->getSymbolCached (
@@ -412,39 +447,9 @@ SymbolFormatter::getFunctionSymbol(const clang::FunctionDecl &functionDecl) {
412
447
if (!optContextSymbol.has_value ()) {
413
448
return {};
414
449
}
415
- const clang::FunctionDecl *definingDecl = &functionDecl;
416
- // clang-format off
417
- if (functionDecl.isTemplateInstantiation ()) {
418
- // Handle non-templated member functions
419
- if (auto *memberFnDecl = functionDecl.getInstantiatedFromMemberFunction ()) {
420
- definingDecl = memberFnDecl;
421
- } else if (auto *templateInfo = functionDecl.getTemplateSpecializationInfo ()) {
422
- // Consider code like:
423
- // template <typename T> class C { template <typename U> void f() {} };
424
- // void g() { C<int>().f<int>(); }
425
- // ^ Emitting a reference
426
- //
427
- // The dance below gets to the original declaration in 3 steps:
428
- // C<int>.f<int> (FunctionDecl) → C<int>.f<$U> (FunctionTemplateDecl)
429
- // ↓
430
- // C<$T>.f<$U> (FunctionDecl) ← C<$T>.f<$U> (FunctionTemplateDecl)
431
- auto *instantiatedTemplateDecl = templateInfo->getTemplate ();
432
- // For some reason, we end up on this code path for overloaded
433
- // literal operators. In that case, uninstantiatedTemplateDecl
434
- // can be null.
435
- if (auto *uninstantiatedTemplateDecl = instantiatedTemplateDecl->getInstantiatedFromMemberTemplate ()) {
436
- definingDecl = uninstantiatedTemplateDecl->getTemplatedDecl ();
437
- }
438
- }
439
- }
440
- // clang-format on
441
450
auto name = this ->formatTemporary (functionDecl);
442
- // 64-bit hash in hex should take 16 characters at most.
443
- auto typeString =
444
- definingDecl->getType ().getCanonicalType ().getAsString ();
445
451
char buf[16 ] = {0 };
446
- auto *end = fmt::format_to (buf, " {:x}" , HashValue::forText (typeString));
447
- std::string_view disambiguator{buf, end};
452
+ auto disambiguator = this ->getFunctionDisambiguator (functionDecl, buf);
448
453
return SymbolBuilder::formatContextual (
449
454
optContextSymbol.value (), DescriptorBuilder{
450
455
.name = name,
@@ -566,6 +571,8 @@ std::optional<std::string_view> SymbolFormatter::getUsingShadowSymbol(
566
571
return {};
567
572
}
568
573
scip::Descriptor::Suffix suffix;
574
+ char buf[16 ] = {0 };
575
+ std::string_view disambiguator = " " ;
569
576
// NOTE: First two branches can't be re-ordered as all
570
577
// TemplateTypeParmDecls also TypeDecls
571
578
if (llvm::dyn_cast<clang::TemplateTypeParmDecl>(canonicalDecl)) {
@@ -577,13 +584,16 @@ std::optional<std::string_view> SymbolFormatter::getUsingShadowSymbol(
577
584
} else if (llvm::dyn_cast<clang::EnumConstantDecl>(canonicalDecl)
578
585
|| llvm::dyn_cast<clang::FieldDecl>(canonicalDecl)) {
579
586
suffix = scip::Descriptor::Term;
580
- } else if (llvm::dyn_cast<clang::FunctionDecl>(canonicalDecl)) {
587
+ } else if (auto *functionDecl =
588
+ llvm::dyn_cast<clang::FunctionDecl>(canonicalDecl)) {
589
+ disambiguator = this ->getFunctionDisambiguator (*functionDecl, buf);
581
590
suffix = scip::Descriptor::Method;
582
591
} else {
583
592
return {};
584
593
}
585
594
auto descriptor = DescriptorBuilder{
586
595
.name = this ->formatTemporary (usingShadowDecl),
596
+ .disambiguator = disambiguator,
587
597
.suffix = suffix,
588
598
};
589
599
return SymbolBuilder::formatContextual (*optContextSymbol, descriptor);
0 commit comments