[PATCH] Add [some] template argument-extraction calls to libclang & cindex

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Oct 6 22:24:43 PDT 2014


Hi Rob,

Thank you for the enhancements in the libclang API!
Looks good, some nitpicks:

+ * If the argument cursor cannot be converted into a template function
+ * declaration, -1 is returned.
<..>
+CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C);

+ * If the argument CXCursor does not represent a FunctionDecl whose I'th
+ * template argument has a kind of ArgKind::Integral, an invalid type is\
+ * returned (in debug mode, this will assert).
<..>
+CINDEX_LINKAGE CXType clang_Cursor_getTemplateArgumentType(CXCursor C,
+                                                           unsigned I);

The convention in the libclang API is that if the function can return an unambiguous invalid value, we do not assert. If you document the behavior of the function ("-1 is returned") you should allow the client to depend on it for both debug and release.
I suggest removing the assertions in clang_Cursor_getNumTemplateArguments and clang_Cursor_getTemplateArgumentType.

+ * If the argument CXCursor does not represent a FunctionDecl whose I'th
+ * template argument has a kind of ArgKind::Integral, an undefined value will be
+ * returned (in debug mode, this call will fail an assert).
<..>
+ * If called with I = 1 or 2, -7 or true will be returned, respectively.
+ * For I == 0, an invalid value will be returned or an assert will be triggered.
+ */
+CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C,
+                                                               unsigned I);

I suggest to keep the assertion in code, but don't document it and be so specific, say "it is undefined to call this function on a CXCursor that does not represent a FunctionDecl or the I'th template argument is not an integral value"
Same for clang_Cursor_getTemplateArgumentUnsignedValue.

+      if (Cursor.kind == CXCursor_FunctionDecl) {
+        // Collect the template parameter kinds from the base template.
+        unsigned NumTemplateArgs = clang_Cursor_getNumTemplateArguments(Cursor);
+        enum CXCursorKind *TemplateParamKinds = (enum CXCursorKind*)
+            malloc(NumTemplateArgs * sizeof(enum CXCursorKind));
+        VisitTemplateParamsData VTPD;
+        VTPD.TemplateParamKinds = TemplateParamKinds;
+        VTPD.CurrentIndex = 0;
+        clang_visitChildren(SpecializationOf, visitTemplateParams,
+                            &VTPD);
+
+        for (unsigned I = 0; I < NumTemplateArgs; I++) {
+          if (TemplateParamKinds[I] == CXCursor_TemplateTypeParameter) {
+            CXType T = clang_Cursor_getTemplateArgumentType(Cursor, I);
+            CXString S = clang_getTypeSpelling(T);
+            printf(" [Template arg %d: type: %s]", I, clang_getCString(S));
+            clang_disposeString(S);
+          } else if (TemplateParamKinds[I] ==
+                     CXCursor_NonTypeTemplateParameter) {
+            printf(" [Template arg %d: intval: %lld]",
+                   I, clang_Cursor_getTemplateArgumentValue(Cursor, I));
+          }
+        }
+        free(TemplateParamKinds);
+      }
     }

This indicates that we are missing another function to make using the others convenient. We are missing a function to get the kind of the I'th template argument, maybe have a function return if the I'th argument is a type or value ?

Also could you please add some tests for this new functionality, e.g. enhance 'test/Index/index-templates.cpp' ?


On Oct 6, 2014, at 2:45 PM, Rob Springer <rspringer at google.com> wrote:

> Factored out common code between clang_Cursor_getTemplateArgumentType, clang_Cursor_getTemplateArgumentValue, and clang_Cursor_getTemplateArgumentUnsignedValue, and simplified test cases.
> 
> http://reviews.llvm.org/D5621
> 
> Files:
>  bindings/python/clang/cindex.py
>  bindings/python/tests/cindex/test_cursor.py
>  include/clang-c/Index.h
>  test/Index/preamble_macro_template.cpp
>  tools/c-index-test/c-index-test.c
>  tools/libclang/CXCursor.cpp
>  tools/libclang/libclang.exports
> <D5621.14476.patch>





More information about the cfe-commits mailing list