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

r4start r4start at gmail.com
Fri Nov 11 00:09:13 PST 2011


On 11/11/2011 11:28, John McCall wrote:
> 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.
This information is need to implement RTTI Class Hierarchy Descriptor in 
MS ABI.
This struct has following fields:
struct RTTIClassHierarchyDescriptor
{
     DWORD signature;      //always zero?
     DWORD attributes;     //bit 0 set = multiple inheritance, bit 1 set 
= virtual inheritance
     DWORD numBaseClasses; //number of classes in pBaseClassArray
     struct RTTIBaseClassArray* pBaseClassArray;
};
Yesterday I discovered that third bit(bit 2) in attributes field set 
when we have class like A1.
If you need more information about it you can see this link 
http://www.openrce.org/articles/full_view/23 .

  - Dmitry.



More information about the cfe-dev mailing list