1 | // RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | namespace std { |
4 | typedef decltype(sizeof(int)) size_t; |
5 | |
6 | // libc++'s implementation with __size_ replaced by __end_ |
7 | template <class _E> |
8 | class initializer_list |
9 | { |
10 | const _E* __begin_; |
11 | const _E* __end_; |
12 | |
13 | initializer_list(const _E* __b, const _E* __e) |
14 | : __begin_(__b), |
15 | __end_(__e) |
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), __end_(nullptr) {} |
28 | |
29 | size_t size() const {return __end_ - __begin_;} |
30 | const _E* begin() const {return __begin_;} |
31 | const _E* end() const {return __end_;} |
32 | }; |
33 | } |
34 | |
35 | // CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3] |
36 | // CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, {{[^)]*}}), i32* |
37 | std::initializer_list<int> globalInitList1 = {1, 2, 3}; |
38 | |
39 | void fn1(int i) { |
40 | // CHECK-LABEL: define void @_Z3fn1i |
41 | // temporary array |
42 | // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] |
43 | // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0 |
44 | // CHECK-NEXT: store i32 1, i32* |
45 | // CHECK-NEXT: getelementptr |
46 | // CHECK-NEXT: store |
47 | // CHECK-NEXT: getelementptr |
48 | // CHECK-NEXT: load |
49 | // CHECK-NEXT: store |
50 | // init the list |
51 | // CHECK-NEXT: getelementptr |
52 | // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* |
53 | // CHECK-NEXT: store i32* |
54 | // CHECK-NEXT: getelementptr |
55 | // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3 |
56 | // CHECK-NEXT: store i32* |
57 | std::initializer_list<int> intlist{1, 2, i}; |
58 | } |
59 | |
60 | struct destroyme1 { |
61 | ~destroyme1(); |
62 | }; |
63 | struct destroyme2 { |
64 | ~destroyme2(); |
65 | }; |
66 | |
67 | |
68 | void fn2() { |
69 | // CHECK-LABEL: define void @_Z3fn2v |
70 | void target(std::initializer_list<destroyme1>); |
71 | // objects should be destroyed before dm2, after call returns |
72 | target({ destroyme1(), destroyme1() }); |
73 | // CHECK: call void @_ZN10destroyme1D1Ev |
74 | destroyme2 dm2; |
75 | // CHECK: call void @_ZN10destroyme2D1Ev |
76 | } |
77 | |
78 | void fn3() { |
79 | // CHECK-LABEL: 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 | } |
86 | |