Allow getting template args for ClassTemplateSpecializations

Modifies clang_Cursor_getNumTemplateArguments() and friends to work on
Struct, Class and ClassTemplatePartialSpecialization decls as well as
functions.

Differential Revision: https://reviews.llvm.org/D134416
This commit is contained in:
Anders Langlands 2022-09-23 11:05:31 -04:00 committed by Aaron Ballman
parent f7907bc536
commit e8c78d8528
8 changed files with 81 additions and 47 deletions

View File

@ -424,6 +424,10 @@ libclang
the behavior of ``QualType::getNonReferenceType`` for ``CXType``. the behavior of ``QualType::getNonReferenceType`` for ``CXType``.
- Introduced the new function ``clang_CXXMethod_isDeleted``, which queries - Introduced the new function ``clang_CXXMethod_isDeleted``, which queries
whether the method is declared ``= delete``. whether the method is declared ``= delete``.
- ``clang_Cursor_getNumTemplateArguments``, ``clang_Cursor_getTemplateArgumentKind``,
``clang_Cursor_getTemplateArgumentType``, ``clang_Cursor_getTemplateArgumentValue`` and
``clang_Cursor_getTemplateArgumentUnsignedValue`` now work on struct, class,
and partial template specialization cursors in addition to function cursors.
Static Analyzer Static Analyzer
--------------- ---------------

View File

@ -3591,8 +3591,8 @@ enum CXTemplateArgumentKind {
}; };
/** /**
*Returns the number of template args of a function decl representing a * Returns the number of template args of a function, struct, or class decl
* template specialization. * representing a template specialization.
* *
* If the argument cursor cannot be converted into a template function * If the argument cursor cannot be converted into a template function
* declaration, -1 is returned. * declaration, -1 is returned.
@ -3611,8 +3611,9 @@ CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C);
/** /**
* Retrieve the kind of the I'th template argument of the CXCursor C. * Retrieve the kind of the I'th template argument of the CXCursor C.
* *
* If the argument CXCursor does not represent a FunctionDecl, an invalid * If the argument CXCursor does not represent a FunctionDecl, StructDecl, or
* template argument kind is returned. * ClassTemplatePartialSpecialization, an invalid template argument kind is
* returned.
* *
* For example, for the following declaration and specialization: * For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool> * template <typename T, int kInt, bool kBool>
@ -3631,9 +3632,9 @@ clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I);
* Retrieve a CXType representing the type of a TemplateArgument of a * Retrieve a CXType representing the type of a TemplateArgument of a
* function decl representing a template specialization. * function decl representing a template specialization.
* *
* If the argument CXCursor does not represent a FunctionDecl whose I'th * If the argument CXCursor does not represent a FunctionDecl, StructDecl,
* template argument has a kind of CXTemplateArgKind_Integral, an invalid type * ClassDecl or ClassTemplatePartialSpecialization whose I'th template argument
* is returned. * has a kind of CXTemplateArgKind_Integral, an invalid type is returned.
* *
* For example, for the following declaration and specialization: * For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool> * template <typename T, int kInt, bool kBool>
@ -3653,7 +3654,8 @@ CINDEX_LINKAGE CXType clang_Cursor_getTemplateArgumentType(CXCursor C,
* decl representing a template specialization) as a signed long long. * decl representing a template specialization) as a signed long long.
* *
* It is undefined to call this function on a CXCursor that does not represent a * It is undefined to call this function on a CXCursor that does not represent a
* FunctionDecl or whose I'th template argument is not an integral value. * FunctionDecl, StructDecl, ClassDecl or ClassTemplatePartialSpecialization
* whose I'th template argument is not an integral value.
* *
* For example, for the following declaration and specialization: * For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool> * template <typename T, int kInt, bool kBool>
@ -3673,7 +3675,8 @@ CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C,
* decl representing a template specialization) as an unsigned long long. * decl representing a template specialization) as an unsigned long long.
* *
* It is undefined to call this function on a CXCursor that does not represent a * It is undefined to call this function on a CXCursor that does not represent a
* FunctionDecl or whose I'th template argument is not an integral value. * FunctionDecl, StructDecl, ClassDecl or ClassTemplatePartialSpecialization or
* whose I'th template argument is not an integral value.
* *
* For example, for the following declaration and specialization: * For example, for the following declaration and specialization:
* template <typename T, int kInt, bool kBool> * template <typename T, int kInt, bool kBool>

View File

@ -221,7 +221,7 @@ struct Z {
// CHECK-TEMPLPARAM: 55:23 TypeRef=struct X:3:8 Extent=[55:23 - 55:24] Spelling=struct X ([55:23 - 55:24]) // CHECK-TEMPLPARAM: 55:23 TypeRef=struct X:3:8 Extent=[55:23 - 55:24] Spelling=struct X ([55:23 - 55:24])
// RUN: c-index-test -cursor-at=%s:66:23 %s | FileCheck -check-prefix=CHECK-TEMPLSPEC %s // RUN: c-index-test -cursor-at=%s:66:23 %s | FileCheck -check-prefix=CHECK-TEMPLSPEC %s
// CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25]) // CHECK-TEMPLSPEC: 66:23 ClassDecl=TC:66:23 (Definition) [Specialization of TC:59:7] [Template arg 0: kind: 1, type: char] Extent=[66:1 - 66:31] Spelling=TC ([66:23 - 66:25])
// RUN: c-index-test -cursor-at=%s:69:3 -cursor-at=%s:70:11 -cursor-at=%s:73:6 -cursor-at=%s:74:6 -cursor-at=%s:77:8 -cursor-at=%s:78:8 -cursor-at=%s:79:8 -cursor-at=%s:80:8 -cursor-at=%s:81:8 -cursor-at=%s:82:8 -cursor-at=%s:85:6 -cursor-at=%s:86:6 -cursor-at=%s:87:6 -cursor-at=%s:88:6 -cursor-at=%s:91:5 -cursor-at=%s:92:5 -cursor-at=%s:93:5 -cursor-at=%s:94:5 -cursor-at=%s:95:5 -cursor-at=%s:96:5 -cursor-at=%s:97:5 -cursor-at=%s:98:5 -cursor-at=%s:100:5 -cursor-at=%s:101:5 -cursor-at=%s:104:6 -cursor-at=%s:105:6 -cursor-at=%s:106:6 -cursor-at=%s:107:6 -cursor-at=%s:108:6 -cursor-at=%s:109:6 -cursor-at=%s:110:6 -cursor-at=%s:111:6 -cursor-at=%s:113:6 -cursor-at=%s:114:6 -cursor-at=%s:117:8 -cursor-at=%s:118:8 -cursor-at=%s:120:8 -cursor-at=%s:121:8 -cursor-at=%s:122:8 -cursor-at=%s:123:8 -cursor-at=%s:124:8 -cursor-at=%s:125:8 -cursor-at=%s:128:6 -cursor-at=%s:129:6 -cursor-at=%s:130:6 -cursor-at=%s:132:3 -cursor-at=%s:146:15 -cursor-at=%s:149:6 -cursor-at=%s:150:25 -cursor-at=%s:151:6 -cursor-at=%s:152:6 -cursor-at=%s:153:6 -cursor-at=%s:154:6 -cursor-at=%s:155:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-SPELLING %s // RUN: c-index-test -cursor-at=%s:69:3 -cursor-at=%s:70:11 -cursor-at=%s:73:6 -cursor-at=%s:74:6 -cursor-at=%s:77:8 -cursor-at=%s:78:8 -cursor-at=%s:79:8 -cursor-at=%s:80:8 -cursor-at=%s:81:8 -cursor-at=%s:82:8 -cursor-at=%s:85:6 -cursor-at=%s:86:6 -cursor-at=%s:87:6 -cursor-at=%s:88:6 -cursor-at=%s:91:5 -cursor-at=%s:92:5 -cursor-at=%s:93:5 -cursor-at=%s:94:5 -cursor-at=%s:95:5 -cursor-at=%s:96:5 -cursor-at=%s:97:5 -cursor-at=%s:98:5 -cursor-at=%s:100:5 -cursor-at=%s:101:5 -cursor-at=%s:104:6 -cursor-at=%s:105:6 -cursor-at=%s:106:6 -cursor-at=%s:107:6 -cursor-at=%s:108:6 -cursor-at=%s:109:6 -cursor-at=%s:110:6 -cursor-at=%s:111:6 -cursor-at=%s:113:6 -cursor-at=%s:114:6 -cursor-at=%s:117:8 -cursor-at=%s:118:8 -cursor-at=%s:120:8 -cursor-at=%s:121:8 -cursor-at=%s:122:8 -cursor-at=%s:123:8 -cursor-at=%s:124:8 -cursor-at=%s:125:8 -cursor-at=%s:128:6 -cursor-at=%s:129:6 -cursor-at=%s:130:6 -cursor-at=%s:132:3 -cursor-at=%s:146:15 -cursor-at=%s:149:6 -cursor-at=%s:150:25 -cursor-at=%s:151:6 -cursor-at=%s:152:6 -cursor-at=%s:153:6 -cursor-at=%s:154:6 -cursor-at=%s:155:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-SPELLING %s
// CHECK-SPELLING: 69:3 CXXConstructor=A:69:3 (default constructor) Extent=[69:3 - 69:6] Spelling=A ([69:3 - 69:4]) // CHECK-SPELLING: 69:3 CXXConstructor=A:69:3 (default constructor) Extent=[69:3 - 69:6] Spelling=A ([69:3 - 69:4])

View File

@ -130,14 +130,14 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:8:31: TemplateTypeParameter=Alloc:8:31 (Definition) Extent=[8:22 - 8:51] // CHECK-LOAD: index-templates.cpp:8:31: TemplateTypeParameter=Alloc:8:31 (Definition) Extent=[8:22 - 8:51]
// CHECK-LOAD: index-templates.cpp:8:39: TemplateRef=allocator:6:28 Extent=[8:39 - 8:48] // CHECK-LOAD: index-templates.cpp:8:39: TemplateRef=allocator:6:28 Extent=[8:39 - 8:48]
// CHECK-LOAD: index-templates.cpp:10:8: CXXMethod=clear:10:8 Extent=[10:3 - 10:15] // CHECK-LOAD: index-templates.cpp:10:8: CXXMethod=clear:10:8 Extent=[10:3 - 10:15]
// CHECK-LOAD: index-templates.cpp:14:7: ClassTemplatePartialSpecialization=vector:14:7 (Definition) [Specialization of vector:9:7] Extent=[13:1 - 14:21] // CHECK-LOAD: index-templates.cpp:14:7: ClassTemplatePartialSpecialization=vector:14:7 (Definition) [Specialization of vector:9:7] [Template arg 0: kind: 1, type: type-parameter-0-0 *] [Template arg 1: kind: 1, type: allocator<type-parameter-0-0 *>] Extent=[13:1 - 14:21]
// CHECK-LOAD: index-templates.cpp:13:19: TemplateTypeParameter=T:13:19 (Definition) Extent=[13:10 - 13:20] // CHECK-LOAD: index-templates.cpp:13:19: TemplateTypeParameter=T:13:19 (Definition) Extent=[13:10 - 13:20]
// CHECK-LOAD: index-templates.cpp:16:8: StructDecl=Z1:16:8 (Definition) Extent=[16:1 - 16:14] // CHECK-LOAD: index-templates.cpp:16:8: StructDecl=Z1:16:8 (Definition) Extent=[16:1 - 16:14]
// CHECK-LOAD: index-templates.cpp:18:16: ClassDecl=vector:18:16 (Definition) [Specialization of vector:9:7] Extent=[18:1 - 18:26] // CHECK-LOAD: index-templates.cpp:18:16: ClassDecl=vector:18:16 (Definition) [Specialization of vector:9:7] [Template arg 0: kind: 1, type: Z1] [Template arg 1: kind: 1, type: allocator<Z1>] Extent=[18:1 - 18:26]
// CHECK-LOAD: index-templates.cpp:18:23: TypeRef=struct Z1:16:8 Extent=[18:23 - 18:25] // CHECK-LOAD: index-templates.cpp:18:23: TypeRef=struct Z1:16:8 Extent=[18:23 - 18:25]
// CHECK-LOAD-NOT: CXXMethod=clear // CHECK-LOAD-NOT: CXXMethod=clear
// CHECK-LOAD: index-templates.cpp:20:8: StructDecl=Z2:20:8 (Definition) Extent=[20:1 - 20:14] // CHECK-LOAD: index-templates.cpp:20:8: StructDecl=Z2:20:8 (Definition) Extent=[20:1 - 20:14]
// CHECK-LOAD: index-templates.cpp:23:7: ClassDecl=vector:23:7 (Definition) [Specialization of vector:9:7] Extent=[22:1 - 25:2] // CHECK-LOAD: index-templates.cpp:23:7: ClassDecl=vector:23:7 (Definition) [Specialization of vector:9:7] [Template arg 0: kind: 1, type: Z2] [Template arg 1: kind: 1, type: allocator<Z2>] Extent=[22:1 - 25:2]
// CHECK-LOAD: index-templates.cpp:23:14: TypeRef=struct Z2:20:8 Extent=[23:14 - 23:16] // CHECK-LOAD: index-templates.cpp:23:14: TypeRef=struct Z2:20:8 Extent=[23:14 - 23:16]
// CHECK-LOAD: index-templates.cpp:24:8: CXXMethod=clear:24:8 Extent=[24:3 - 24:15] // CHECK-LOAD: index-templates.cpp:24:8: CXXMethod=clear:24:8 Extent=[24:3 - 24:15]
// CHECK-LOAD: index-templates.cpp:28:8: ClassTemplate=Y:28:8 (Definition) Extent=[27:1 - 31:2] // CHECK-LOAD: index-templates.cpp:28:8: ClassTemplate=Y:28:8 (Definition) Extent=[27:1 - 31:2]
@ -163,7 +163,7 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:44:19: TemplateTypeParameter=T:44:19 (Definition) Extent=[44:10 - 44:20] // CHECK-LOAD: index-templates.cpp:44:19: TemplateTypeParameter=T:44:19 (Definition) Extent=[44:10 - 44:20]
// CHECK-LOAD: index-templates.cpp:44:31: NonTypeTemplateParameter=Value:44:31 (Definition) Extent=[44:22 - 44:36] // CHECK-LOAD: index-templates.cpp:44:31: NonTypeTemplateParameter=Value:44:31 (Definition) Extent=[44:22 - 44:36]
// CHECK-LOAD: index-templates.cpp:44:22: TypeRef=Unsigned:42:18 Extent=[44:22 - 44:30] // CHECK-LOAD: index-templates.cpp:44:22: TypeRef=Unsigned:42:18 Extent=[44:22 - 44:30]
// CHECK-LOAD: index-templates.cpp:47:16: ClassDecl=vector:47:16 (Definition) [Specialization of vector:14:7] Extent=[47:1 - 47:28] // 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: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-LOAD: index-templates.cpp:50:26: FunctionTemplate=getAs:50:26 Extent=[50:3 - 50:33]
// CHECK-LOAD: index-templates.cpp:50:21: TemplateTypeParameter=T:50:21 (Definition) Extent=[50:12 - 50:22] // CHECK-LOAD: index-templates.cpp:50:21: TemplateTypeParameter=T:50:21 (Definition) Extent=[50:12 - 50:22]
@ -186,6 +186,7 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:85:20: DeclRefExpr=t:82:18 Extent=[85:20 - 85:21] // CHECK-LOAD: index-templates.cpp:85:20: DeclRefExpr=t:82:18 Extent=[85:20 - 85:21]
// CHECK-LOAD: index-templates.cpp:85:23: TypeRef=second_type:83:13 Extent=[85:23 - 85:34] // CHECK-LOAD: index-templates.cpp:85:23: TypeRef=second_type:83:13 Extent=[85:23 - 85:34]
// CHECK-LOAD: index-templates.cpp:85:35: DeclRefExpr=u:82:23 Extent=[85:35 - 85:36] // CHECK-LOAD: index-templates.cpp:85:35: DeclRefExpr=u:82:23 Extent=[85:35 - 85:36]
// CHECK-LOAD: index-templates.cpp:98:16: StructDecl=Pair:98:16 (Definition) [Specialization of Pair:76:8] [Template arg 0: kind: 1, type: int] [Template arg 1: kind: 1, type: int] Extent=[98:1 - 98:30]
// CHECK-LOAD: index-templates.cpp:101:8: ClassTemplate=SuperPair:101:8 (Definition) Extent=[100:1 - 101:50] // CHECK-LOAD: index-templates.cpp:101:8: ClassTemplate=SuperPair:101:8 (Definition) Extent=[100:1 - 101:50]
// CHECK-LOAD: index-templates.cpp:100:19: TemplateTypeParameter=T:100:19 (Definition) Extent=[100:10 - 100:20] // CHECK-LOAD: index-templates.cpp:100:19: TemplateTypeParameter=T:100:19 (Definition) Extent=[100:10 - 100:20]
// CHECK-LOAD: index-templates.cpp:100:31: TemplateTypeParameter=U:100:31 (Definition) Extent=[100:22 - 100:32] // CHECK-LOAD: index-templates.cpp:100:31: TemplateTypeParameter=U:100:31 (Definition) Extent=[100:22 - 100:32]

View File

@ -22,7 +22,7 @@ template<> void g<int>(ClassTmpl<int, int>);
// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY // RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY
// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename> class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20] // PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename> class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20]
// PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20] // PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20]
// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<Integer, Integer> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43] // PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<Integer, Integer> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] [Template arg 0: kind: 1, type: int] [Template arg 1: kind: 1, type: int] Extent=[6:1 - 6:43]
// PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36] // PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36]
// 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: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:6: FunctionTemplate=template <typename T> void g(ClassTmpl<T, T>):11:6 Extent=[10:1 - 11:24]

View File

@ -191,7 +191,7 @@ inline namespace InlineNS {}
// CHECK: TemplateRef=TypeAlias:61:1 [type=] [typekind=Invalid] [isPOD=0] // CHECK: TemplateRef=TypeAlias:61:1 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: ClassTemplate=Specialization:66:8 (Definition) [type=] [typekind=Invalid] [isPOD=0] // CHECK: ClassTemplate=Specialization:66:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TemplateTypeParameter=T:65:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0] // CHECK: TemplateTypeParameter=T:65:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
// CHECK: StructDecl=Specialization:69:8 [Specialization of Specialization:66:8] [type=Specialization<int>] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0] // CHECK: StructDecl=Specialization:69:8 [Specialization of Specialization:66:8] [Template arg 0: kind: 1, type: int] [type=Specialization<int>] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0]
// CHECK: VarDecl=templRefParam:71:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1] // CHECK: VarDecl=templRefParam:71:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
// CHECK: TemplateRef=Specialization:66:8 [type=] [typekind=Invalid] [isPOD=0] // CHECK: TemplateRef=Specialization:66:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: CallExpr=Specialization:66:8 [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1] // CHECK: CallExpr=Specialization:66:8 [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]

View File

@ -1002,7 +1002,10 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
clang_getCString(Name), line, column); clang_getCString(Name), line, column);
clang_disposeString(Name); clang_disposeString(Name);
if (Cursor.kind == CXCursor_FunctionDecl) { if (Cursor.kind == CXCursor_FunctionDecl
|| Cursor.kind == CXCursor_StructDecl
|| Cursor.kind == CXCursor_ClassDecl
|| Cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
/* Collect the template parameter kinds from the base template. */ /* Collect the template parameter kinds from the base template. */
int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor); int NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
int I; int I;

View File

@ -1353,34 +1353,43 @@ CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
} }
int clang_Cursor_getNumTemplateArguments(CXCursor C) { int clang_Cursor_getNumTemplateArguments(CXCursor C) {
if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { CXCursorKind kind = clang_getCursorKind(C);
if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
kind != CXCursor_ClassDecl &&
kind != CXCursor_ClassTemplatePartialSpecialization) {
return -1; return -1;
} }
const FunctionDecl *FD = if (const auto *FD =
llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C)); llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) {
if (!FD) { const FunctionTemplateSpecializationInfo *SpecInfo =
return -1; FD->getTemplateSpecializationInfo();
if (!SpecInfo) {
return -1;
}
return SpecInfo->TemplateArguments->size();
} }
const FunctionTemplateSpecializationInfo *SpecInfo = if (const auto *SD =
FD->getTemplateSpecializationInfo(); llvm::dyn_cast_if_present<clang::ClassTemplateSpecializationDecl>(
if (!SpecInfo) { getCursorDecl(C))) {
return -1; return SD->getTemplateArgs().size();
} }
return SpecInfo->TemplateArguments->size(); return -1;
} }
enum CXGetTemplateArgumentStatus { enum CXGetTemplateArgumentStatus {
/** The operation completed successfully */ /** The operation completed successfully */
CXGetTemplateArgumentStatus_Success = 0, CXGetTemplateArgumentStatus_Success = 0,
/** The specified cursor did not represent a FunctionDecl. */ /** The specified cursor did not represent a FunctionDecl or
CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1, ClassTemplateSpecializationDecl. */
CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1,
/** The specified cursor was not castable to a FunctionDecl. */ /** The specified cursor was not castable to a FunctionDecl or
CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2, ClassTemplateSpecializationDecl. */
CXGetTemplateArgumentStatus_BadDeclCast = -2,
/** A NULL FunctionTemplateSpecializationInfo was retrieved. */ /** A NULL FunctionTemplateSpecializationInfo was retrieved. */
CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3, CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
@ -1391,28 +1400,42 @@ enum CXGetTemplateArgumentStatus {
static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I, static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I,
TemplateArgument *TA) { TemplateArgument *TA) {
if (clang_getCursorKind(C) != CXCursor_FunctionDecl) { CXCursorKind kind = clang_getCursorKind(C);
return CXGetTemplateArgumentStatus_CursorNotFunctionDecl; if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
kind != CXCursor_ClassDecl &&
kind != CXCursor_ClassTemplatePartialSpecialization) {
return -1;
} }
const FunctionDecl *FD = if (const auto *FD =
llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C)); llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) {
if (!FD) {
return CXGetTemplateArgumentStatus_BadFunctionDeclCast; const FunctionTemplateSpecializationInfo *SpecInfo =
FD->getTemplateSpecializationInfo();
if (!SpecInfo) {
return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
}
if (I >= SpecInfo->TemplateArguments->size()) {
return CXGetTemplateArgumentStatus_InvalidIndex;
}
*TA = SpecInfo->TemplateArguments->get(I);
return 0;
} }
const FunctionTemplateSpecializationInfo *SpecInfo = if (const auto *SD =
FD->getTemplateSpecializationInfo(); llvm::dyn_cast_if_present<clang::ClassTemplateSpecializationDecl>(
if (!SpecInfo) { getCursorDecl(C))) {
return CXGetTemplateArgumentStatus_NullTemplSpecInfo; if (I >= SD->getTemplateArgs().size()) {
return CXGetTemplateArgumentStatus_InvalidIndex;
}
*TA = SD->getTemplateArgs()[I];
return 0;
} }
if (I >= SpecInfo->TemplateArguments->size()) { return CXGetTemplateArgumentStatus_BadDeclCast;
return CXGetTemplateArgumentStatus_InvalidIndex;
}
*TA = SpecInfo->TemplateArguments->get(I);
return 0;
} }
enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C, enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,