r201722 - MS ABI: Let non-virtual method overloads participate in vftable ordering

Reid Kleckner reid at kleckner.net
Wed Feb 19 14:06:10 PST 2014


Author: rnk
Date: Wed Feb 19 16:06:10 2014
New Revision: 201722

URL: http://llvm.org/viewvc/llvm-project?rev=201722&view=rev
Log:
MS ABI: Let non-virtual method overloads participate in vftable ordering

In the Microsoft ABI, the vftable is laid out as if all methods in every
overload set were declared in reverse order of declaration at the point
of declaration of the first overload in the set.

Previously we only considered virtual methods in an overload set, but
MSVC includes non-virtual methods for ordering purposes.

Fixes PR18902.

Modified:
    cfe/trunk/lib/AST/VTableBuilder.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp

Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=201722&r1=201721&r2=201722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
+++ cfe/trunk/lib/AST/VTableBuilder.cpp Wed Feb 19 16:06:10 2014
@@ -2789,7 +2789,7 @@ static void GroupNewVirtualOverloads(
   // Put the virtual methods into VirtualMethods in the proper order:
   // 1) Group overloads by declaration name. New groups are added to the
   //    vftable in the order of their first declarations in this class
-  //    (including overrides).
+  //    (including overrides and non-virtual methods).
   // 2) In each group, new overloads appear in the reverse order of declaration.
   typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup;
   SmallVector<MethodGroup, 10> Groups;
@@ -2798,16 +2798,14 @@ static void GroupNewVirtualOverloads(
   for (CXXRecordDecl::method_iterator I = RD->method_begin(),
        E = RD->method_end(); I != E; ++I) {
     const CXXMethodDecl *MD = *I;
-    if (!MD->isVirtual())
-      continue;
 
     VisitedGroupIndicesTy::iterator J;
     bool Inserted;
     llvm::tie(J, Inserted) = VisitedGroupIndices.insert(
         std::make_pair(MD->getDeclName(), Groups.size()));
     if (Inserted)
-      Groups.push_back(MethodGroup(1, MD));
-    else
+      Groups.push_back(MethodGroup());
+    if (I->isVirtual())
       Groups[J->second].push_back(MD);
   }
 

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp?rev=201722&r1=201721&r2=201722&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp Wed Feb 19 16:06:10 2014
@@ -15,6 +15,8 @@
 // RUN: FileCheck --check-prefix=CHECK-M %s < %t
 // RUN: FileCheck --check-prefix=CHECK-N %s < %t
 // RUN: FileCheck --check-prefix=CHECK-O %s < %t
+// RUN: FileCheck --check-prefix=CHECK-Q %s < %t
+// RUN: FileCheck --check-prefix=CHECK-R %s < %t
 
 struct A {
   // CHECK-A: VFTable for 'A' (3 entries)
@@ -260,3 +262,28 @@ P p;
 
 // CHECK-O: VFTable for 'O' (1 entries)
 // CHECK-O-NEXT: 0 | A *O::f()
+
+struct Q {
+  // CHECK-Q: VFTable for 'Q' (2 entries)
+  // CHECK-Q-NEXT: 0 | void Q::foo(int)
+  // CHECK-Q-NEXT: 1 | void Q::bar(int)
+  void foo(short);
+  void bar(short);
+  virtual void bar(int);
+  virtual void foo(int);
+};
+
+Q q;
+
+// Inherited non-virtual overloads don't participate in the ordering.
+struct R : Q {
+  // CHECK-R: VFTable for 'Q' in 'R' (4 entries)
+  // CHECK-R-NEXT: 0 | void Q::foo(int)
+  // CHECK-R-NEXT: 1 | void Q::bar(int)
+  // CHECK-R-NEXT: 2 | void R::bar(long)
+  // CHECK-R-NEXT: 3 | void R::foo(long)
+  virtual void bar(long);
+  virtual void foo(long);
+};
+
+R r;





More information about the cfe-commits mailing list