[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-05 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6b104ea4b463: Implement Lambda Conversion Operators for All 
CCs for MSVC. (authored by erichkeane).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp

Index: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
===
--- clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
+++ clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
 
 #ifndef CC
 #define CC
@@ -10,20 +10,36 @@
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 
   double (*CC fp)(int, float, double) = lambda;
-  fp(0, 1.1, 2.2);
 #ifdef WIN32
   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
+  double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
+  double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
+  double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
+#endif // WIN32
+  fp(0, 1.1, 2.2);
+#ifdef WIN32
   fp2(0, 1.1, 2.2);
+  fp3(0, 1.1, 2.2);
+  fp4(0, 1.1, 2.2);
+  fp5(0, 1.1, 2.2);
 #endif // WIN32
+
+  auto x = +lambda;
 }
 
-// void usage function, calls convrsion operator.
+// void usage function, calls conversion operator.
 // LIN64: define void @_Z5usagev()
 // VECCALL: define void @_Z5usagev()
 // WIN32: define dso_local void @"?usage@@YAXXZ"()
 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// Operator+ calls 'default' calling convention.
+// CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 //
 // Conversion operator, returns __invoke.
 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
@@ -32,6 +48,12 @@
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CA?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
 //
 // __invoke function, calls operator(). Win32 should call both.
 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
@@ -42,3 +64,9 @@
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_stdcallcc double @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_fastcallcc double @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_vectorcallcc double @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/S

[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 302827.
erichkeane added a comment.

Added test for +lambda as @rsmith requested.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp

Index: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
===
--- clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
+++ clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
 
 #ifndef CC
 #define CC
@@ -10,20 +10,36 @@
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 
   double (*CC fp)(int, float, double) = lambda;
-  fp(0, 1.1, 2.2);
 #ifdef WIN32
   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
+  double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
+  double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
+  double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
+#endif // WIN32
+  fp(0, 1.1, 2.2);
+#ifdef WIN32
   fp2(0, 1.1, 2.2);
+  fp3(0, 1.1, 2.2);
+  fp4(0, 1.1, 2.2);
+  fp5(0, 1.1, 2.2);
 #endif // WIN32
+
+  auto x = +lambda;
 }
 
-// void usage function, calls convrsion operator.
+// void usage function, calls conversion operator.
 // LIN64: define void @_Z5usagev()
 // VECCALL: define void @_Z5usagev()
 // WIN32: define dso_local void @"?usage@@YAXXZ"()
 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// Operator+ calls 'default' calling convention.
+// CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 //
 // Conversion operator, returns __invoke.
 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
@@ -32,6 +48,12 @@
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CA?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
 //
 // __invoke function, calls operator(). Win32 should call both.
 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
@@ -42,3 +64,9 @@
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_stdcallcc double @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_fastcallcc double @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_vectorcallcc double @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1272,6 +1272,34 @@
   CallOpProto.isVariadic(), /*IsCXXMethod=*/true);
   Calli

[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp:10
 void usage() {
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 

rsmith wrote:
> Does lambda-to-function-pointer decay still work (eg, `+lambda` or 
> `*lambda`)? It'd be good to test that, since it's a fairly common idiom.
It does! I tested that in the last patch, but don't seem to have a codegen test 
for it, so I'll make sure to add it.

I ended up having to do a tiebreaker as you suggested in that patch as well.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/Sema/SemaLambda.cpp:1285
+  /// that someone who intentionally places 'thiscall' on the lambda call
+  /// operator will still get that overload, since we don't have the a way of
+  /// detecting the attribute by the time we get here.





Comment at: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp:10
 void usage() {
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 

Does lambda-to-function-pointer decay still work (eg, `+lambda` or `*lambda`)? 
It'd be good to test that, since it's a fairly common idiom.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D90634#2371436 , @aaron.ballman 
wrote:

> This LGTM but you should wait a day or so in case @rjmccall has opinions.

Thanks, will do!




Comment at: clang/lib/Sema/SemaLambda.cpp:1281
+  /// Additionally, we are ensuring that the default-free/default-member and
+  /// call-operator calling convention are generated as well.
+  if (S.getLangOpts().MSVCCompat) {

aaron.ballman wrote:
> Should we call out that one of the existing member functions is likely to be 
> `thiscall` which means we'll generate a version of the operator for that 
> calling convention even though MSVC doesn't, but we want to do this because 
> users can explicitly write the CC on the lambda (unlike in MSVC)? (I'm 
> worried that lack of mention about `thiscall` may look like a bug to someone 
> a few years down the line.)
Can do!  I put it in the commit message as well, 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

This LGTM but you should wait a day or so in case @rjmccall has opinions.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 302595.
erichkeane marked 2 inline comments as done.
erichkeane added a comment.

Made another attempt at fixing the comment.  Wordsmithing welcomed/encouraged :)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp

Index: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
===
--- clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
+++ clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
 
 #ifndef CC
 #define CC
@@ -10,20 +10,31 @@
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 
   double (*CC fp)(int, float, double) = lambda;
-  fp(0, 1.1, 2.2);
 #ifdef WIN32
   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
+  double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
+  double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
+  double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
+#endif // WIN32
+  fp(0, 1.1, 2.2);
+#ifdef WIN32
   fp2(0, 1.1, 2.2);
+  fp3(0, 1.1, 2.2);
+  fp4(0, 1.1, 2.2);
+  fp5(0, 1.1, 2.2);
 #endif // WIN32
 }
 
-// void usage function, calls convrsion operator.
+// void usage function, calls conversion operator.
 // LIN64: define void @_Z5usagev()
 // VECCALL: define void @_Z5usagev()
 // WIN32: define dso_local void @"?usage@@YAXXZ"()
 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
 //
 // Conversion operator, returns __invoke.
 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
@@ -32,6 +43,12 @@
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CA?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
 //
 // __invoke function, calls operator(). Win32 should call both.
 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
@@ -42,3 +59,9 @@
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_stdcallcc double @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_fastcallcc double @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_vectorcallcc double @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1272,6 +1272,34 @@
   CallOpProto.isVariadic(), /*IsCXXMethod=*/true);
   CallingConv CallOpCC = CallOpProto.getCallConv();
 
+  /// Implement emitting a version of the operator for many of the calling
+  /// conventions for MSVC, as described here:
+

[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Sema/SemaLambda.cpp:1282
+  /// call-operator calling convention are generated as well.
+  /// NOTE: We intentionally generate a 'thiscall' (on Win32) despite MSVC not.
+  /// We do this in order to ensure that someone who intentionally places

If we're intentionally generating it, should it be listed explicitly in `Convs` 
below? (If not, then perhaps change the comment somewhat to "We intentionally 
generate a 'thiscall' (on Win32) implicitly from the default member call's 
calling convention..."?)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 302562.
erichkeane added a comment.

update comment as @aaron.ballman requested.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp

Index: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
===
--- clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
+++ clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
 
 #ifndef CC
 #define CC
@@ -10,20 +10,31 @@
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 
   double (*CC fp)(int, float, double) = lambda;
-  fp(0, 1.1, 2.2);
 #ifdef WIN32
   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
+  double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
+  double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
+  double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
+#endif // WIN32
+  fp(0, 1.1, 2.2);
+#ifdef WIN32
   fp2(0, 1.1, 2.2);
+  fp3(0, 1.1, 2.2);
+  fp4(0, 1.1, 2.2);
+  fp5(0, 1.1, 2.2);
 #endif // WIN32
 }
 
-// void usage function, calls convrsion operator.
+// void usage function, calls conversion operator.
 // LIN64: define void @_Z5usagev()
 // VECCALL: define void @_Z5usagev()
 // WIN32: define dso_local void @"?usage@@YAXXZ"()
 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
 //
 // Conversion operator, returns __invoke.
 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
@@ -32,6 +43,12 @@
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CA?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
 //
 // __invoke function, calls operator(). Win32 should call both.
 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
@@ -42,3 +59,9 @@
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_stdcallcc double @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_fastcallcc double @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
+// WIN32: define internal x86_vectorcallcc double @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
+// WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1272,6 +1272,34 @@
   CallOpProto.isVariadic(), /*IsCXXMethod=*/true);
   CallingConv CallOpCC = CallOpProto.getCallConv();
 
+  /// Implement emitting a version of the operator for many of the calling
+  /// conventions for MSVC, as described here:
+  /// https://devblogs.microsoft.com/oldnewthing/20150220-00/?p=44623.
+  /// Expe

[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Sema/SemaLambda.cpp:1281
+  /// Additionally, we are ensuring that the default-free/default-member and
+  /// call-operator calling convention are generated as well.
+  if (S.getLangOpts().MSVCCompat) {

Should we call out that one of the existing member functions is likely to be 
`thiscall` which means we'll generate a version of the operator for that 
calling convention even though MSVC doesn't, but we want to do this because 
users can explicitly write the CC on the lambda (unlike in MSVC)? (I'm worried 
that lack of mention about `thiscall` may look like a bug to someone a few 
years down the line.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90634/new/

https://reviews.llvm.org/D90634

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D90634: Implement Lambda Conversion Operators for All CCs for MSVC.

2020-11-02 Thread Erich Keane via Phabricator via cfe-commits
erichkeane created this revision.
erichkeane added reviewers: rjmccall, aaron.ballman.
Herald added subscribers: mgrang, kristof.beyls.
erichkeane requested review of this revision.

As described here:
https://devblogs.microsoft.com/oldnewthing/20150220-00/?p=44623

In order to allow Lambdas to be used with traditional Win32 APIs, they
emit a conversion function for (what Raymond Chen claims is all) a
number of the calling conventions.  Through experimentation, we
discovered that the list isn't quite 'all'.

This patch implements this by taking the list of conversions that MSVC
emits (across 'all' architectures, I don't see any CCs on ARM), then
emits them if they are supported by the current target.

However, we also add 3 other options (which may be duplicates):
free-function, member-function, and operator() calling conventions.  We
do this because we have an extension where we generate both free and
member for these cases so th at people specifying a calling convention
on the lambda will have the expected behavior when specifying one of
those two.

MSVC doesn't seem to permit specifying calling-convention on lambdas,
but we do, so we need to make sure those are emitted as well. We do this
so that clang-only conventions are supported if the user specifies them.


https://reviews.llvm.org/D90634

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp

Index: clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
===
--- clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
+++ clang/test/CodeGenCXX/lambda-conversion-op-cc.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
+// RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
 
 #ifndef CC
 #define CC
@@ -10,20 +10,31 @@
   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
 
   double (*CC fp)(int, float, double) = lambda;
-  fp(0, 1.1, 2.2);
 #ifdef WIN32
   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
+  double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
+  double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
+  double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
+#endif // WIN32
+  fp(0, 1.1, 2.2);
+#ifdef WIN32
   fp2(0, 1.1, 2.2);
+  fp3(0, 1.1, 2.2);
+  fp4(0, 1.1, 2.2);
+  fp5(0, 1.1, 2.2);
 #endif // WIN32
 }
 
-// void usage function, calls convrsion operator.
+// void usage function, calls conversion operator.
 // LIN64: define void @_Z5usagev()
 // VECCALL: define void @_Z5usagev()
 // WIN32: define dso_local void @"?usage@@YAXXZ"()
 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6A?A?@@HMN@ZXZ"
 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: call x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
 //
 // Conversion operator, returns __invoke.
 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
@@ -32,6 +43,12 @@
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CA?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6E?A?@@HMN@ZXZ"
 // WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6G?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CG?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6I?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CI?A?@@HMN@Z"
+// WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B@?0??usage@@YAXXZ@QBEP6Q?A?@@HMN@ZXZ"
+// WIN32: ret double (i32, float, double)* @"?__invoke@@?0??usage@@YAXXZ@CQ?A?@@HMN@Z"
 //
 // __invoke function, calls operator(). Win32 should call both.
 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
@@ -42,3 +59,9 @@
 // WIN32: call x86_thiscallcc double @"??R@?0??usage@@YAXXZ@QBE?A?@@HMN@Z"
 // WIN32: define internal x86_thiscallcc double @"?__invoke@@?0??usage@@YAXXZ@CE?A?@@HMN@Z"
 /