[cfe-dev] How to determine base class direct or not?

John McCall rjmccall at apple.com
Thu Nov 10 23:28:43 PST 2011


On Nov 10, 2011, at 9:24 PM, r4start wrote:
> On 11/11/2011 01:27, John McCall wrote:
>> On Nov 10, 2011, at 5:35 AM, r4start wrote:
>>> Can anybody help me with following problem. I have such code:
>>> class B {
>>> public:
>>>   virtual void b(){}
>>>   double b_field;
>>> };
>>> 
>>> struct D : B {
>>>   virtual void fr(){}
>>> };
>>> 
>>> class C {
>>> public:
>>>   virtual void C_f(){}
>>> };
>>> 
>>> class A : public C,
>>>           public virtual D {
>>> public:
>>>   int a_field;
>>>   virtual void a(){}
>>> };
>>> class A1 : public C, public B,
>>>           public virtual D {
>>> public:
>>>   int a_field;
>>>   virtual void a(){}
>>> };
>>> 
>>> I write function that determines "Has class and his bases a common base?".
>>> For example for class A this function returns false and for class A1 -
>>> true. In A1 as you can see B is base class for A1 and for D.
>>> I tried to use isDerivedFrom(), but this function searches path from A
>>> to B(path is A->D->B) and if path exists return true.
>>> I need something like isDirectDerivedFrom.
>>> 
>>> So my question is, what is the best way to determine these relations?
>> You're trying to ask whether a type is directly named by one
>> of the base specifiers?  I don't think we have a utility function
>> for that, but you can just walk the class's base specifiers directly.
>> 
>> John.
> Yes, you are right.
> Now I have such code:
> for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
>       E = RD->bases_end(); I!= E; ++I) {
>    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
> 
>    for (CXXRecordDecl::base_class_const_iterator IB = Base->bases_begin(),
>         EB = Base->bases_end(); IB != EB; ++IB) {
> 
>      for (CXXRecordDecl::base_class_const_iterator II = RD->bases_begin(),
>           EE = RD->bases_end(); II != EE; ++II) {
> 
>        if (IB->getType()->getAsCXXRecordDecl() ==
>            II->getType()->getAsCXXRecordDecl())
>          return true;
>      }
>    }
>  }
> I think it is not good approach, but I can`t think of alternatives.

You could iterate over each of RD's bases and check whether there
are multiple paths from RD to the base.

I'm curious what this is for.  Just a warning about having redundant
copies of a base class?  The easiest algorithm would probably be
to do a search of the hierarchy and track what classes you find.

John.



More information about the cfe-dev mailing list