================
@@ -1438,29 +1438,40 @@ 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;
   }
 
-  if (const auto *FD =
-          llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) {
+  const TemplateArgumentList *TAL = nullptr;
+
+  if (const auto *FD = dyn_cast_if_present<FunctionDecl>(getCursorDecl(C))) {
     const FunctionTemplateSpecializationInfo *SpecInfo =
         FD->getTemplateSpecializationInfo();
     if (!SpecInfo) {
       return -1;
     }
-    return SpecInfo->TemplateArguments->size();
+    TAL = SpecInfo->TemplateArguments;
   }
 
-  if (const auto *SD =
-          llvm::dyn_cast_if_present<clang::ClassTemplateSpecializationDecl>(
-              getCursorDecl(C))) {
-    return SD->getTemplateArgs().size();
+  if (!TAL) {
+    if (const auto *SD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
+            getCursorDecl(C))) {
+      TAL = &SD->getTemplateArgs();
+    }
   }
 
-  return -1;
+  if (!TAL)
+    return -1;
+
+  unsigned ArgCount = TAL->size();
+  for (unsigned i = 0; i < TAL->size(); i++) {
+    const TemplateArgument &Arg = TAL->get(i);
+    if (Arg.getKind() == TemplateArgument::Pack)
+      ArgCount += Arg.pack_size() - 1;
----------------
fscheidl wrote:

@Endilll Wondered about this too, but I'd think this falls under "The library 
should be ABI and API stable over time, but ABI- and API-breaking changes can 
happen in the following (non-exhaustive) situations: [...] Rarely, bug fixes to 
libclang itself" (see https://clang.llvm.org/docs/LibClang.html) - what do you 
think?

`clang_Cursor_getNumTemplateArguments` is supposed to return the number of 
template arguments for a specialization, and `Foo<int, float, double>` has 3. 
Returning 2 because the template definition uses a parameter pack seems off. 
Also, the current functions wouldn't work for the third argument at all.

https://github.com/llvm/llvm-project/pull/183504
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to