[clang][Index] Enable indexing of Template Type Parameters behind a flag
Summary: clangd uses indexing api to provide references and it was not possible to perform symbol information for template parameters. This patch enables visiting of TemplateTypeParmTypeLocs. Reviewers: ilya-biryukov, akyrtzi Subscribers: javed.absar, kristof.beyls, ioeric, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58293 llvm-svn: 354560
This commit is contained in:
parent
b672602f9e
commit
b780517ca5
|
@ -46,6 +46,7 @@ struct IndexingOptions {
|
|||
bool IndexMacrosInPreprocessor = false;
|
||||
// Has no effect if IndexFunctionLocals are false.
|
||||
bool IndexParametersInDeclarations = false;
|
||||
bool IndexTemplateParameters = false;
|
||||
};
|
||||
|
||||
/// Creates a frontend action that indexes all symbols (macros and AST decls).
|
||||
|
|
|
@ -672,6 +672,8 @@ public:
|
|||
shouldIndexTemplateParameterDefaultValue(Parent)) {
|
||||
const TemplateParameterList *Params = D->getTemplateParameters();
|
||||
for (const NamedDecl *TP : *Params) {
|
||||
if (IndexCtx.shouldIndexTemplateParameters())
|
||||
IndexCtx.handleDecl(TP);
|
||||
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
|
||||
if (TTP->hasDefaultArgument())
|
||||
IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
|
||||
|
|
|
@ -55,9 +55,6 @@ bool index::isFunctionLocalSymbol(const Decl *D) {
|
|||
if (isa<ParmVarDecl>(D))
|
||||
return true;
|
||||
|
||||
if (isa<TemplateTemplateParmDecl>(D))
|
||||
return true;
|
||||
|
||||
if (isa<ObjCTypeParamDecl>(D))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -45,6 +45,13 @@ public:
|
|||
return false; \
|
||||
} while (0)
|
||||
|
||||
bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) {
|
||||
SourceLocation Loc = TTPL.getNameLoc();
|
||||
TemplateTypeParmDecl *TTPD = TTPL.getDecl();
|
||||
return IndexCtx.handleReference(TTPD, Loc, Parent, ParentDC,
|
||||
SymbolRoleSet());
|
||||
}
|
||||
|
||||
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
|
||||
SourceLocation Loc = TL.getNameLoc();
|
||||
TypedefNameDecl *ND = TL.getTypedefNameDecl();
|
||||
|
|
|
@ -44,6 +44,10 @@ bool IndexingContext::shouldIndexParametersInDeclarations() const {
|
|||
return IndexOpts.IndexParametersInDeclarations;
|
||||
}
|
||||
|
||||
bool IndexingContext::shouldIndexTemplateParameters() const {
|
||||
return IndexOpts.IndexTemplateParameters;
|
||||
}
|
||||
|
||||
bool IndexingContext::handleDecl(const Decl *D,
|
||||
SymbolRoleSet Roles,
|
||||
ArrayRef<SymbolRelation> Relations) {
|
||||
|
@ -76,8 +80,11 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
|
|||
if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
|
||||
return true;
|
||||
|
||||
if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
|
||||
if (!shouldIndexTemplateParameters() &&
|
||||
(isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
|
||||
isa<TemplateTemplateParmDecl>(D))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
|
||||
RefE, RefD, DC);
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
|
||||
bool shouldIndexParametersInDeclarations() const;
|
||||
|
||||
bool shouldIndexTemplateParameters() const;
|
||||
|
||||
static bool isTemplateImplicitInstantiation(const Decl *D);
|
||||
|
||||
bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(),
|
||||
|
|
|
@ -216,6 +216,30 @@ TEST(IndexTest, IndexTemplateInstantiationPartial) {
|
|||
DeclAt(Position(5, 12)))));
|
||||
}
|
||||
|
||||
TEST(IndexTest, IndexTypeParmDecls) {
|
||||
std::string Code = R"cpp(
|
||||
template <typename T, int I, template<typename> class C, typename NoRef>
|
||||
struct Foo {
|
||||
T t = I;
|
||||
C<int> x;
|
||||
};
|
||||
)cpp";
|
||||
auto Index = std::make_shared<Indexer>();
|
||||
IndexingOptions Opts;
|
||||
tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
|
||||
EXPECT_THAT(Index->Symbols, AllOf(Not(Contains(QName("Foo::T"))),
|
||||
Not(Contains(QName("Foo::I"))),
|
||||
Not(Contains(QName("Foo::C"))),
|
||||
Not(Contains(QName("Foo::NoRef")))));
|
||||
|
||||
Opts.IndexTemplateParameters = true;
|
||||
Index->Symbols.clear();
|
||||
tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
|
||||
EXPECT_THAT(Index->Symbols,
|
||||
AllOf(Contains(QName("Foo::T")), Contains(QName("Foo::I")),
|
||||
Contains(QName("Foo::C")), Contains(QName("Foo::NoRef"))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace index
|
||||
} // namespace clang
|
||||
|
|
Loading…
Reference in New Issue