From d43f75b54a246af10febebaa03169be9aa9d08ad Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Fri, 12 May 2017 16:32:26 +0000 Subject: [PATCH] [index] Index template specialization arguments for function templats Also ensure that class template specialization arguments are covered rdar://31812032 llvm-svn: 302918 --- clang/lib/Index/IndexDecl.cpp | 22 ++++++++++++++++++++++ clang/test/Index/Core/index-source.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index 7de70a1..e55dea8 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -52,6 +52,22 @@ public: return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition(); } + void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc, + const NamedDecl *Parent, + const DeclContext *DC) { + const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo(); + switch (TALoc.getArgument().getKind()) { + case TemplateArgument::Expression: + IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC); + break; + case TemplateArgument::Type: + IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC); + break; + default: + break; + } + } + void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = nullptr, bool isIBType = false) { @@ -233,6 +249,12 @@ public: Dtor->getParent(), Dtor->getDeclContext()); } } + // Template specialization arguments. + if (const ASTTemplateArgumentListInfo *TemplateArgInfo = + D->getTemplateSpecializationArgsAsWritten()) { + for (const auto &Arg : TemplateArgInfo->arguments()) + handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext()); + } if (D->isThisDeclarationADefinition()) { const Stmt *Body = D->getBody(); diff --git a/clang/test/Index/Core/index-source.cpp b/clang/test/Index/Core/index-source.cpp index 6f90261..cae7508 100644 --- a/clang/test/Index/Core/index-source.cpp +++ b/clang/test/Index/Core/index-source.cpp @@ -287,3 +287,30 @@ class PartialSpecilizationClass : Cls { }; // CHECK-NEXT: [[@LINE-5]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | | Ref | rel: 0 // CHECK-NEXT: [[@LINE-6]]:33 | class/C++ | Cls | c:@S@Cls | | Ref | rel: 0 // CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | | Ref | rel: 0 + +template +void functionSp() { } + +struct Record { + constexpr static int C = 2; +}; + +template<> +void functionSp, Record::C>() { +// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSp | c:@F@functionSp<#$@S@SpecializationDecl>#$@S@Cls#VI2># | __Z10functionSpI18SpecializationDeclI3ClsELi2EEvv | Def,RelSpecialization | rel: 1 +// CHECK: RelSpecialization | functionSp | c:@FT@>2#T#NIfunctionSp#v# +// CHECK: [[@LINE-3]]:17 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | | Ref,RelCont | rel: 1 +// CHECK: [[@LINE-4]]:36 | class/C++ | Cls | c:@S@Cls | | Ref,RelCont | rel: 1 +// CHECK: [[@LINE-5]]:50 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,RelCont | rel: 1 +// CHECK: [[@LINE-6]]:42 | struct/C++ | Record | c:@S@Record | | Ref,RelCont | rel: 1 +} + +template +class ClassWithCorrectSpecialization { }; + +template<> +class ClassWithCorrectSpecialization, Record::C> { }; +// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | | Ref | rel: 0 +// CHECK: [[@LINE-2]]:57 | class/C++ | Cls | c:@S@Cls | | Ref | rel: 0 +// CHECK: [[@LINE-3]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read | rel: 0 +// CHECK: [[@LINE-4]]:63 | struct/C++ | Record | c:@S@Record | | Ref | rel: 0 -- 2.7.4