1 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s |
2 | // RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s |
3 | |
4 | struct test_struct {}; |
5 | typedef int test_struct::* test_struct_mdp; |
6 | typedef int (test_struct::*test_struct_mfp)(); |
7 | |
8 | // CHECK-LABEL: define i32 @{{.*}}f_mdp{{.*}}(i32 %a) |
9 | test_struct_mdp f_mdp(test_struct_mdp a) { return a; } |
10 | |
11 | // CHECK-LABEL: define {{.*}} @{{.*}}f_mfp{{.*}}(i64 %a.coerce) |
12 | test_struct_mfp f_mfp(test_struct_mfp a) { return a; } |
13 | |
14 | // A struct with <= 12 bytes before a member data pointer should still |
15 | // be allowed in registers, since the member data pointer is only 4 bytes. |
16 | // CHECK-LABEL: define void @{{.*}}f_struct_with_mdp{{.*}}(i64 %a.coerce0, i64 %a.coerce1) |
17 | struct struct_with_mdp { char *a; char *b; char *c; test_struct_mdp d; }; |
18 | void f_struct_with_mdp(struct_with_mdp a) { (void)a; } |
19 | |
20 | struct struct_with_mdp_too_much { |
21 | char *a; char *b; char *c; char *d; test_struct_mdp e; |
22 | }; |
23 | // CHECK-LABEL: define void @{{.*}}f_struct_with_mdp_too_much{{.*}}({{.*}} byval {{.*}} %a) |
24 | void f_struct_with_mdp_too_much(struct_with_mdp_too_much a) { |
25 | (void)a; |
26 | } |
27 | |
28 | // A struct with <= 8 bytes before a member function pointer should still |
29 | // be allowed in registers, since the member function pointer is only 8 bytes. |
30 | // CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_0{{.*}}(i64 %a.coerce0, i32 %a.coerce1) |
31 | struct struct_with_mfp_0 { char *a; test_struct_mfp b; }; |
32 | void f_struct_with_mfp_0(struct_with_mfp_0 a) { (void)a; } |
33 | |
34 | // CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_1{{.*}}(i64 %a.coerce0, i64 %a.coerce1) |
35 | struct struct_with_mfp_1 { char *a; char *b; test_struct_mfp c; }; |
36 | void f_struct_with_mfp_1(struct_with_mfp_1 a) { (void)a; } |
37 | |
38 | // CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_too_much{{.*}}({{.*}} byval {{.*}} %a, i32 %x) |
39 | struct struct_with_mfp_too_much { |
40 | char *a; char *b; char *c; test_struct_mfp d; |
41 | }; |
42 | void f_struct_with_mfp_too_much(struct_with_mfp_too_much a, int x) { |
43 | (void)a; |
44 | } |
45 | |
46 | /* Struct containing an empty struct */ |
47 | typedef struct { int* a; test_struct x; double *b; } struct_with_empty; |
48 | |
49 | // CHECK-LABEL: define void @{{.*}}f_pass_struct_with_empty{{.*}}(i64 %x{{.*}}, double* %x |
50 | void f_pass_struct_with_empty(struct_with_empty x) { |
51 | (void) x; |
52 | } |
53 | |
54 | // CHECK-LABEL: define { i64, double* } @{{.*}}f_return_struct_with_empty |
55 | struct_with_empty f_return_struct_with_empty() { |
56 | return {0, {}, 0}; |
57 | } |
58 | |