[PATCH] [ms-cxxabi] Implement vbtable name mangling

Reid Kleckner rnk at google.com
Tue Apr 16 10:20:29 PDT 2013


On Tue, Apr 16, 2013 at 12:25 PM, John McCall <rjmccall at apple.com> wrote:
> On Apr 16, 2013, at 6:42 AM, Reid Kleckner <rnk at google.com> wrote:
>> On Fri, Apr 12, 2013 at 2:42 PM, John McCall <rjmccall at apple.com> wrote:
>>> On Apr 12, 2013, at 10:59 AM, Reid Kleckner <rnk at google.com> wrote:
>>>> On Wed, Apr 10, 2013 at 4:12 PM, John McCall <rjmccall at apple.com> wrote:
>>>>> On Apr 6, 2013, at 3:44 PM, Reid Kleckner <rnk at google.com> wrote:
>>>>>> +  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
>>>>>> +                                llvm::ArrayRef<const CXXRecordDecl *> BasePath,
>>>>>
>>>>> This needs to be a path of CXXBaseSpecifier*s.  One, that's probably
>>>>> more straightforward to create, and two, there's an ambiguity here that
>>>>> it'd clean up.
>>>>
>>>> Should I be rolling my own recursion here to discover all unique
>>>> subobjects, or is there some method on CXXBasePaths I should be
>>>> calling to generate these?
>>>
>>> A CXXBasePathElement stores the Base.
>>>
>>>>> For example:
>>>>> struct A { int x; };
>>>>> struct B : virtual A {}; // vbptrs: B
>>>>> struct C : virtual B {}; // vbptrs: C, virtual B in C
>>>>> struct D : B, C {}; // vbptrs: B in D, C in D, virtual B in D
>>>>>
>>>>> Incidentally, how would these actually be mangled?
>>>>
>>>> That program gives:
>>>> error C2584: 'D' : direct base 'B' is inaccessible; already a base of 'C'
>>>
>>> Oh, right, yes, sorry.
>>
>> Re-ordering B and C gets through with a warning instead of an error:
>> struct A { int a; };
>> struct B : virtual A { int b; };
>> struct C : virtual B { int c; };
>> struct D : C, B { int d; };
>> D d;
>>
>> warning C4584: 'D' : base-class 'B' is already a base-class of 'C'
>
> Hah.  I don't think that's an extension we need to stress over supporting.
>
>> I'm still stumped on the logic for the symbols this produces though:
>>
>> # B's vbtable for itself
>> ??_8B@@7B@
>>
>> # C's vbtables, self then for B
>> ??_8C@@7B0@@
>> ??_8C@@7BB@@@
>>
>> # D's vbtables.
>> ??_8D@@7BC@@@  # vbptr inside C
>> ??_8D@@7B@           # vbptr inside non-virtual B
>> ??_8D@@7BB@@@  # vbptr inside morally virtual B
>>
>> I would expect this to be mangled as:
>> ??_8D@@7BC@@@  # same
>> ??_8D@@7BB@@@  # because there is ambiguity between B and C
>> ??_8D@@7BB@@C@@@  # same
>>
>> Adding another level of non-virtual inheritance gives deeper paths:
>> struct E : D, C, B { int e; };
>>
>> ??_8E@@7BC@@D@@@  # vbptr in C in D in E
>> ??_8E@@7BD@@@     # vbptr in non-virtual B in D in E
>> ??_8E@@7BC@@@     # vbptr in C in E
>> ??_8E@@7BB@@@     # vbptr in non-virtual B in E
>> ??_8E@@7BB@@D@@@  # vbptr in virtual B in C in D in E
>>
>> It seems weird to me that the symbol for vbtables installed inside
>> morally virtual bases includes non-virtual path steps.  That means the
>> symbol depends on which path you follow to find the virtual base.
>> That said, the path order is fairly obvious.
>
> How dependent are the manglings on each other?  Like, if you remove
> the direct 'B' base here, do any of the other manglings change?

Things change.  :(

When removing the nv B from E, the symbols go from this:
??_8E@@7BC@@D@@@
??_8E@@7BD@@@     # nv B in D
??_8E@@7BC@@@
??_8E@@7BB@@@     # nv B in E
??_8E@@7BB@@D@@@  # virtual B in C in D

To this:
??_8E@@7BC@@D@@@
??_8E@@7B@     # nv B in D
??_8E@@7BC@@@
??_8E@@7BB@@@  # virtual B in C in D

I'll have to think on it.

At some point I may give up on these deep hierarchies.  I *think* it
should be safe to get the name wrong, so long as it doesn't collide
with anything else.  The only reference to vbtables that I know of is
in the constructor, and as long as it produced objects that have
vbtables with the correct entries (easily done), everything should
work.



More information about the cfe-commits mailing list