[cfe-dev] CXCursor_CXXBaseSpecifier for template instantiated base class

Michael via cfe-dev cfe-dev at lists.llvm.org
Wed Mar 15 11:02:27 PDT 2017


This is an interesting question I was also wondering about the other 
day... (sorry, if you were hoping for an answer;)

The best thing I figured out was: get the type of template parameter 
RecursiveBase<Base> (via clang_Type_getTemplateArgumentAsType), then go 
to the referenced template RecursiveBase and do the parameter mapping 
myself. Of course this will get more complicated if that again derives 
from a template using that parameter...

Running the example through "clang++ -Xclang -ast-dump -fsyntax-only .." 
I see the needed ClassTemplateSpecializationDecls, also for further base 
templates, carrying the proper specialized parameter types...

I would have expected clang_getSpecializedCursorTemplate giving me these 
specialized versions of the templates, but either I understand it wrong 
what is supposed to do or it's implementation is incomplete here? Some 
insight on this question would be appreciated.

Thanks

Michael


On 03/14/2017 05:39 PM, Nestal Wan via cfe-dev wrote:
> Thanks Adi,
>
> Like you said, I solve the problem by fixing the errors that were
> indicated by the diagnostic messages.
>
> Now I have another question, if you don't mind I keep using this thread.
>
> I wish know the class hierarchy of "Derived". That means getting the
> base class the the instantiated RecursiveBase<Base> template. That
> should be "Base".
>
> When I visit "Dervied", I got a cursor to a CXCursor_CXXBaseSpecifier.
> I tried to get the type by:
>
> CXType recursive_base =
> clang_getCursorType(clang_getCursorDefinition(cxx_base_specifier));
>
> "recursive_base" refers to the RecursiveBase<Base> instantiation. How
> can I get the base type of this class? I know I can get the cursor to
> the template that instantiate it (i.e. template <typename BaseType>
> RecursiveBase), and I can see it inherits "BaseType" by visiting it
> and look for CXCursor_CXXBaseSpecifier. But how can I know "BaseType"
> will become "Base" when we instantiate it? Will the CXType provides me
> this linkage or I need to use LibTooling instead?
>
> Thanks again.
>
> Nestal
>
> On Sun, Mar 12, 2017 at 9:25 PM, Jusufadis Bakamovic <jbakam at gmail.com> wrote:
>> It is hard to tell without more context why you're getting this error, but
>> my guess is that you're missing some command line args (i.e. include paths,
>> preprocessor flags, etc.) which is specific to the code you're analyzing and
>> which is required in order to get the parsing stage done right. Very often
>> this is the case and which is why you should, whenever you have doubts,
>> always try to come up with a small reproducible example (without
>> dependencies) and have it validated separately.
>>
>> Additionally, you can try to extract diagnostics for the given translation
>> unit and see if you get any hints there. Normally, you should get hints if
>> clang parser was not able to fully parse the source code because it was
>> missing some information such as failing to find particular headers.
>>
>> Cheers,
>> Adi
>>
>> On 12 March 2017 at 10:13, Nestal Wan <me at nestal.net> wrote:
>>> Thanks for the reply.
>>>
>>> -CXXRecordDecl 0x55e6db0f5ad8 <line:53:1, line:59:1> line:53:7 invalid
>>> class
>>> Derived definition
>>>
>>> | |-public 'class Base2'
>>> | |-public 'class Base3'
>>> | |-CXXRecordDecl 0x55e6db0f5df8 <col:1, col:7> col:7 implicit referenced
>>>
>>> class Derived
>>>
>>> | |-AccessSpecDecl 0x55e6db0f5e88 <line:55:1, col:7> col:1 public
>>> | |-CXXConstructorDecl 0x55e6db0f5ef0 <line:56:2, col:20> col:2 Derived
>>> 'void
>>>
>>> (void)' noexcept-unevaluated 0x55e6db0f5ef0
>>>
>>> | `-CXXMethodDecl 0x55e6db0f5fd0 <line:58:2, col:24> col:7 Func 'void
>>> (void)'
>>> | `-CompoundStmt 0x55e6db0f6118 <col:23, col:24>
>>>
>>>
>>> Sometimes I got "invalid class Derived definition", but if I extract the
>>> classes in another source file, the result is different:
>>>
>>> |-CXXRecordDecl 0x55ccfcb583b0 <line:33:1, line:39:1> line:33:7 class
>>> Derived
>>>
>>> definition
>>>
>>> | |-public 'RecursiveBase<class Base>':'class RecursiveBase<class Base>'
>>> | |-public 'class Base2'
>>> | |-public 'class Base3'
>>> | |-CXXRecordDecl 0x55ccfcb58c70 <col:1, col:7> col:7 implicit referenced
>>>
>>> class Derived
>>>
>>> What does it mean the class definition is invalid? There is no compile
>>> error.
>>>
>>> Nestal
>>>
>>> On Sun, Mar 12, 2017 at 4:46 PM, Jusufadis Bakamovic <jbakam at gmail.com>
>>> wrote:
>>>> You should be getting three times the `CXCursor_CXXBaseSpecifier`, one
>>>> for
>>>> each class you're inheriting from. I ran the analysis on my machine
>>>> (clang
>>>> 3.8) and that is exactly what I am getting: `RecursiveBase<class Base>`,
>>>> `Base2`, `Base3`. Maybe you could use `clang -Xclang -ast-dump
>>>> -fsyntax-only
>>>> <this_demo>` to see the output of Clang's built-in AST dumper. It should
>>>> contain these entries. Otherwise, clang version you're running might be
>>>> an
>>>> older one.
>>>>
>>>> On 12 March 2017 at 05:09, Nestal Wan via cfe-dev
>>>> <cfe-dev at lists.llvm.org>
>>>> wrote:
>>>>> Hi,
>>>>>
>>>>> When I use clang_visitChildren() to visit a class, I can't get a
>>>>> CXCursor_CXXBaseSpecifier for its base class if the base class is a
>>>>> template. For example:
>>>>>
>>>>> template <typename BaseType>
>>>>> class RecursiveBase : public BaseType
>>>>> {
>>>>> public:
>>>>>     virtual void SomeFunc()
>>>>>     {
>>>>>        // prevent optimizer to remove the function
>>>>>        global_var++;
>>>>>     }
>>>>> };
>>>>>
>>>>> class Derived : public RecursiveBase<Base>, public Base2, public Base3
>>>>> {
>>>>> public:
>>>>>     Derived() = default;
>>>>>
>>>>>     void Func() override {}
>>>>> };
>>>>>
>>>>> I can get a CXCursor_CXXBaseSpecifier cursor as children of the
>>>>> "Derived" cursor, but not RecursiveBase. How can I find out references
>>>>> to all base classes including templates?
>>>>>
>>>>> Thanks.
>>>>>
>>>>> Nestal
>>>>> _______________________________________________
>>>>> cfe-dev mailing list
>>>>> cfe-dev at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>>
>>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





More information about the cfe-dev mailing list