[cfe-dev] CXCursor_CXXBaseSpecifier for template instantiated base class

Jusufadis Bakamovic via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 17 02:55:54 PDT 2017


On 16 March 2017 at 22:14, Michael <redm at gmx.de> wrote:
>
> template <typename BaseType>
> class BaseTemplate : public BaseType
> {
>  void bar(BaseType arg1);
> }
>
> template <typename BaseType>
> class RecursiveBase : public BaseTemplate<BaseType>
> {
>  void foo(BaseType arg2);
> }
>

I am not sure if I understood you correctly but:


> You also want to know that the specialised parameter of “BaseTemplate" is
> “Base”
>

Sure, you can get this information once you _instantiate_ a class from your
class template. I.e.
    class Base {};
    class Derived : public RecursiveBase<Base> {};

Traversing the AST and getting to the 'CXCursor_TypeRef's of 'Derived' will
get you this information.


> And you also want to know that arg1 and arg2 of the specialised
> “RecursiveBase” are of type “Base”
>

If you have the information that 'Derived' is built with 'Base', which you
do have, then you should be able to match this information against
'foo()'/'bar()' and corresponding arguments. I.e. if we have the following:

    void fun() {
        Derived d;
        d.foo(Base());
    }

Then AST dump for 'd.foo(Base())' line would look something like this:

|-`CXCursor_UnexposedExpr`: ''
|    |-`CXCursor_CallExpr`: 'foo'
|        |-`CXCursor_MemberRefExpr`: 'foo'
|            |-`CXCursor_UnexposedExpr`: 'd'
|                |-`CXCursor_DeclRefExpr`: 'd'
|        |-`CXCursor_CallExpr`: ''
|            |-`CXCursor_UnexposedExpr`: ''
|                |-`CXCursor_CallExpr`: 'Base'

If we wanted to find out more information about 'foo' we would do the
follow-up on 'CXCursor_MemberRefExpr' : 'foo' node by using a
'clang_getCursorReferenced()' and dumping the information we get from
resulting node. You will find out that type spelling of referenced
(resulting) node will be set to 'void (Base)', and not to 'void (BaseType)'
as it was for a 'RecursiveBase' template class. I am not sure but there
might be a libclang API from this point on wards to get the number of
arguments and their types.

The methods are only accessible through the referenced raw template
> (ClassTemplate?), where you only have the raw template parameters.
> It’s still possible to figure out the types in this case, yes, but it gets
> more and more cumbersome in the more general cases.
>
> With a cursor directly at the specialised version of the template
> everything would already be resolved, readily usable. As you can see when
> dumping the tree with commandline clang. It seems just that libclang does
> not expose that information.
>

Not every use-case is covered and exposed via libclang API. There are
situations where you will have to handle your specific use-cases manually
with your code (as shown above). If shown that these use-cases might be
relevant for general purpose then you might go ahead and issue a patch to
libclang API.

Cheers,
Adi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170317/a1780e1d/attachment.html>


More information about the cfe-dev mailing list