[cfe-dev] CXCursor_CXXBaseSpecifier for template instantiated base class

Nestal Wan via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 16 11:16:59 PDT 2017


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