[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