[clang-tools-extra] [clangd] Don't collect templated decls for builtin templates (PR #78466)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 08:35:52 PST 2024


https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/78466

Builtin templates e.g. `__make_integer_seq`, `__type_pack_element` are such that they don't have alias *Decls*. [D133262](https://reviews.llvm.org/D133262) marked these as alias templates, resulting in an attempt to collect their null "using" Decls within our `TargetFinder`.

This fixes https://github.com/clangd/clangd/issues/1906.

>From efa5098e9ca433654ef3bc439c422867e4abee41 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Thu, 18 Jan 2024 00:15:18 +0800
Subject: [PATCH] [clangd] Don't collect templated decls for builtin templates

This fixes https://github.com/clangd/clangd/issues/1906.
---
 clang-tools-extra/clangd/FindTarget.cpp       | 12 ++++++---
 .../clangd/unittests/FindTargetTests.cpp      | 27 +++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 839cf6332fe8b0..31450820f1b20a 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -443,9 +443,15 @@ struct TargetFinder {
           Outer.add(TST->getAliasedType(), Flags | Rel::Underlying);
           // Don't *traverse* the alias, which would result in traversing the
           // template of the underlying type.
-          Outer.report(
-              TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(),
-              Flags | Rel::Alias | Rel::TemplatePattern);
+
+          // Builtin templates e.g. __make_integer_seq, __type_pack_element
+          // are such that they don't have alias *decls*. Even then, we still
+          // traverse their desugared *types* so that instantiated decls are
+          // collected.
+          if (NamedDecl *D = TST->getTemplateName()
+                                 .getAsTemplateDecl()
+                                 ->getTemplatedDecl())
+            Outer.report(D, Flags | Rel::Alias | Rel::TemplatePattern);
         }
         // specializations of template template parameters aren't instantiated
         // into decls, so they must refer to the parameter itself.
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index fbd10c4a47a793..29cff68cf03b2e 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -709,6 +709,33 @@ TEST_F(TargetDeclTest, TypeAliasTemplate) {
                 Rel::Alias | Rel::TemplatePattern});
 }
 
+TEST_F(TargetDeclTest, BuiltinTemplates) {
+  Code = R"cpp(
+    template <class T, T... Index> struct integer_sequence {};
+    [[__make_integer_seq]]<integer_sequence, int, 3> X;
+  )cpp";
+  EXPECT_DECLS(
+      "TemplateSpecializationTypeLoc",
+      {"struct integer_sequence", Rel::TemplatePattern | Rel::Underlying},
+      {"template<> struct integer_sequence<int, <0, 1, 2>>",
+       Rel::TemplateInstantiation | Rel::Underlying});
+
+  // Dependent context.
+  Code = R"cpp(
+    template <class T, T... Index> struct integer_sequence;
+
+    template <class T, int N>
+    using make_integer_sequence = [[__make_integer_seq]]<integer_sequence, T, N>;
+  )cpp";
+  EXPECT_DECLS("TemplateSpecializationTypeLoc");
+
+  Code = R"cpp(
+    template <int N, class... Pack>
+    using type_pack_element = [[__type_pack_element]]<N, Pack...>;
+  )cpp";
+  EXPECT_DECLS("TemplateSpecializationTypeLoc");
+}
+
 TEST_F(TargetDeclTest, MemberOfTemplate) {
   Code = R"cpp(
     template <typename T> struct Foo {



More information about the cfe-commits mailing list