xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s -check-prefix=X86
2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64
3*0a6a1f1dSLionel Sambuc 
4*0a6a1f1dSLionel Sambuc struct A {
5*0a6a1f1dSLionel Sambuc   A(int a);
6*0a6a1f1dSLionel Sambuc   A(const A &o);
7*0a6a1f1dSLionel Sambuc   ~A();
8*0a6a1f1dSLionel Sambuc   int a;
9*0a6a1f1dSLionel Sambuc };
10*0a6a1f1dSLionel Sambuc 
foo(A a,A b,A c)11*0a6a1f1dSLionel Sambuc void foo(A a, A b, A c) {
12*0a6a1f1dSLionel Sambuc }
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc // Order of destruction should be left to right.
15*0a6a1f1dSLionel Sambuc //
16*0a6a1f1dSLionel Sambuc // X86-LABEL: define void @"\01?foo@@YAXUA@@00@Z"
17*0a6a1f1dSLionel Sambuc // X86:          ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca)
18*0a6a1f1dSLionel Sambuc // X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 0
19*0a6a1f1dSLionel Sambuc // X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 1
20*0a6a1f1dSLionel Sambuc // X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 2
21*0a6a1f1dSLionel Sambuc // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[a]])
22*0a6a1f1dSLionel Sambuc // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[b]])
23*0a6a1f1dSLionel Sambuc // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[c]])
24*0a6a1f1dSLionel Sambuc // X86: ret void
25*0a6a1f1dSLionel Sambuc 
26*0a6a1f1dSLionel Sambuc // X64-LABEL: define void @"\01?foo@@YAXUA@@00@Z"
27*0a6a1f1dSLionel Sambuc // X64:         (%struct.A* %[[a:[^,]*]], %struct.A* %[[b:[^,]*]], %struct.A* %[[c:[^)]*]])
28*0a6a1f1dSLionel Sambuc // X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[a]])
29*0a6a1f1dSLionel Sambuc // X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[b]])
30*0a6a1f1dSLionel Sambuc // X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[c]])
31*0a6a1f1dSLionel Sambuc // X64: ret void
32*0a6a1f1dSLionel Sambuc 
33*0a6a1f1dSLionel Sambuc 
call_foo()34*0a6a1f1dSLionel Sambuc void call_foo() {
35*0a6a1f1dSLionel Sambuc   foo(A(1), A(2), A(3));
36*0a6a1f1dSLionel Sambuc }
37*0a6a1f1dSLionel Sambuc 
38*0a6a1f1dSLionel Sambuc // Order of evaluation should be right to left, and we should clean up the right
39*0a6a1f1dSLionel Sambuc // things as we unwind.
40*0a6a1f1dSLionel Sambuc //
41*0a6a1f1dSLionel Sambuc // X86-LABEL: define void @"\01?call_foo@@YAXXZ"()
42*0a6a1f1dSLionel Sambuc // X86: call i8* @llvm.stacksave()
43*0a6a1f1dSLionel Sambuc // X86: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
44*0a6a1f1dSLionel Sambuc // X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 2
45*0a6a1f1dSLionel Sambuc // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg3]], i32 3)
46*0a6a1f1dSLionel Sambuc // X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
47*0a6a1f1dSLionel Sambuc // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg2]], i32 2)
48*0a6a1f1dSLionel Sambuc // X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
49*0a6a1f1dSLionel Sambuc // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg1]], i32 1)
50*0a6a1f1dSLionel Sambuc // X86: invoke void @"\01?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]])
51*0a6a1f1dSLionel Sambuc // X86: call void @llvm.stackrestore
52*0a6a1f1dSLionel Sambuc // X86: ret void
53*0a6a1f1dSLionel Sambuc //
54*0a6a1f1dSLionel Sambuc //   lpad2:
55*0a6a1f1dSLionel Sambuc // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg2]])
56*0a6a1f1dSLionel Sambuc // X86: br label
57*0a6a1f1dSLionel Sambuc //
58*0a6a1f1dSLionel Sambuc //   ehcleanup:
59*0a6a1f1dSLionel Sambuc // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg3]])
60*0a6a1f1dSLionel Sambuc 
61*0a6a1f1dSLionel Sambuc // X64-LABEL: define void @"\01?call_foo@@YAXXZ"()
62*0a6a1f1dSLionel Sambuc // X64: call %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg3:[^,]*]], i32 3)
63*0a6a1f1dSLionel Sambuc // X64: invoke %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg2:[^,]*]], i32 2)
64*0a6a1f1dSLionel Sambuc // X64: invoke %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg1:[^,]*]], i32 1)
65*0a6a1f1dSLionel Sambuc // X64: call void @"\01?foo@@YAXUA@@00@Z"
66*0a6a1f1dSLionel Sambuc // X64:       (%struct.A* %[[arg1]], %struct.A* %[[arg2]], %struct.A* %[[arg3]])
67*0a6a1f1dSLionel Sambuc // X64: ret void
68*0a6a1f1dSLionel Sambuc //
69*0a6a1f1dSLionel Sambuc //   lpad2:
70*0a6a1f1dSLionel Sambuc // X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[arg2]])
71*0a6a1f1dSLionel Sambuc // X64: br label
72*0a6a1f1dSLionel Sambuc //
73*0a6a1f1dSLionel Sambuc //   ehcleanup:
74*0a6a1f1dSLionel Sambuc // X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[arg3]])
75