Using clang_Type_getNumTemplateArguments


I’m trying to use clang_Type_getNumTemplateArguments() to help walk the Cursors emitted by the clang Python binding. Specifically I think I need this function to be able to correctly associate template arguments with the templated entity, for example, in the case of nested templates such as:

template<typename X, typename Y, typename Z, typename O>

Foo<X, Bar<Y, Bleh >, O >

I expect the routine to return 3 for Foo, 2 for Bar and 1 for Bleh. The routine works as I expect in this case:

typedef QStringBuilder<A, B> type;

(Here, A and B are template parameters for the containing class). The value returned by the function is “2”, so given the sequence of Cursors:

TEMPLATE_REF on line 346 ‘::QStringBuilder’


TYPE_REF on line 346 ‘::A’
TYPE_REF on line 346 ‘::B’
TYPEDEF_DECL on line 348 ‘QConcatenable::type’

it is easy to see that both A and B are associated with QStringBuilder. However, for this case:

typedef typename QtStringBuilder::ConvertToTypeHelper<typename QConcatenable::ConvertTo, typename QConcatenable::ConvertTo>::ConvertTo ConvertTo;

the routine returns -1 for each of the three templates:

TYPEDEF_DECL on line 349 ‘QConcatenable::ConvertTo’
NAMESPACE_REF on line 349 ‘::QtStringBuilder’
TEMPLATE_REF on line 349 ‘::ConvertToTypeHelper’
TEMPLATE_REF on line 349 ‘::QConcatenable’
TYPE_REF on line 349 ‘::A’
TEMPLATE_REF on line 349 ‘::QConcatenable’
TYPE_REF on line 349 ‘::B’

I’m not a compiler expert, but I notice that the various clang_{Cursor,Type}_ functions are all documented as applying only to very specific cases, so my question is whether the above represents a bug or expected behaviour? If the behaviour is expected, then is there some other way to walk the cursors and figure out the shape of the AST?

Thanks, Shaheed

P.S. This is with clang+±, on Ubuntu artful.