[PATCH] [ms-cxxabi] Implement vbtable name mangling
John McCall
rjmccall at apple.com
Tue Apr 16 15:56:10 PDT 2013
On Apr 16, 2013, at 10:20 AM, Reid Kleckner <rnk at google.com> wrote:
> 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.
Looks like a disambiguation thing with some very funky logic.
> 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.
vb-tables are probably emitted strongly with the key function if present,
so a ctor in a different file (e.g. an inline one) theoretically needs to be
able to find them. Although of course they should be relatively trivial
to reproduce in every interested TU.
John.
More information about the cfe-commits
mailing list