[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:06 PDT 2017


Thanks, Adi! Do you mean that CXCursor_TypeRef is a child under the
CXCursor_CXXBaseSpecifier?

On Fri, Mar 17, 2017 at 1:10 AM, Jusufadis Bakamovic <jbakam at gmail.com> wrote:
> Hi Nestal,
>
> I am not sure if I understood you correctly but you want to find out the
> structure/hierarchy of your "Derived" class, that is all of the base classes
> that your derived class is inheriting from? If this is what you are asking
> for, then you can accomplish this by enumerating all of the
> `CXCursor_TypeRef`'s of corresponding `CXCursor_CXXBaseSpecifier` cursors
> which are descendants (children) of class declaration (`CXCursor_ClassDecl`)
> which you're interested in (i.e. "Derived").
>
> When parser is run on your example, `CXCursor_CXXBaseSpecifier` cursors are
> `RecursiveBase<class Base>`, `class Base2` and `class Base3`. Corresponding
> `CXCursor_TypeRef` cursors are `class Base`, `class Base2` and `class
> Base3`. This is what I believe you're looking for.
>
> For a generic and full-proof solution, you will want to do the same thing
> recursively for each `CXCursor_CXXBaseSpecifier` found.
>
> Cheers,
> Adi
>
> On 14 March 2017 at 17:39, Nestal Wan <me at nestal.net> 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
>> >> >
>> >> >
>> >
>> >
>
>



More information about the cfe-dev mailing list