blob: a1c4167261bde52abdfd41e18a742e623d4270af [file] [log] [blame]
Sebastian Redl32cf1f22012-02-17 08:42:25 +00001// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
2
3namespace std {
4 typedef decltype(sizeof(int)) size_t;
5
6 // libc++'s implementation
7 template <class _E>
8 class initializer_list
9 {
10 const _E* __begin_;
11 size_t __size_;
12
13 initializer_list(const _E* __b, size_t __s)
14 : __begin_(__b),
15 __size_(__s)
16 {}
17
18 public:
19 typedef _E value_type;
20 typedef const _E& reference;
21 typedef const _E& const_reference;
22 typedef size_t size_type;
23
24 typedef const _E* iterator;
25 typedef const _E* const_iterator;
26
27 initializer_list() : __begin_(nullptr), __size_(0) {}
28
29 size_t size() const {return __size_;}
30 const _E* begin() const {return __begin_;}
31 const _E* end() const {return __begin_ + __size_;}
32 };
33}
34
35void fn1(int i) {
36 // CHECK: define void @_Z3fn1i
37 // temporary array
38 // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
39 // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0
40 // CHECK-NEXT: store i32 1, i32*
41 // CHECK-NEXT: getelementptr
42 // CHECK-NEXT: store
43 // CHECK-NEXT: getelementptr
44 // CHECK-NEXT: load
45 // CHECK-NEXT: store
46 // init the list
47 // CHECK-NEXT: getelementptr
48 // CHECK-NEXT: getelementptr inbounds [3 x i32]*
49 // CHECK-NEXT: store i32*
50 // CHECK-NEXT: getelementptr
51 // CHECK-NEXT: store i{{32|64}} 3
52 std::initializer_list<int> intlist{1, 2, i};
53}
54
55struct destroyme1 {
56 ~destroyme1();
57};
58struct destroyme2 {
59 ~destroyme2();
60};
Sebastian Redl25e640a2012-02-19 12:27:51 +000061struct witharg1 {
62 witharg1(const destroyme1&);
63 ~witharg1();
64};
Sebastian Redl32cf1f22012-02-17 08:42:25 +000065
66
67void fn2() {
68 // CHECK: define void @_Z3fn2v
69 void target(std::initializer_list<destroyme1>);
70 // objects should be destroyed before dm2, after call returns
Sebastian Redl25e640a2012-02-19 12:27:51 +000071 // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
Sebastian Redl32cf1f22012-02-17 08:42:25 +000072 target({ destroyme1(), destroyme1() });
73 // CHECK: call void @_ZN10destroyme1D1Ev
74 destroyme2 dm2;
75 // CHECK: call void @_ZN10destroyme2D1Ev
76}
77
78void fn3() {
79 // CHECK: define void @_Z3fn3v
80 // objects should be destroyed after dm2
81 auto list = { destroyme1(), destroyme1() };
82 destroyme2 dm2;
83 // CHECK: call void @_ZN10destroyme2D1Ev
84 // CHECK: call void @_ZN10destroyme1D1Ev
85}
Sebastian Redl25e640a2012-02-19 12:27:51 +000086
87void fn4() {
88 // CHECK: define void @_Z3fn4v
89 void target(std::initializer_list<witharg1>);
90 // objects should be destroyed before dm2, after call returns
91 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
92 // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
93 target({ witharg1(destroyme1()), witharg1(destroyme1()) });
94 // CHECK: call void @_ZN8witharg1D1Ev
95 // CHECK: call void @_ZN10destroyme1D1Ev
96 destroyme2 dm2;
97 // CHECK: call void @_ZN10destroyme2D1Ev
98}
99
100void fn5() {
101 // CHECK: define void @_Z3fn5v
102 // temps should be destroyed before dm2
103 // objects should be destroyed after dm2
104 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
105 auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
106 // CHECK: call void @_ZN10destroyme1D1Ev
107 destroyme2 dm2;
108 // CHECK: call void @_ZN10destroyme2D1Ev
109 // CHECK: call void @_ZN8witharg1D1Ev
110}