[clang] [libclang] Visit function template instantiations (PR #67928)
Daan Vanoverloop via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 7 01:28:54 PDT 2023
https://github.com/Danacus updated https://github.com/llvm/llvm-project/pull/67928
>From a516d2c53451db78147a631b5c092dbfeba73e89 Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sun, 1 Oct 2023 18:48:26 +0200
Subject: [PATCH 1/6] [libclang] Add support for template arguments of
CXXMethod cursors
---
clang/include/clang-c/Index.h | 13 +++++++------
clang/tools/c-index-test/c-index-test.c | 1 +
clang/tools/libclang/CXCursor.cpp | 8 ++++----
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 1b91feabd584c50..eeb23ce41ef373c 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3126,9 +3126,9 @@ CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C);
/**
* Retrieve the kind of the I'th template argument of the CXCursor C.
*
- * If the argument CXCursor does not represent a FunctionDecl, StructDecl, or
- * ClassTemplatePartialSpecialization, an invalid template argument kind is
- * returned.
+ * If the argument CXCursor does not represent a FunctionDecl, CXXMethod,
+ * StructDecl, or ClassTemplatePartialSpecialization, an invalid template
+ * argument kind is returned.
*
* For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool>
@@ -3147,9 +3147,10 @@ clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I);
* Retrieve a CXType representing the type of a TemplateArgument of a
* function decl representing a template specialization.
*
- * If the argument CXCursor does not represent a FunctionDecl, StructDecl,
- * ClassDecl or ClassTemplatePartialSpecialization whose I'th template argument
- * has a kind of CXTemplateArgKind_Integral, an invalid type is returned.
+ * If the argument CXCursor does not represent a FunctionDecl, CXXMethod,
+ * StructDecl, ClassDecl or ClassTemplatePartialSpecialization whose I'th
+ * template argument has a kind of CXTemplateArgKind_Integral, an invalid type
+ * is returned.
*
* For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool>
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 9d66a22f3b43b55..238c9951269d159 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1040,6 +1040,7 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
clang_disposeString(Name);
if (Cursor.kind == CXCursor_FunctionDecl
+ || Cursor.kind == CXCursor_CXXMethod
|| Cursor.kind == CXCursor_StructDecl
|| Cursor.kind == CXCursor_ClassDecl
|| Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index fd03c48ba1a42aa..190e0063b78d740 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1364,8 +1364,8 @@ CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
int clang_Cursor_getNumTemplateArguments(CXCursor C) {
CXCursorKind kind = clang_getCursorKind(C);
- if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
- kind != CXCursor_ClassDecl &&
+ if (kind != CXCursor_FunctionDecl && kind != CXCursor_CXXMethod &&
+ kind != CXCursor_StructDecl && kind != CXCursor_ClassDecl &&
kind != CXCursor_ClassTemplatePartialSpecialization) {
return -1;
}
@@ -1411,8 +1411,8 @@ enum CXGetTemplateArgumentStatus {
static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I,
TemplateArgument *TA) {
CXCursorKind kind = clang_getCursorKind(C);
- if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
- kind != CXCursor_ClassDecl &&
+ if (kind != CXCursor_FunctionDecl && kind != CXCursor_CXXMethod &&
+ kind != CXCursor_StructDecl && kind != CXCursor_ClassDecl &&
kind != CXCursor_ClassTemplatePartialSpecialization) {
return -1;
}
>From fa471bdf99b7d4e44f92c6e88af4f3d9876f6b95 Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sun, 1 Oct 2023 18:48:32 +0200
Subject: [PATCH 2/6] [libclang] Visit function template instantiations
---
clang/test/Index/index-templates.cpp | 17 +++++++++++------
clang/test/Index/print-display-names.cpp | 3 +++
clang/tools/libclang/CIndex.cpp | 9 ++++++++-
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/clang/test/Index/index-templates.cpp b/clang/test/Index/index-templates.cpp
index 430a156b189d9e3..4994ddcde8d9ebc 100644
--- a/clang/test/Index/index-templates.cpp
+++ b/clang/test/Index/index-templates.cpp
@@ -54,7 +54,7 @@ void template_exprs() {
f<Unsigned, OneDimension, value>(value<Unsigned, OneDimension>());
Z4().getAs<Unsigned>();
}
-
+extern template float Z4::getAs<float>();
template<typename T> void swap(T&, T&);
template<typename T, typename U> void swap(Y<T, U>&, Y<T, U>&);
void swap(Z4&, Z4&);
@@ -110,6 +110,8 @@ static const int FxnTmpl_Var = 7;
template <>
void foo<float, 9, FxnTmplEnum_B, FxnTmpl_Var + 7>(float Value);
+template void foo<char, 2, FxnTmplEnum_A, FxnTmpl_Var + 3>(char Value);
+
template <class T>
using alias = T;
@@ -166,6 +168,8 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:47:16: ClassDecl=vector:47:16 (Definition) [Specialization of vector:14:7] [Template arg 0: kind: 1, type: int *] [Template arg 1: kind: 1, type: allocator<int *>] Extent=[47:1 - 47:28]
// CHECK-LOAD: index-templates.cpp:49:8: StructDecl=Z4:49:8 (Definition) Extent=[49:1 - 51:2]
// CHECK-LOAD: index-templates.cpp:50:26: FunctionTemplate=getAs:50:26 Extent=[50:3 - 50:33]
+// CHECK: index-templates.cpp:50:26: CXXMethod=template<> unsigned int getAs<unsigned int>():50:26 [Specialization of getAs:50:26] [Template arg 0: kind: 1, type: unsigned int] Extent=[50:24 - 50:33] [access=public]
+// CHECK: index-templates.cpp:50:26: CXXMethod=template<> float getAs<float>():50:26 [Specialization of getAs:50:26] [Template arg 0: kind: 1, type: float] Extent=[50:24 - 50:33] [access=public]
// CHECK-LOAD: index-templates.cpp:50:21: TemplateTypeParameter=T:50:21 (Definition) Extent=[50:12 - 50:22]
// CHECK-LOAD: index-templates.cpp:53:6: FunctionDecl=template_exprs:53:6 (Definition)
// CHECK-LOAD: index-templates.cpp:54:3: CallExpr=f:4:6 Extent=[54:3 - 54:68]
@@ -177,7 +181,7 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:55:8: MemberRefExpr=getAs:50:26 SingleRefName=[55:8 - 55:13] RefName=[55:8 - 55:13] Extent=[55:3 - 55:23]
// CHECK-LOAD: index-templates.cpp:55:3: CallExpr=Z4:49:8 Extent=[55:3 - 55:7]
// CHECK-LOAD: index-templates.cpp:55:14: TypeRef=Unsigned:42:18 Extent=[55:14 - 55:22]
-// CHECK-LOAD: index-templates.cpp:68:6: FunctionTemplate=unresolved_exprs:68:6 (Definition)
+// CHECK-LOAD: index-templates.cpp:68:6: FunctionTemplate=unresolved_exprs:68:6 (Definition) Extent=[67:1 - 73:2]
// CHECK-LOAD: index-templates.cpp:69:3: OverloadedDeclRef=swap[60:6, 59:39, 58:27]
// CHECK-LOAD: index-templates.cpp:71:6: OverloadedDeclRef=f[63:7, 64:9]
// CHECK-LOAD: index-templates.cpp:72:3: OverloadedDeclRef=swap[58:27, 59:39]
@@ -192,11 +196,12 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:100:31: TemplateTypeParameter=U:100:31 (Definition) Extent=[100:22 - 100:32]
// CHECK-LOAD: index-templates.cpp:101:20: C++ base class specifier=Pair<int, int>:98:16 [access=public isVirtual=false] Extent=[101:20 - 101:34]
// CHECK-LOAD: index-templates.cpp:101:36: C++ base class specifier=Pair<T, U>:76:8 [access=public isVirtual=false] Extent=[101:36 - 101:46]
+// CHECK-LOAD: index-templates.cpp:107:6: FunctionDecl=foo:107:6 (Definition) [Specialization of foo:107:6] [Template arg 0: kind: 1, type: char] [Template arg 1: kind: 4, intval: 2] [Template arg 2: kind: 4, intval: 0] [Template arg 3: kind: 4, intval: 10] Extent=[107:1 - 107:21]
// CHECK-LOAD: index-templates.cpp:111:6: FunctionDecl=foo:111:6 [Specialization of foo:107:6] [Template arg 0: kind: 1, type: float] [Template arg 1: kind: 4, intval: 9] [Template arg 2: kind: 4, intval: 1] [Template arg 3: kind: 4, intval: 14] Extent=[110:1 - 111:64]
-// CHECK-LOAD: index-templates.cpp:114:1: TypeAliasTemplateDecl=alias:114:1 (Definition) Extent=[113:1 - 114:16]
-// CHECK-LOAD: index-templates.cpp:113:17: TemplateTypeParameter=T:113:17 (Definition) Extent=[113:11 - 113:18] [access=public]
-// CHECK-LOAD: index-templates.cpp:114:7: TypeAliasDecl=alias:114:7 (Definition) Extent=[114:1 - 114:16]
-// CHECK-LOAD: index-templates.cpp:114:15: TypeRef=T:113:17 Extent=[114:15 - 114:16]
+// CHECK-LOAD: index-templates.cpp:116:1: TypeAliasTemplateDecl=alias:116:1 (Definition) Extent=[115:1 - 116:16]
+// CHECK-LOAD: index-templates.cpp:115:17: TemplateTypeParameter=T:115:17 (Definition) Extent=[115:11 - 115:18] [access=public]
+// CHECK-LOAD: index-templates.cpp:116:7: TypeAliasDecl=alias:116:7 (Definition) Extent=[116:1 - 116:16]
+// CHECK-LOAD: index-templates.cpp:116:15: TypeRef=T:115:17 Extent=[116:15 - 116:16]
// RUN: c-index-test -test-load-source-usrs all -fno-delayed-template-parsing %s | FileCheck -check-prefix=CHECK-USRS %s
// CHECK-USRS: index-templates.cpp c:@FT@>3#T#Nt0.0#t>2#T#Nt1.0f#>t0.22S0_#v# Extent=[3:1 - 4:22]
diff --git a/clang/test/Index/print-display-names.cpp b/clang/test/Index/print-display-names.cpp
index 7623fa838085b7c..24915690d253e2c 100644
--- a/clang/test/Index/print-display-names.cpp
+++ b/clang/test/Index/print-display-names.cpp
@@ -11,12 +11,14 @@ template<typename T>
void g(ClassTmpl<T, T>);
template<> void g<int>(ClassTmpl<int, int>);
+extern template void g<char>(ClassTmpl<char, char>);
// RUN: c-index-test -test-load-source all-display %s | FileCheck %s --check-prefix=DISPLAY_NAME
// DISPLAY_NAME: print-display-names.cpp:2:7: ClassTemplate=ClassTmpl<T, typename>:2:7
// DISPLAY_NAME: print-display-names.cpp:6:16: ClassDecl=ClassTmpl<Integer, Integer>:6:16 (Definition)
// DISPLAY_NAME: print-display-names.cpp:8:6: FunctionDecl=f(ClassTmpl<float, Integer>):8:6
// DISPLAY_NAME: print-display-names.cpp:11:6: FunctionTemplate=g(ClassTmpl<T, T>):11:6
+// DISPLAY_NAME: print-display-names.cpp:11:6: FunctionDecl=g<>(ClassTmpl<char, char>):11:6 [Specialization of g:11:6] [Template arg 0: kind: 1, type: char] Extent=[11:1 - 11:24]
// DISPLAY_NAME: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6]
// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY
@@ -27,5 +29,6 @@ template<> void g<int>(ClassTmpl<int, int>);
// PRETTY: print-display-names.cpp:8:34: ParmDecl=ClassTmpl<float, Integer> p:8:34 (Definition) Extent=[8:8 - 8:35]
// PRETTY: print-display-names.cpp:11:6: FunctionTemplate=template <typename T> void g(ClassTmpl<T, T>):11:6 Extent=[10:1 - 11:24]
// PRETTY: print-display-names.cpp:11:23: ParmDecl=ClassTmpl<T, T>:11:23 (Definition) Extent=[11:8 - 11:23]
+// PRETTY: print-display-names.cpp:11:6: FunctionDecl=template<> void g<char>(ClassTmpl<char, char>):11:6 [Specialization of g:11:6] [Template arg 0: kind: 1, type: char] Extent=[11:1 - 11:24]
// PRETTY: print-display-names.cpp:13:17: FunctionDecl=template<> void g<int>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6] [Template arg 0: kind: 1, type: int] Extent=[13:1 - 13:44]
// PRETTY: print-display-names.cpp:13:43: ParmDecl=ClassTmpl<int, int>:13:43 (Definition) Extent=[13:24 - 13:43]
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index f0c8ecfcb6264fb..aeb685694e9d114 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -962,7 +962,14 @@ bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
return true;
auto *FD = D->getTemplatedDecl();
- return VisitAttributes(FD) || VisitFunctionDecl(FD);
+ if (VisitAttributes(FD) || VisitFunctionDecl(FD))
+ return true;
+
+ for (auto *Child : D->specializations())
+ if (Visit(MakeCXCursor(Child, TU)))
+ return true;
+
+ return false;
}
bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
>From a0fb919d9823139525649adb0e6668ac5d5e32cd Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sun, 1 Oct 2023 18:57:29 +0200
Subject: [PATCH 3/6] Fix formatting
---
clang/tools/c-index-test/c-index-test.c | 10 +++++-----
clang/tools/libclang/CIndex.cpp | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 238c9951269d159..b41aaf00c68ee09 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1039,11 +1039,11 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
clang_getCString(Name), line, column);
clang_disposeString(Name);
- if (Cursor.kind == CXCursor_FunctionDecl
- || Cursor.kind == CXCursor_CXXMethod
- || Cursor.kind == CXCursor_StructDecl
- || Cursor.kind == CXCursor_ClassDecl
- || Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
+ if (Cursor.kind == CXCursor_FunctionDecl ||
+ Cursor.kind == CXCursor_CXXMethod ||
+ Cursor.kind == CXCursor_StructDecl ||
+ Cursor.kind == CXCursor_ClassDecl ||
+ Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
/* Collect the template parameter kinds from the base template. */
int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
int I;
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index aeb685694e9d114..c747cbbeefb4d2e 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -967,7 +967,7 @@ bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
for (auto *Child : D->specializations())
if (Visit(MakeCXCursor(Child, TU)))
- return true;
+ return true;
return false;
}
>From 00a996cd7ca39e4cec51e7036ea67911b8e0b7ce Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sun, 1 Oct 2023 19:04:53 +0200
Subject: [PATCH 4/6] Fix formatting
---
clang/tools/c-index-test/c-index-test.c | 8 ++++----
clang/tools/libclang/CIndex.cpp | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index b41aaf00c68ee09..f370c2dfca22acb 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1044,10 +1044,10 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
Cursor.kind == CXCursor_StructDecl ||
Cursor.kind == CXCursor_ClassDecl ||
Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
- /* Collect the template parameter kinds from the base template. */
- int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
- int I;
- if (NumTemplateArgs < 0) {
+ /* Collect the template parameter kinds from the base template. */
+ int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
+ int I;
+ if (NumTemplateArgs < 0) {
printf(" [no template arg info]");
}
for (I = 0; I < NumTemplateArgs; I++) {
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index c747cbbeefb4d2e..7cb85ee6139c53b 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -968,7 +968,7 @@ bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
for (auto *Child : D->specializations())
if (Visit(MakeCXCursor(Child, TU)))
return true;
-
+
return false;
}
>From 156585a3de1c69e10fffdccb255de6df97fa78f4 Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sat, 7 Oct 2023 10:26:49 +0200
Subject: [PATCH 5/6] Formatting
---
clang/tools/c-index-test/c-index-test.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index f370c2dfca22acb..b41aaf00c68ee09 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1044,10 +1044,10 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
Cursor.kind == CXCursor_StructDecl ||
Cursor.kind == CXCursor_ClassDecl ||
Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
- /* Collect the template parameter kinds from the base template. */
- int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
- int I;
- if (NumTemplateArgs < 0) {
+ /* Collect the template parameter kinds from the base template. */
+ int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
+ int I;
+ if (NumTemplateArgs < 0) {
printf(" [no template arg info]");
}
for (I = 0; I < NumTemplateArgs; I++) {
>From a0f10a692b3a1f0468cbd64cb87b1fa9e50ad7d4 Mon Sep 17 00:00:00 2001
From: Daan Vanoverloop <daan at vanoverloop.xyz>
Date: Sat, 7 Oct 2023 10:27:58 +0200
Subject: [PATCH 6/6] Fix formatting
---
clang/tools/c-index-test/c-index-test.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index b41aaf00c68ee09..27359bf88104d23 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1044,12 +1044,12 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
Cursor.kind == CXCursor_StructDecl ||
Cursor.kind == CXCursor_ClassDecl ||
Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
- /* Collect the template parameter kinds from the base template. */
- int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
- int I;
- if (NumTemplateArgs < 0) {
+ /* Collect the template parameter kinds from the base template. */
+ int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
+ int I;
+ if (NumTemplateArgs < 0) {
printf(" [no template arg info]");
- }
+ }
for (I = 0; I < NumTemplateArgs; I++) {
enum CXTemplateArgumentKind TAK =
clang_Cursor_getTemplateArgumentKind(Cursor, I);
More information about the cfe-commits
mailing list