[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