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

John McCall rjmccall at apple.com
Tue Apr 16 16:17:58 PDT 2013


On Apr 16, 2013, at 3:56 PM, John McCall <rjmccall at apple.com> wrote:
> 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.

That was a useless statement, sorry.

I mean that it looks like it's making some sort of (breadth-first-ish?)
pass through the bases and then, as it encounters bases that would
mangle ambiguously, maybe adding paths to disambiguate as
necessary.  And I think the simultaneous indirect-virtual-and-direct-NV
case might trip some really funky workaround logic.

John.



More information about the cfe-commits mailing list