[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