diff options
| author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 | 
|---|---|---|
| committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 | 
| commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
| tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp | |
| parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) | |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp')
| -rw-r--r-- | clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp | 252 | 
1 files changed, 252 insertions, 0 deletions
| diff --git a/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp new file mode 100644 index 0000000..81ce559 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -0,0 +1,252 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +namespace std { +  typedef decltype(sizeof(int)) size_t; + +  // libc++'s implementation +  template <class _E> +  class initializer_list +  { +    const _E* __begin_; +    size_t    __size_; + +    initializer_list(const _E* __b, size_t __s) +      : __begin_(__b), +        __size_(__s) +    {} + +  public: +    typedef _E        value_type; +    typedef const _E& reference; +    typedef const _E& const_reference; +    typedef size_t    size_type; + +    typedef const _E* iterator; +    typedef const _E* const_iterator; + +    initializer_list() : __begin_(nullptr), __size_(0) {} + +    size_t    size()  const {return __size_;} +    const _E* begin() const {return __begin_;} +    const _E* end()   const {return __begin_ + __size_;} +  }; +} + +struct destroyme1 { +  ~destroyme1(); +}; +struct destroyme2 { +  ~destroyme2(); +}; +struct witharg1 { +  witharg1(const destroyme1&); +  ~witharg1(); +}; +struct wantslist1 { +  wantslist1(std::initializer_list<destroyme1>); +  ~wantslist1(); +}; + +// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 } +std::initializer_list<int> globalInitList1 = {1, 2, 3}; + +// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer +// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x +// CHECK: appending global +// CHECK: define internal void +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 0 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 1 +// CHECK: __cxa_atexit +// CHECK: call void @_ZN10destroyme1D1Ev +// CHECK: call void @_ZN10destroyme1D1Ev +std::initializer_list<witharg1> globalInitList2 = { +  witharg1(destroyme1()), witharg1(destroyme1()) +}; + +void fn1(int i) { +  // CHECK: define void @_Z3fn1i +  // temporary array +  // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] +  // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 +  // CHECK-NEXT: store i32 1, i32* +  // CHECK-NEXT: getelementptr +  // CHECK-NEXT: store +  // CHECK-NEXT: getelementptr +  // CHECK-NEXT: load +  // CHECK-NEXT: store +  // init the list +  // CHECK-NEXT: getelementptr +  // CHECK-NEXT: getelementptr inbounds [3 x i32]* +  // CHECK-NEXT: store i32* +  // CHECK-NEXT: getelementptr +  // CHECK-NEXT: store i{{32|64}} 3 +  std::initializer_list<int> intlist{1, 2, i}; +} + +void fn2() { +  // CHECK: define void @_Z3fn2v +  void target(std::initializer_list<destroyme1>); +  // objects should be destroyed before dm2, after call returns +  // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E +  target({ destroyme1(), destroyme1() }); +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn3() { +  // CHECK: define void @_Z3fn3v +  // objects should be destroyed after dm2 +  auto list = { destroyme1(), destroyme1() }; +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +  // CHECK: call void @_ZN10destroyme1D1Ev +} + +void fn4() { +  // CHECK: define void @_Z3fn4v +  void target(std::initializer_list<witharg1>); +  // objects should be destroyed before dm2, after call returns +  // CHECK: call void @_ZN8witharg1C1ERK10destroyme1 +  // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E +  target({ witharg1(destroyme1()), witharg1(destroyme1()) }); +  // CHECK: call void @_ZN8witharg1D1Ev +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn5() { +  // CHECK: define void @_Z3fn5v +  // temps should be destroyed before dm2 +  // objects should be destroyed after dm2 +  // CHECK: call void @_ZN8witharg1C1ERK10destroyme1 +  auto list = { witharg1(destroyme1()), witharg1(destroyme1()) }; +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +  // CHECK: call void @_ZN8witharg1D1Ev +} + +void fn6() { +  // CHECK: define void @_Z3fn6v +  void target(const wantslist1&); +  // objects should be destroyed before dm2, after call returns +  // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E +  // CHECK: call void @_Z6targetRK10wantslist1 +  target({ destroyme1(), destroyme1() }); +  // CHECK: call void @_ZN10wantslist1D1Ev +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn7() { +  // CHECK: define void @_Z3fn7v +  // temps should be destroyed before dm2 +  // object should be destroyed after dm2 +  // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E +  wantslist1 wl = { destroyme1(), destroyme1() }; +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +  // CHECK: call void @_ZN10wantslist1D1Ev +} + +void fn8() { +  // CHECK: define void @_Z3fn8v +  void target(std::initializer_list<std::initializer_list<destroyme1>>); +  // objects should be destroyed before dm2, after call returns +  // CHECK: call void @_Z6targetSt16initializer_listIS_I10destroyme1EE +  std::initializer_list<destroyme1> inner; +  target({ inner, { destroyme1() } }); +  // CHECK: call void @_ZN10destroyme1D1Ev +  // Only one destroy loop, since only one inner init list is directly inited. +  // CHECK-NOT: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +} + +void fn9() { +  // CHECK: define void @_Z3fn9v +  // objects should be destroyed after dm2 +  std::initializer_list<destroyme1> inner; +  std::initializer_list<std::initializer_list<destroyme1>> list = +      { inner, { destroyme1() } }; +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +  // CHECK: call void @_ZN10destroyme1D1Ev +  // Only one destroy loop, since only one inner init list is directly inited. +  // CHECK-NOT: call void @_ZN10destroyme1D1Ev +  // CHECK: ret void +} + +struct haslist1 { +  std::initializer_list<int> il; +  haslist1(); +}; + +// CHECK: define void @_ZN8haslist1C2Ev +haslist1::haslist1() +// CHECK: alloca [3 x i32] +// CHECK: store i32 1 +// CHECK: store i32 2 +// CHECK: store i32 3 +// CHECK: store i{{32|64}} 3 +  : il{1, 2, 3} +{ +  destroyme2 dm2; +} + +struct haslist2 { +  std::initializer_list<destroyme1> il; +  haslist2(); +}; + +// CHECK: define void @_ZN8haslist2C2Ev +haslist2::haslist2() +  : il{destroyme1(), destroyme1()} +{ +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +  // CHECK: call void @_ZN10destroyme1D1Ev +} + +void fn10() { +  // CHECK: define void @_Z4fn10v +  // CHECK: alloca [3 x i32] +  // CHECK: call noalias i8* @_Znw{{[jm]}} +  // CHECK: store i32 1 +  // CHECK: store i32 2 +  // CHECK: store i32 3 +  // CHECK: store i32* +  // CHECK: store i{{32|64}} 3 +  (void) new std::initializer_list<int> {1, 2, 3}; +} + +void fn11() { +  // CHECK: define void @_Z4fn11v +  (void) new std::initializer_list<destroyme1> {destroyme1(), destroyme1()}; +  // CHECK: call void @_ZN10destroyme1D1Ev +  destroyme2 dm2; +  // CHECK: call void @_ZN10destroyme2D1Ev +} + +namespace PR12178 { +  struct string { +    string(int); +    ~string(); +  }; + +  struct pair { +    string a; +    int b; +  }; + +  struct map { +    map(std::initializer_list<pair>); +  }; + +  map m{ {1, 2}, {3, 4} }; +} | 
