@@ -386,7 +386,7 @@ void ForwardDeclMap::emit(bool deterministic, scip::ForwardDeclIndex &index) {
386386
387387TuIndexer::TuIndexer (const clang::SourceManager &sourceManager,
388388 const clang::LangOptions &langOptions,
389- const clang::ASTContext &astContext,
389+ clang::ASTContext &astContext,
390390 const FileIdsToBeIndexedSet &fileIdsToBeIndexed,
391391 SymbolFormatter &symbolFormatter,
392392 FileMetadataMap &fileMetadataMap)
@@ -530,7 +530,8 @@ void TuIndexer::saveFunctionDecl(const clang::FunctionDecl &functionDecl) {
530530 }
531531 auto symbol = optSymbol.value ();
532532
533- if (functionDecl.isPure () || functionDecl.isThisDeclarationADefinition ()) {
533+ if (functionDecl.isPureVirtual ()
534+ || functionDecl.isThisDeclarationADefinition ()) {
534535 scip::SymbolInformation symbolInfo{};
535536 this ->getDocComment (functionDecl).addTo (symbolInfo);
536537 if (auto *cxxMethodDecl =
@@ -671,33 +672,6 @@ void TuIndexer::saveNestedNameSpecifierLoc(
671672 case Kind::NamespaceAlias:
672673 case Kind::Global:
673674 case Kind::Super:
674- case Kind::TypeSpecWithTemplate:
675- // FIXME(def: template-specialization-support)
676- // Adding support for TypeSpecWithTemplate needs extra care
677- // for (partial) template specializations. Example code:
678- //
679- // template <typename T0>
680- // struct X {
681- // template <typename T1>
682- // struct Y {};
683- // };
684- //
685- // template <>
686- // struct X {
687- // template <typename A>
688- // struct Y { int[42] magic; };
689- // };
690- //
691- // template <typename U0> void f() {
692- // typename X<U0>::template Y<U0> y{};
693- // //^^^^^^^^^^^^^^ TypeSpecWithTemplate
694- // std::cout << sizeof(y) << '\n';
695- // }
696- //
697- // In 'template Y<U0>', clangd will navigate to 'Y' in the body of 'X',
698- // even when there is partial template specialization of X
699- // (so calling f<int>() will print a different value).
700- // Ideally, we should surface such specializations too.
701675 break ;
702676 }
703677 nameSpecLoc = nameSpecLoc.getPrefix ();
@@ -834,6 +808,17 @@ void TuIndexer::saveTemplateSpecializationTypeLoc(
834808 const clang::TemplateSpecializationTypeLoc &templateSpecializationTypeLoc) {
835809 auto *templateSpecializationType = templateSpecializationTypeLoc.getTypePtr ();
836810 auto templateName = templateSpecializationType->getTemplateName ();
811+
812+ // Unwrap QualifiedTemplateName and DeducedTemplateStorage to get the
813+ // underlying template. These wrappers preserve source-level qualifications
814+ // but we need the actual template declaration for indexing.
815+ if (auto *qualifiedName = templateName.getAsQualifiedTemplateName ()) {
816+ templateName = qualifiedName->getUnderlyingTemplate ();
817+ }
818+ if (auto *deducedStorage = templateName.getAsDeducedTemplateName ()) {
819+ templateName = deducedStorage->getUnderlying ();
820+ }
821+
837822 using Kind = clang::TemplateName::NameKind;
838823 switch (templateName.getKind ()) {
839824 case Kind::Template: {
@@ -871,6 +856,7 @@ void TuIndexer::saveTemplateSpecializationTypeLoc(
871856 case Kind::OverloadedTemplate:
872857 case Kind::AssumedTemplate:
873858 case Kind::QualifiedTemplate:
859+ case Kind::DeducedTemplate:
874860 case Kind::DependentTemplate:
875861 case Kind::SubstTemplateTemplateParm:
876862 case Kind::SubstTemplateTemplateParmPack:
0 commit comments