Skip to content

Commit d304f47

Browse files
feat: Support code nav for template parameters (#133)
1 parent 646b1bd commit d304f47

File tree

10 files changed

+178
-33
lines changed

10 files changed

+178
-33
lines changed

indexer/Indexer.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "clang/AST/ASTContext.h"
1313
#include "clang/AST/Decl.h"
1414
#include "clang/AST/DeclCXX.h"
15+
#include "clang/AST/DeclTemplate.h"
1516
#include "clang/AST/Expr.h"
1617
#include "clang/AST/RawCommentList.h"
1718
#include "clang/AST/TypeLoc.h"
@@ -28,6 +29,7 @@
2829
#include "indexer/Indexer.h"
2930
#include "indexer/Path.h"
3031
#include "indexer/ScipExtras.h"
32+
#include "indexer/SymbolFormatter.h"
3133

3234
namespace scip_clang {
3335

@@ -524,6 +526,52 @@ void TuIndexer::saveTagTypeLoc(const clang::TagTypeLoc &tagTypeLoc) {
524526
}
525527
}
526528

529+
#define SAVE_TEMPLATE_PARM(name_) \
530+
void TuIndexer::save##name_##Decl(const clang::name_##Decl &decl) { \
531+
if (auto optSymbol = this->symbolFormatter.get##name_##Symbol(decl)) { \
532+
this->saveDefinition(*optSymbol, decl.getLocation(), std::nullopt); \
533+
} \
534+
}
535+
FOR_EACH_TEMPLATE_PARM_TO_BE_INDEXED(SAVE_TEMPLATE_PARM)
536+
#undef SAVE_TEMPLATE_PARM
537+
538+
void TuIndexer::saveTemplateTypeParmTypeLoc(
539+
const clang::TemplateTypeParmTypeLoc &templateTypeParmTypeLoc) {
540+
if (auto optSymbol = this->symbolFormatter.getTemplateTypeParmSymbol(
541+
*templateTypeParmTypeLoc.getDecl())) {
542+
this->saveReference(*optSymbol, templateTypeParmTypeLoc.getNameLoc());
543+
}
544+
}
545+
546+
void TuIndexer::saveTemplateSpecializationTypeLoc(
547+
const clang::TemplateSpecializationTypeLoc &templateSpecializationTypeLoc) {
548+
auto *templateSpecializationType = templateSpecializationTypeLoc.getTypePtr();
549+
auto templateName = templateSpecializationType->getTemplateName();
550+
using Kind = clang::TemplateName::NameKind;
551+
switch (templateName.getKind()) {
552+
case Kind::Template: {
553+
if (auto *templateTemplateParmDecl =
554+
llvm::dyn_cast<clang::TemplateTemplateParmDecl>(
555+
templateName.getAsTemplateDecl())) {
556+
if (auto optSymbol = this->symbolFormatter.getTemplateTemplateParmSymbol(
557+
*templateTemplateParmDecl)) {
558+
this->saveReference(*optSymbol,
559+
templateSpecializationTypeLoc.getTemplateNameLoc());
560+
}
561+
}
562+
break;
563+
}
564+
case Kind::OverloadedTemplate:
565+
case Kind::AssumedTemplate:
566+
case Kind::QualifiedTemplate:
567+
case Kind::DependentTemplate:
568+
case Kind::SubstTemplateTemplateParm:
569+
case Kind::SubstTemplateTemplateParmPack:
570+
case Kind::UsingTemplate:
571+
break;
572+
}
573+
}
574+
527575
void TuIndexer::saveTypedefNameDecl(
528576
const clang::TypedefNameDecl &typedefNameDecl) {
529577
auto optSymbol = this->symbolFormatter.getNamedDeclSymbol(typedefNameDecl);

indexer/Indexer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828
#define FOR_EACH_TYPE_TO_BE_INDEXED(F) \
2929
F(Enum) \
30-
F(Record)
30+
F(Record) \
31+
F(TemplateSpecialization) \
32+
F(TemplateTypeParm)
3133

3234
namespace clang {
3335
#define FORWARD_DECLARE(DeclName) class DeclName##Decl;

indexer/SymbolFormatter.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "clang/AST/Decl.h"
1111
#include "clang/AST/DeclCXX.h"
12+
#include "clang/AST/DeclTemplate.h"
1213
#include "clang/Basic/SourceLocation.h"
1314
#include "clang/Basic/SourceManager.h"
1415
#include "llvm/Support/raw_ostream.h"
@@ -331,7 +332,10 @@ SymbolFormatter::getBindingSymbol(const clang::BindingDecl &bindingDecl) {
331332
}
332333

333334
std::optional<std::string_view>
334-
SymbolFormatter::getNextLocalSymbol(const clang::ValueDecl &decl) {
335+
SymbolFormatter::getNextLocalSymbol(const clang::NamedDecl &decl) {
336+
if (decl.getDeclName().isEmpty()) {
337+
return {};
338+
}
335339
return this->getSymbolCached(decl, [&]() -> std::optional<std::string> {
336340
auto loc = this->sourceManager.getExpansionLoc(decl.getLocation());
337341
auto defFileId = this->sourceManager.getFileID(loc);
@@ -467,12 +471,17 @@ SymbolFormatter::getNamespaceSymbol(const clang::NamespaceDecl &namespaceDecl) {
467471
std::optional<std::string_view>
468472
SymbolFormatter::getLocalVarOrParmSymbol(const clang::VarDecl &varDecl) {
469473
ENFORCE(varDecl.isLocalVarDeclOrParm());
470-
if (varDecl.getName().empty()) {
471-
return {};
472-
}
473474
return this->getNextLocalSymbol(varDecl);
474475
}
475476

477+
#define GET_AS_LOCAL(name_) \
478+
std::optional<std::string_view> SymbolFormatter::get##name_##Symbol( \
479+
const clang::name_##Decl &decl) { \
480+
return this->getNextLocalSymbol(decl); \
481+
}
482+
FOR_EACH_TEMPLATE_PARM_TO_BE_INDEXED(GET_AS_LOCAL)
483+
#undef GET_AS_LOCAL
484+
476485
std::optional<std::string_view> SymbolFormatter::getTypedefNameSymbol(
477486
const clang::TypedefNameDecl &typedefNameDecl) {
478487
return this->getSymbolCached(

indexer/SymbolFormatter.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@
2323
F(Field) \
2424
F(Function) \
2525
F(Namespace) \
26+
F(NonTypeTemplateParm) \
2627
F(Record) \
28+
F(TemplateTemplateParm) \
29+
F(TemplateTypeParm) \
2730
F(TypedefName) \
2831
F(Var)
2932

33+
#define FOR_EACH_TEMPLATE_PARM_TO_BE_INDEXED(F) \
34+
F(NonTypeTemplateParm) \
35+
F(TemplateTemplateParm) \
36+
F(TemplateTypeParm)
37+
3038
namespace clang {
3139
#define FORWARD_DECLARE(DeclName) class DeclName##Decl;
3240
FOR_EACH_DECL_TO_BE_INDEXED(FORWARD_DECLARE)
@@ -132,7 +140,7 @@ class SymbolFormatter final {
132140
getSymbolCached(const clang::Decl &,
133141
absl::FunctionRef<std::optional<std::string>()>);
134142

135-
std::optional<std::string_view> getNextLocalSymbol(const clang::ValueDecl &);
143+
std::optional<std::string_view> getNextLocalSymbol(const clang::NamedDecl &);
136144

137145
/// Format the string to a buffer stored by `this` and return a view to it.
138146
template <typename... T>

test/index/functions/ctors_dtors.snapshot.cc

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
11
// extra-args: -std=c++20
22

33
template<class T> struct remove_ref { typedef T type; };
4+
// ^ definition local 0
45
// ^^^^^^^^^^ definition [..] remove_ref#
6+
// ^ reference local 0
57
// ^^^^ definition [..] remove_ref#type#
68
template<class T> struct remove_ref<T&> { typedef T type; };
9+
// ^ definition local 1
710
// ^^^^^^^^^^ definition [..] remove_ref#
11+
// ^ reference local 1
12+
// ^ reference local 1
813
// ^^^^ definition [..] remove_ref#type#
914
template<class T> struct remove_ref<T&&> { typedef T type; };
15+
// ^ definition local 2
1016
// ^^^^^^^^^^ definition [..] remove_ref#
17+
// ^ reference local 2
18+
// ^ reference local 2
1119
// ^^^^ definition [..] remove_ref#type#
1220

1321
template <typename T>
22+
// ^ definition local 3
1423
typename remove_ref<T>::type&& move(T&& arg) {
1524
// ^^^^ definition [..] move(721d19cf58c53974).
16-
// ^^^ definition local 0
25+
// ^ reference local 3
26+
// ^^^ definition local 4
1727
return static_cast<typename remove_ref<T>::type&&>(arg);
18-
// ^^^ reference local 0
28+
// ^^^ reference local 4
1929
}
2030

2131
struct C {
@@ -55,68 +65,68 @@
5565
// ^^^^^^^^^^ definition [..] test_ctors(49f6e7a06ebc5aa8).
5666
C c0;
5767
// ^ reference [..] C#
58-
// ^^ definition local 1
68+
// ^^ definition local 5
5969
D d0;
6070
// ^ reference [..] D#
61-
// ^^ definition local 2
71+
// ^^ definition local 6
6272
C c1{};
6373
// ^ reference [..] C#
64-
// ^^ definition local 3
74+
// ^^ definition local 7
6575
D d1{};
6676
// ^ reference [..] D#
67-
// ^^ definition local 4
77+
// ^^ definition local 8
6878
C c2{0, 1};
6979
// ^ reference [..] C#
70-
// ^^ definition local 5
80+
// ^^ definition local 9
7181
// TODO: Figure out a minimal stub for std::initializer_list,
7282
// which we can use here, without running into Clang's
7383
// "cannot compile this weird std::initializer_list yet" error
7484
// D d2{0, 1};
7585
C c3{move(c1)};
7686
// ^ reference [..] C#
77-
// ^^ definition local 6
78-
// ^^ reference local 3
87+
// ^^ definition local 10
88+
// ^^ reference local 7
7989
D d3{move(d1)};
8090
// ^ reference [..] D#
81-
// ^^ definition local 7
82-
// ^^ reference local 4
91+
// ^^ definition local 11
92+
// ^^ reference local 8
8393

8494
C c4 = {};
8595
// ^ reference [..] C#
86-
// ^^ definition local 8
96+
// ^^ definition local 12
8797
D d4 = {};
8898
// ^ reference [..] D#
89-
// ^^ definition local 9
99+
// ^^ definition local 13
90100
C c5 = C();
91101
// ^ reference [..] C#
92-
// ^^ definition local 10
102+
// ^^ definition local 14
93103
// ^ reference [..] C#
94104
D d5 = D();
95105
// ^ reference [..] D#
96-
// ^^ definition local 11
106+
// ^^ definition local 15
97107
// ^ reference [..] D#
98108
C c6 = {0, 1};
99109
// ^ reference [..] C#
100-
// ^^ definition local 12
110+
// ^^ definition local 16
101111
// Uncomment after adding initializer_list
102112
// D d6 = {0, 1};
103113

104114
C c7 = {.x = 0};
105115
// ^ reference [..] C#
106-
// ^^ definition local 13
116+
// ^^ definition local 17
107117
C c8 = {.x = 0, .y = 1};
108118
// ^ reference [..] C#
109-
// ^^ definition local 14
119+
// ^^ definition local 18
110120
C c9 = C{0, 1};
111121
// ^ reference [..] C#
112-
// ^^ definition local 15
122+
// ^^ definition local 19
113123
// ^ reference [..] C#
114124
C c10 = move(c1);
115125
// ^ reference [..] C#
116-
// ^^^ definition local 16
117-
// ^^ reference local 3
126+
// ^^^ definition local 20
127+
// ^^ reference local 7
118128
D d10 = move(d1);
119129
// ^ reference [..] D#
120-
// ^^^ definition local 17
121-
// ^^ reference local 4
130+
// ^^^ definition local 21
131+
// ^^ reference local 8
122132
}

test/index/functions/operators.snapshot.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@
271271

272272
template <A a> // since C++20
273273
// ^ reference [..] A#
274+
// ^ definition local 25
274275
void operator ""_a_op() { return; }
275276
// ^^^^^^^^ definition [..] `operator""_a_op`(49f6e7a06ebc5aa8).
276277

test/index/types/bad_tagdecl.snapshot.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,32 @@
1010
// See NOTE(def: missing-definition-for-tagdecl)
1111

1212
template<bool B, class T = void>
13+
// ^ definition local 0
14+
// ^ definition local 1
1315
struct enable_if {};
1416
// ^^^^^^^^^ definition [..] enable_if#
1517

1618
template<class T>
19+
// ^ definition local 2
1720
struct enable_if<true, T> { typedef T type; };
1821
// ^^^^^^^^^ definition [..] enable_if#
22+
// ^ reference local 2
23+
// ^ reference local 2
1924
// ^^^^ definition [..] enable_if#type#
2025

2126
template< bool B, class T = void >
27+
// ^ definition local 3
28+
// ^ definition local 4
2229
using enable_if_t = typename enable_if<B,T>::type;
2330
// ^^^^^^^^^^^ definition [..] enable_if_t#
2431

2532
template <typename T, typename Enable = void> struct MyTemplate { };
33+
// ^ definition local 5
34+
// ^^^^^^ definition local 6
2635
// ^^^^^^^^^^ definition [..] MyTemplate#
2736

2837
template <class T>
38+
// ^ definition local 7
2939
struct ShouldEnable { static bool const value = false; };
3040
// ^^^^^^^^^^^^ definition [..] ShouldEnable#
3141
// ^^^^^ definition [..] ShouldEnable#value.

test/index/types/templates.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// extra-args: -std=c++17
2+
3+
template <typename ...Args>
4+
struct S0 {
5+
void f(Args... args) {}
6+
};
7+
8+
template <typename A, typename B, template <typename> typename F>
9+
F<B> fmap(A f(B), F<A> fa) {
10+
return fa.fmap(f);
11+
}
12+
13+
template <int N>
14+
void f(int arr[N]) {}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// extra-args: -std=c++17
2+
3+
template <typename ...Args>
4+
// ^^^^ definition local 0
5+
struct S0 {
6+
// ^^ definition [..] S0#
7+
void f(Args... args) {}
8+
// ^ definition [..] S0#f(f327490b5edb0dcb).
9+
// ^^^^ reference local 0
10+
// ^^^^ definition local 1
11+
};
12+
13+
template <typename A, typename B, template <typename> typename F>
14+
// ^ definition local 2
15+
// ^ definition local 3
16+
// ^ definition local 4
17+
F<B> fmap(A f(B), F<A> fa) {
18+
//^ reference local 4
19+
// ^ reference local 3
20+
// ^^^^ definition [..] fmap(48b319d339a486cb).
21+
// ^ reference local 2
22+
// ^ definition local 5
23+
// ^ reference local 3
24+
// ^ reference local 4
25+
// ^ reference local 2
26+
// ^^ definition local 6
27+
return fa.fmap(f);
28+
// ^^ reference local 6
29+
// ^ reference local 5
30+
}
31+
32+
template <int N>
33+
// ^ definition local 7
34+
void f(int arr[N]) {}
35+
// ^ definition [..] f(11b0e290e57a7e53).
36+
// ^^^ definition local 8
37+
// ^ reference local 7

0 commit comments

Comments
 (0)