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 - -triple=i386-windows-pc -DWIN32 | FileCheck %s --check-prefixes=WIN32
4 
5 #ifndef CC
6 #define CC
7 #endif
8 
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   fp(0, 1.1, 2.2);
14 #ifdef WIN32
15   double (*__attribute__((thiscall)) fp2)(int, float, double) = lambda;
16   fp2(0, 1.1, 2.2);
17 #endif // WIN32
18 }
19 
20 // void usage function, calls convrsion operator.
21 // LIN64: define void @_Z5usagev()
22 // VECCALL: define void @_Z5usagev()
23 // WIN32: define dso_local void @"?usage@@YAXXZ"()
24 // CHECK: call double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
25 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6A?A?<auto>@@HMN@ZXZ"
26 // WIN32: call x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6E?A?<auto>@@HMN@ZXZ"
27 //
28 // Conversion operator, returns __invoke.
29 // CHECK: define internal double (i32, float, double)* @"_ZZ5usagevENK3$_0cvPFdifdEEv"
30 // CHECK: ret double (i32, float, double)* @"_ZZ5usagevEN3$_08__invokeEifd"
31 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6A?A?<auto>@@HMN@ZXZ"
32 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CA?A?<auto>@@HMN@Z"
33 // WIN32: define internal x86_thiscallcc double (i32, float, double)* @"??B<lambda_0>@?0??usage@@YAXXZ@QBEP6E?A?<auto>@@HMN@ZXZ"
34 // WIN32: ret double (i32, float, double)* @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CE?A?<auto>@@HMN@Z"
35 //
36 // __invoke function, calls operator(). Win32 should call both.
37 // LIN64: define internal double @"_ZZ5usagevEN3$_08__invokeEifd"
38 // LIN64: call double @"_ZZ5usagevENK3$_0clEifd"
39 // VECCALL: define internal x86_vectorcallcc double @"_ZZ5usagevEN3$_08__invokeEifd"
40 // VECCALL: call x86_vectorcallcc double @"_ZZ5usagevENK3$_0clEifd"
41 // WIN32: define internal double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CA?A?<auto>@@HMN@Z"
42 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
43 // WIN32: define internal x86_thiscallcc double @"?__invoke@<lambda_0>@?0??usage@@YAXXZ@CE?A?<auto>@@HMN@Z"
44 // WIN32: call x86_thiscallcc double @"??R<lambda_0>@?0??usage@@YAXXZ@QBE?A?<auto>@@HMN@Z"
45