[PATCH] [ms-cxxabi] Implement member data pointers for non-dynamic classes

John McCall rjmccall at apple.com
Thu Mar 21 18:45:14 PDT 2013


On Mar 21, 2013, at 6:19 PM, Reid Kleckner <rnk at google.com> wrote:
> +  // FIXME: Emit a pair of {vbtable offset, field offset} when we know vbtable
> +  // layout.
> +  return GetBogusMemberPointer(QualType(MPT, 0));
> 
> I don't think this ever actually comes up here.  If it did, you'd need a
> totally different interface anyway.
> 
> Yeah, we do need a different interface.  Testing this case hits assertions.

Oh, sorry, this case *will* come up, but only with a "null" vbtable offset.
The trick is that &A::foo always has the type of the actual member;  the type
"A" only matters for lookup.

That is, if you have:
  struct A { int x, y; };
  struct B : virtual A { int z; };
then "&B::x" has type int A::*.  (This is supposed to ignore using decls, too.)

Therefore, when you're forming a member pointer constant from a field,
the constant itself will always refer to a direct member of the base type of the
member pointer type.  That doesn't mean you can't have member pointer
constants that have vbase-offset fields — case in point, &B::z — but it does
mean that those fields will always be the null value.

That's assuming that MSVC follows the language rules about the type of a
member pointer constant, of course.

> +  // For member data pointers, this is just a check against -1 or 0.
> +  if (MPT->isMemberDataPointer()) {
> +    assert(MemPtr->getType() == getPtrDiffTy());
> +    llvm::Constant *Val = getNullMemberDataPointer(MPT);
> +    return Builder.CreateICmpNE(MemPtr, Val, "memptr.tobool");
> +  }
> 
> You forgot the virtual inheritance case here.
> 
> OK, fixed, that will issue an error instead of asserting now.

> I haven't figured out exactly how to do this with a virtual base yet, and Timur says that Clang currently has very little support for virtual inheritance.  I'd rather handle simple member data pointers that are just offsets first, and then come back when we tackle virtual inheritance.

Okay.  I mean, to me it makes sense to get easy cases out of the way while
you're thinking about them, but it's ultimately up to you.

I'm pretty sure that the way that this works with virtual bases work is that, if
the vbase offset field isn't null (and I'm not sure what that null value is), then
it's an offset within the primary vbtbl for the class.  So you ask the record
layout for the offset of the vbtbl, load the vbtbl, add the offset, load a size_t
out of that, and then just add that to the non-virtual offset.

What this implies is that the act of converting member pointers between
classes that don't use the same primary vbtbl potentially involves a
case-by-case conversion between vbase offsets ("for offset 0, use offset 4;
for offset 4, use offset 12;  for offset 8, use offset 0"), because there's no
fixed relationship between the order of vbases in different vbtbls.

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130321/c9eaa193/attachment.html>


More information about the cfe-commits mailing list