r239500 - [MS ABI] Allow fastcall member function pointers to get CodeGen'd

David Majnemer david.majnemer at gmail.com
Wed Jun 10 17:45:45 PDT 2015


Author: majnemer
Date: Wed Jun 10 19:45:44 2015
New Revision: 239500

URL: http://llvm.org/viewvc/llvm-project?rev=239500&view=rev
Log:
[MS ABI] Allow fastcall member function pointers to get CodeGen'd

This restriction appears unnecessary and most likely came about during
early work for musttail.

Modified:
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=239500&r1=239499&r2=239500&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Jun 10 19:45:44 2015
@@ -2423,20 +2423,15 @@ MicrosoftCXXABI::BuildMemberPointer(cons
     FirstField = CGM.GetAddrOfFunction(MD, Ty);
     FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
   } else {
-    if (FPT->getCallConv() == CC_X86FastCall) {
-      CGM.ErrorUnsupported(MD, "pointer to fastcall virtual member function");
-      FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
-    } else {
-      auto &VTableContext = CGM.getMicrosoftVTableContext();
-      MicrosoftVTableContext::MethodVFTableLocation ML =
-          VTableContext.getMethodVFTableLocation(MD);
-      llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
-      FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
-      // Include the vfptr adjustment if the method is in a non-primary vftable.
-      NonVirtualBaseAdjustment += ML.VFPtrOffset;
-      if (ML.VBase)
-        VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
-    }
+    auto &VTableContext = CGM.getMicrosoftVTableContext();
+    MicrosoftVTableContext::MethodVFTableLocation ML =
+        VTableContext.getMethodVFTableLocation(MD);
+    llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
+    FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
+    // Include the vfptr adjustment if the method is in a non-primary vftable.
+    NonVirtualBaseAdjustment += ML.VFPtrOffset;
+    if (ML.VBase)
+      VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
   }
 
   // The rest of the fields are common with data member pointers.

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp?rev=239500&r1=239499&r2=239500&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vmemptr-fastcall.cpp Wed Jun 10 19:45:44 2015
@@ -1,11 +1,15 @@
-// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm-only -verify
-
-// We reject this because LLVM doesn't forward the second regparm through the
-// thunk.
+// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s
 
 struct A {
-  virtual void __fastcall f(int a, int b); // expected-error {{cannot compile this pointer to fastcall virtual member function yet}}
+  virtual void __fastcall f(int a, int b);
 };
 void (__fastcall A::*doit())(int, int) {
   return &A::f;
 }
+
+// CHECK: define linkonce_odr x86_fastcallcc void @"\01??_9A@@$BA at AI"(%struct.A* inreg %this, ...) {{.*}} comdat align 2 {
+// CHECK: [[VPTR:%.*]] = getelementptr inbounds void (%struct.A*, ...)*, void (%struct.A*, ...)** %vtable, i64 0
+// CHECK: [[CALLEE:%.*]] = load void (%struct.A*, ...)*, void (%struct.A*, ...)** [[VPTR]]
+// CHECK: musttail call x86_fastcallcc void (%struct.A*, ...) [[CALLEE]](%struct.A* inreg %{{.*}}, ...)
+// CHECK: ret void
+// CHECK: }





More information about the cfe-commits mailing list