anderslanglands created this revision.
Herald added a project: All.
anderslanglands requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134416

Files:
  clang/docs/ReleaseNotes.rst
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===================================================================
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -1353,34 +1353,42 @@
 }
 
 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;
   }
 
-  const FunctionDecl *FD =
-      llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C));
-  if (!FD) {
-    return -1;
-  }
-
-  const FunctionTemplateSpecializationInfo *SpecInfo =
-      FD->getTemplateSpecializationInfo();
-  if (!SpecInfo) {
+  if (const FunctionDecl *FD =
+          llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) {
+    const FunctionTemplateSpecializationInfo *SpecInfo =
+        FD->getTemplateSpecializationInfo();
+    if (!SpecInfo) {
+      return -1;
+    }
+    return SpecInfo->TemplateArguments->size();
+  } else if (const ClassTemplateSpecializationDecl *SD =
+                 llvm::dyn_cast_if_present<
+                     clang::ClassTemplateSpecializationDecl>(
+                     getCursorDecl(C))) {
+    return SD->getTemplateArgs().size();
+  } else {
     return -1;
   }
-
-  return SpecInfo->TemplateArguments->size();
 }
 
 enum CXGetTemplateArgumentStatus {
   /** The operation completed successfully */
   CXGetTemplateArgumentStatus_Success = 0,
 
-  /** The specified cursor did not represent a FunctionDecl. */
-  CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1,
+  /** The specified cursor did not represent a FunctionDecl or
+      ClassTemplateSpecializationDecl.                         */
+  CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1,
 
-  /** The specified cursor was not castable to a FunctionDecl. */
-  CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2,
+  /** The specified cursor was not castable to a FunctionDecl or
+      ClassTemplateSpecializationDecl.                         */
+  CXGetTemplateArgumentStatus_BadDeclCast = -2,
 
   /** A NULL FunctionTemplateSpecializationInfo was retrieved. */
   CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
@@ -1391,28 +1399,43 @@
 
 static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I,
                                             TemplateArgument *TA) {
-  if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
-    return CXGetTemplateArgumentStatus_CursorNotFunctionDecl;
+  CXCursorKind kind = clang_getCursorKind(C);
+  if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
+      kind != CXCursor_ClassDecl &&
+      kind != CXCursor_ClassTemplatePartialSpecialization) {
+    return -1;
   }
 
-  const FunctionDecl *FD =
-      llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C));
-  if (!FD) {
-    return CXGetTemplateArgumentStatus_BadFunctionDeclCast;
-  }
+  if (const FunctionDecl *FD =
+          llvm::dyn_cast_if_present<clang::FunctionDecl>(getCursorDecl(C))) {
 
-  const FunctionTemplateSpecializationInfo *SpecInfo =
-      FD->getTemplateSpecializationInfo();
-  if (!SpecInfo) {
-    return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
-  }
+    const FunctionTemplateSpecializationInfo *SpecInfo =
+        FD->getTemplateSpecializationInfo();
+    if (!SpecInfo) {
+      return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
+    }
 
-  if (I >= SpecInfo->TemplateArguments->size()) {
-    return CXGetTemplateArgumentStatus_InvalidIndex;
-  }
+    if (I >= SpecInfo->TemplateArguments->size()) {
+      return CXGetTemplateArgumentStatus_InvalidIndex;
+    }
 
-  *TA = SpecInfo->TemplateArguments->get(I);
-  return 0;
+    *TA = SpecInfo->TemplateArguments->get(I);
+    return 0;
+  } else if (const ClassTemplateSpecializationDecl *SD =
+                 llvm::dyn_cast_if_present<
+                     clang::ClassTemplateSpecializationDecl>(
+                     getCursorDecl(C))) {
+    if (I >= SD->getTemplateArgs().size()) {
+      printf("INVALID INDEX\n");
+      return CXGetTemplateArgumentStatus_InvalidIndex;
+    }
+
+    *TA = SD->getTemplateArgs()[I];
+    return 0;
+  } else {
+    printf("CAST FAILED\n");
+    return CXGetTemplateArgumentStatus_BadDeclCast;
+  }
 }
 
 enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -402,6 +402,10 @@
   the behavior of ``QualType::getNonReferenceType`` for ``CXType``.
 - Introduced the new function ``clang_CXXMethod_isDeleted``, which queries
   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
 ---------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to