1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,LIN64
2 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -DCC="__attribute__((vectorcall))" | FileCheck %s --check-prefixes=CHECK,VECCALL
3 // RUN: %clang_cc1 -emit-llvm %s -o - -fms-compatibility -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
4 
5 #ifndef CC
6 #define CC
7 #endif
8 
usage()9 void usage() {
10   auto lambda = [](int i, float f, double d) CC { return i + f + d; };
11 
12   double (*CC fp)(int, float, double) = lambda;
13 #ifdef WIN32
14   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
15   double (*__attribute__((stdcall)) fp3)(int, float, double) = lambda;
16   double (*__attribute__((fastcall)) fp4)(int, float, double) = lambda;
17   double (*__attribute__((vectorcall)) fp5)(int, float, double) = lambda;
18 #endif // WIN32
19   fp(0, 1.1, 2.2);
20 #ifdef WIN32
21   fp2(0, 1.1, 2.2);
22   fp3(0, 1.1, 2.2);
23   fp4(0, 1.1, 2.2);
24   fp5(0, 1.1, 2.2);
25 #endif // WIN32
26 
27   auto x = +lambda;
28 }
29 
30 // void usage function, calls conversion operator.
31 // LIN64: define{{.*}} void @_Z5usagev()
32 // VECCALL: define{{.*}} void @_Z5usagev()
33 // WIN32: define dso_local void @"?usage@@YAXXZ"()
34 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
35 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6A?A?<auto>@@HMN@ZXZ"
36 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6E?A?<auto>@@HMN@ZXZ"
37 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6G?A?<auto>@@HMN@ZXZ"
38 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6I?A?<auto>@@HMN@ZXZ"
39 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6Q?A?<auto>@@HMN@ZXZ"
40 // Operator+ calls 'default' calling convention.
41 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
42 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6A?A?<auto>@@HMN@ZXZ"
43 //
44 // Conversion operator, returns __invoke.
45 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
46 // CHECK: ret double (i32, float, double)* @"_ZZ5usagevEN3$_08__invokeEifd"
47 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6A?A?<auto>@@HMN@ZXZ"
48 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CA?A?<auto>@@HMN@Z"
49 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6E?A?<auto>@@HMN@ZXZ"
50 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CE?A?<auto>@@HMN@Z"
51 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6G?A?<auto>@@HMN@ZXZ"
52 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CG?A?<auto>@@HMN@Z"
53 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6I?A?<auto>@@HMN@ZXZ"
54 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CI?A?<auto>@@HMN@Z"
55 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6Q?A?<auto>@@HMN@ZXZ"
56 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CQ?A?<auto>@@HMN@Z"
57 //
58 // __invoke function, calls operator(). Win32 should call both.
59 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
60 // LIN64: call double @"_ZZ5usagevENK3$_0clEifd"
61 // VECCALL: define internal x86_vectorcallcc double @"_ZZ5usagevEN3$_08__invokeEifd"
62 // VECCALL: call x86_vectorcallcc double @"_ZZ5usagevENK3$_0clEifd"
63 // WIN32: define internal double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CA?A?<auto>@@HMN@Z"
64 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
65 // WIN32: define internal x86_thiscallcc double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CE?A?<auto>@@HMN@Z"
66 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
67 // WIN32: define internal x86_stdcallcc double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CG?A?<auto>@@HMN@Z"
68 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
69 // WIN32: define internal x86_fastcallcc double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CI?A?<auto>@@HMN@Z"
70 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
71 // WIN32: define internal x86_vectorcallcc double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CQ?A?<auto>@@HMN@Z"
72 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
73