[cfe-dev] CXCursor_CXXBaseSpecifier for template instantiated base class

Michael via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 16 12:01:34 PDT 2017


Well, at least for me it didn't really help, it did not do what I would 
have expected it to do... i.e. return the specialized versions of the 
template, "RecursiveBase<Base>" and more importantly it's base "Base" in 
your example.


On 03/16/2017 07:16 PM, Nestal Wan wrote:
> Yes. I think clang_getSpecializedCursorTemplate() will definitely be
> useful for me. Thanks for the info.
>
> On Thu, Mar 16, 2017 at 2:02 AM, Michael via cfe-dev
> <cfe-dev at lists.llvm.org> wrote:
>> 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
>>
>>
>>
>> _______________________________________________
>> 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