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

Reid Kleckner rnk at google.com
Fri Apr 12 10:59:23 PDT 2013


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?

> 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'

I can indirect B through a non-virtual base, though:
struct A { int a; };
struct B : virtual A { int b; };
struct C : virtual B { int c; };
struct BB : B { };  // Indirection =/
struct D : BB, C { int d; };
D d; // Force vbtable emission.

That gives these manglings:

??_8B@@7B@
??_8C@@7B0@@
??_8C@@7BB@@@
??_8BB@@7B@

// D's vbtables:
??_8D@@7B@          // installed inside the non-virtual B
??_8D@@7BC@@@   // installed inside C
??_8D@@7BB@@@   // installed inside virtual B

>> +bool CXXRecordDecl::hasDirectVirtualBase() const {
>> +  for (CXXRecordDecl::base_class_const_iterator I = this->bases_begin(),
>> +       E = this->bases_end(); I != E; ++I) {
>> +    if (I->isVirtual())
>> +      return true;
>> +  }
>> +  return false;
>> +}
>> +
>
> I really doubt you actually need this.
>
>> +      // If Base is the only non-virtual base of its parent, we can skip this
>> +      // link in the path and still guarantee that this is a unique symbol.
>> +      if ((*I)->getNumBases() == 1 && !(*I)->hasDirectVirtualBase())
>> +        continue;
>
> This is just ((*)->getNumBases() == 1 && !(*(*I)->bases_begin())->isVirtual()),
> but I'm very skeptical about this computation.
>
> The deep question here, which I can't really answer myself without seeing
> tests, is when, exactly, MSVC adds base-path information to the mangling?
> If I were designing this, I would add it only when a class has multiple non-virtual
> bases, and I would only add it to "secondary" vb-tables — i.e. to vb-tables that
> are not the "primary" vb-table, i.e. not the one that I would add the new entries
> to if my class added new virtual bases.  And I'd need some way to distinguish
> paths that correspond to morally virtual base sub-objects, e.g. to handle my
> test case above.

I see.  I had something similar to including path elements only when
there are multiple non-virtual bases, but it wasn't quite right.

Your test case also shows that I'm currently messing up the "primary"
vbptr case, which I currently mangle as ??_8D at Test9@@7BBB at 1@@.




More information about the cfe-commits mailing list