]> granicus.if.org Git - clang/commitdiff
[clang][Index] Enable indexing of Template Type Parameters behind a flag
authorKadir Cetinkaya <kadircet@google.com>
Thu, 21 Feb 2019 09:52:33 +0000 (09:52 +0000)
committerKadir Cetinkaya <kadircet@google.com>
Thu, 21 Feb 2019 09:52:33 +0000 (09:52 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354560 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Index/IndexingAction.h
lib/Index/IndexDecl.cpp
lib/Index/IndexSymbol.cpp
lib/Index/IndexTypeSourceInfo.cpp
lib/Index/IndexingContext.cpp
lib/Index/IndexingContext.h
unittests/Index/IndexTests.cpp

index 8b3d5415c063e35c651c3d845d2fd051bbf876c1..9756f3c539e65b172fc5fc9c51783fe7d51fff6b 100644 (file)
@@ -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).
index eb0b3d4a70e355cb2d96f6bf5ce89330aa6bf910..0f6d6212a243870e72f35d45474cf6c0982df97d 100644 (file)
@@ -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);
index 27e62af19f2d2ffcea73e30e2c94b63f9b6ef772..d21c673dee4eb9c09ceccfe3b7a64e07677a10e9 100644 (file)
@@ -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;
 
index e791a9d4a3c9f9be792e9d730db743e6f3093ffe..9f9740b607975f20bb5cb2dd1430ea581ee0fa30 100644 (file)
@@ -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();
index 3d2d7d4ff02aea1b400ff3322d57f5d610efbbdc..d01dd50f3b5d4de94f0a0c925b4652b27e9278b5 100644 (file)
@@ -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);
index 7765fa73f82c842f58833e9d70374ab9166a1c1b..3136878c080c64e935b9f99ee9fb8d3f70945bef 100644 (file)
@@ -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(),
index 61c969f978c6be893945cfc480d6684a34e2d45f..66cef881f636cf01b7a21a943f174b9c9aeb4cc1 100644 (file)
@@ -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