cxx0x-initializer-stdinitializerlist.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
  2. namespace std {
  3. typedef decltype(sizeof(int)) size_t;
  4. // libc++'s implementation
  5. template <class _E>
  6. class initializer_list
  7. {
  8. const _E* __begin_;
  9. size_t __size_;
  10. initializer_list(const _E* __b, size_t __s)
  11. : __begin_(__b),
  12. __size_(__s)
  13. {}
  14. public:
  15. typedef _E value_type;
  16. typedef const _E& reference;
  17. typedef const _E& const_reference;
  18. typedef size_t size_type;
  19. typedef const _E* iterator;
  20. typedef const _E* const_iterator;
  21. initializer_list() : __begin_(nullptr), __size_(0) {}
  22. size_t size() const {return __size_;}
  23. const _E* begin() const {return __begin_;}
  24. const _E* end() const {return __begin_ + __size_;}
  25. };
  26. }
  27. struct destroyme1 {
  28. ~destroyme1();
  29. };
  30. struct destroyme2 {
  31. ~destroyme2();
  32. };
  33. struct witharg1 {
  34. witharg1(const destroyme1&);
  35. ~witharg1();
  36. };
  37. struct wantslist1 {
  38. wantslist1(std::initializer_list<destroyme1>);
  39. ~wantslist1();
  40. };
  41. // CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3]
  42. // CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 }
  43. std::initializer_list<int> globalInitList1 = {1, 2, 3};
  44. // CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer
  45. // CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x
  46. // CHECK: appending global
  47. // CHECK: define internal void
  48. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 0
  49. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 1
  50. // CHECK: __cxa_atexit
  51. // CHECK: call void @_ZN10destroyme1D1Ev
  52. // CHECK: call void @_ZN10destroyme1D1Ev
  53. std::initializer_list<witharg1> globalInitList2 = {
  54. witharg1(destroyme1()), witharg1(destroyme1())
  55. };
  56. void fn1(int i) {
  57. // CHECK: define void @_Z3fn1i
  58. // temporary array
  59. // CHECK: [[array:%[^ ]+]] = alloca [3 x i32]
  60. // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0
  61. // CHECK-NEXT: store i32 1, i32*
  62. // CHECK-NEXT: getelementptr
  63. // CHECK-NEXT: store
  64. // CHECK-NEXT: getelementptr
  65. // CHECK-NEXT: load
  66. // CHECK-NEXT: store
  67. // init the list
  68. // CHECK-NEXT: getelementptr
  69. // CHECK-NEXT: getelementptr inbounds [3 x i32]*
  70. // CHECK-NEXT: store i32*
  71. // CHECK-NEXT: getelementptr
  72. // CHECK-NEXT: store i{{32|64}} 3
  73. std::initializer_list<int> intlist{1, 2, i};
  74. }
  75. void fn2() {
  76. // CHECK: define void @_Z3fn2v
  77. void target(std::initializer_list<destroyme1>);
  78. // objects should be destroyed before dm2, after call returns
  79. // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
  80. target({ destroyme1(), destroyme1() });
  81. // CHECK: call void @_ZN10destroyme1D1Ev
  82. destroyme2 dm2;
  83. // CHECK: call void @_ZN10destroyme2D1Ev
  84. }
  85. void fn3() {
  86. // CHECK: define void @_Z3fn3v
  87. // objects should be destroyed after dm2
  88. auto list = { destroyme1(), destroyme1() };
  89. destroyme2 dm2;
  90. // CHECK: call void @_ZN10destroyme2D1Ev
  91. // CHECK: call void @_ZN10destroyme1D1Ev
  92. }
  93. void fn4() {
  94. // CHECK: define void @_Z3fn4v
  95. void target(std::initializer_list<witharg1>);
  96. // objects should be destroyed before dm2, after call returns
  97. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
  98. // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
  99. target({ witharg1(destroyme1()), witharg1(destroyme1()) });
  100. // CHECK: call void @_ZN8witharg1D1Ev
  101. // CHECK: call void @_ZN10destroyme1D1Ev
  102. destroyme2 dm2;
  103. // CHECK: call void @_ZN10destroyme2D1Ev
  104. }
  105. void fn5() {
  106. // CHECK: define void @_Z3fn5v
  107. // temps should be destroyed before dm2
  108. // objects should be destroyed after dm2
  109. // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
  110. auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
  111. // CHECK: call void @_ZN10destroyme1D1Ev
  112. destroyme2 dm2;
  113. // CHECK: call void @_ZN10destroyme2D1Ev
  114. // CHECK: call void @_ZN8witharg1D1Ev
  115. }
  116. void fn6() {
  117. // CHECK: define void @_Z3fn6v
  118. void target(const wantslist1&);
  119. // objects should be destroyed before dm2, after call returns
  120. // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
  121. // CHECK: call void @_Z6targetRK10wantslist1
  122. target({ destroyme1(), destroyme1() });
  123. // CHECK: call void @_ZN10wantslist1D1Ev
  124. // CHECK: call void @_ZN10destroyme1D1Ev
  125. destroyme2 dm2;
  126. // CHECK: call void @_ZN10destroyme2D1Ev
  127. }
  128. void fn7() {
  129. // CHECK: define void @_Z3fn7v
  130. // temps should be destroyed before dm2
  131. // object should be destroyed after dm2
  132. // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
  133. wantslist1 wl = { destroyme1(), destroyme1() };
  134. // CHECK: call void @_ZN10destroyme1D1Ev
  135. destroyme2 dm2;
  136. // CHECK: call void @_ZN10destroyme2D1Ev
  137. // CHECK: call void @_ZN10wantslist1D1Ev
  138. }
  139. void fn8() {
  140. // CHECK: define void @_Z3fn8v
  141. void target(std::initializer_list<std::initializer_list<destroyme1>>);
  142. // objects should be destroyed before dm2, after call returns
  143. // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE
  144. std::initializer_list<destroyme1> inner;
  145. target({ inner, { destroyme1() } });
  146. // CHECK: call void @_ZN10destroyme1D1Ev
  147. // Only one destroy loop, since only one inner init list is directly inited.
  148. // CHECK-NOT: call void @_ZN10destroyme1D1Ev
  149. destroyme2 dm2;
  150. // CHECK: call void @_ZN10destroyme2D1Ev
  151. }
  152. void fn9() {
  153. // CHECK: define void @_Z3fn9v
  154. // objects should be destroyed after dm2
  155. std::initializer_list<destroyme1> inner;
  156. std::initializer_list<std::initializer_list<destroyme1>> list =
  157. { inner, { destroyme1() } };
  158. destroyme2 dm2;
  159. // CHECK: call void @_ZN10destroyme2D1Ev
  160. // CHECK: call void @_ZN10destroyme1D1Ev
  161. // Only one destroy loop, since only one inner init list is directly inited.
  162. // CHECK-NOT: call void @_ZN10destroyme1D1Ev
  163. // CHECK: ret void
  164. }
  165. struct haslist1 {
  166. std::initializer_list<int> il;
  167. haslist1();
  168. };
  169. // CHECK: define void @_ZN8haslist1C2Ev
  170. haslist1::haslist1()
  171. // CHECK: alloca [3 x i32]
  172. // CHECK: store i32 1
  173. // CHECK: store i32 2
  174. // CHECK: store i32 3
  175. // CHECK: store i{{32|64}} 3
  176. : il{1, 2, 3}
  177. {
  178. destroyme2 dm2;
  179. }
  180. struct haslist2 {
  181. std::initializer_list<destroyme1> il;
  182. haslist2();
  183. };
  184. // CHECK: define void @_ZN8haslist2C2Ev
  185. haslist2::haslist2()
  186. : il{destroyme1(), destroyme1()}
  187. {
  188. destroyme2 dm2;
  189. // CHECK: call void @_ZN10destroyme2D1Ev
  190. // CHECK: call void @_ZN10destroyme1D1Ev
  191. }
  192. void fn10() {
  193. // CHECK: define void @_Z4fn10v
  194. // CHECK: alloca [3 x i32]
  195. // CHECK: call noalias i8* @_Znw{{[jm]}}
  196. // CHECK: store i32 1
  197. // CHECK: store i32 2
  198. // CHECK: store i32 3
  199. // CHECK: store i32*
  200. // CHECK: store i{{32|64}} 3
  201. (void) new std::initializer_list<int> {1, 2, 3};
  202. }
  203. void fn11() {
  204. // CHECK: define void @_Z4fn11v
  205. (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()};
  206. // CHECK: call void @_ZN10destroyme1D1Ev
  207. destroyme2 dm2;
  208. // CHECK: call void @_ZN10destroyme2D1Ev
  209. }