[PATCH] [ms-cxxabi] Correctly compute the size of member pointers

John McCall rjmccall at apple.com
Fri Mar 22 13:44:12 PDT 2013


On Mar 22, 2013, at 11:41 AM, Reid Kleckner <rnk at google.com> wrote:
>    - Update the test case to pass under x86_64.
> 
> Hi rjmccall,
> 
> http://llvm-reviews.chandlerc.com/D568

+    // FIXME: Handling x86_64 will require changing this method to return sizes
+    // in bytes instead of pointers.  Some member pointer sizes are not
+    // multiples of a pointer size.

So, change the method to return sizes in bytes instead of pointers instead
of reporting a diagnostic in a core AST routine.

+  attr::Kind Inheritance;

+      // This last case seems like an error, but MSVC allocates one more slot
+      // than is used for virtual inheritance.  We follow suit for
+      // compatibility.

My understanding is that it's required for vtordisps or something.

+      // FIXME: Issue a warning.

Well, you wouldn't issue a warning in the AST library, so the FIXME doesn't
go here.

+    if (Attr *IA = RD->getAttr<SingleInheritanceAttr>())
+      Inheritance = IA->getKind();
+    else if (Attr *IA = RD->getAttr<MultipleInheritanceAttr>())
+      Inheritance = IA->getKind();
+    else if (Attr *IA = RD->getAttr<VirtualInheritanceAttr>())
+      Inheritance = IA->getKind();

You should really make a common base class for these attributes.
I believe this is just as simple as adding:
  class MSInheritanceAttr : InheritableAttr;
to Attr.td, making the attribute defs inherit from that, and then defining that
class in Attr.h.

+// getNumBases() seems to only give us the number of direct bases, and not the
+// total.  This function tells us if we inherit from anybody that uses MI.
+static bool recordHasMultipleInheritance(const CXXRecordDecl *RD) {
+  while (RD->getNumBases() > 0) {
+    if (RD->getNumBases() > 1)
+      return true;
+    assert(RD->getNumBases() == 1);
+    RD = RD->bases_begin()->getType()->getAsCXXRecordDecl();
+  }
+  return false;
+}

Hmm.  I bet that non-primary base class forces the "multiple inheritance" case:
  struct A { int x; void bar(); };
  struct B : A { virtual void foo(); };
What's sizeof(void (B::*)())?

+  switch (Inheritance) {
+  case attr::SingleInheritance:
+    return 1;
+  case attr::MultipleInheritance:
+    return 1 + int(Pointee->isFunctionType());
+  case attr::VirtualInheritance:
+    return 2 + int(Pointee->isFunctionType());

Please try to avoid doing the somewhat-expensive query about multiple
inheritance if this is a non-function member pointer.

John.



More information about the cfe-commits mailing list