1 // RUN: %clang_cc1 -std=c++2a -triple %itanium_abi_triple -emit-llvm -o - %s -w | FileCheck %s 2 3 template<class, int, class> 4 struct DummyType { }; 5 6 inline void inline_func() { 7 // CHECK: UlvE 8 []{}(); 9 10 // CHECK: UlTyvE 11 []<class>{}.operator()<int>(); 12 13 // CHECK: UlTyT_E 14 []<class T>(T){}(1); 15 16 // CHECK: UlTyTyT_T0_E 17 []<class T1, class T2>(T1, T2){}(1, 2); 18 19 // CHECK: UlTyTyT0_T_E 20 []<class T1, class T2>(T2, T1){}(2, 1); 21 22 // CHECK: UlTniTyTnjT0_E 23 []<int I, class T, unsigned U>(T){}.operator()<1, int, 2>(3); 24 25 // CHECK: UlTyTtTyTniTyETniTyvE 26 []<class, 27 template<class, int, class> class, 28 int, 29 class>{}.operator()<unsigned, DummyType, 5, int>(); 30 } 31 32 void call_inline_func() { 33 inline_func(); 34 } 35 36 template<typename T, int> struct X {}; 37 38 inline auto pack = []<typename ...T, T ...N>(T (&...)[N]) {}; 39 int arr1[] = {1}; 40 int arr2[] = {1, 2}; 41 // CHECK: @_ZNK4packMUlTpTyTpTnT_DpRAT0__S0_E_clIJiiEJLi1ELi2EEEEDaS3_( 42 void use_pack() { pack(arr1, arr2); } 43 44 inline void collision() { 45 auto a = []<typename T, template<typename U, T> typename>{}; 46 auto b = []<typename T, template<typename U, U> typename>{}; 47 auto c = []<typename T, template<typename U, T> typename>{}; 48 a.operator()<int, X>(); 49 // CHECK: @_ZZ9collisionvENKUlTyTtTyTnT_EvE_clIi1XEEDav 50 b.operator()<int, X>(); 51 // CHECK: @_ZZ9collisionvENKUlTyTtTyTnTL0__EvE_clIi1XEEDav 52 c.operator()<int, X>(); 53 // CHECK: @_ZZ9collisionvENKUlTyTtTyTnT_EvE0_clIi1XEEDav 54 } 55 void use_collision() { collision(); } 56 57 namespace pack_not_pack_expansion { 58 template<typename T, int, T...> struct X; 59 // CHECK: @_ZNK23pack_not_pack_expansion1xMUlTyTtTyTnT_TpTnTL0__ETpTyvE_clIiNS_1XEJfEEEDav 60 inline auto x = []<typename T, template<typename U, T, U...> typename, typename ...V>(){}; void f() { x.operator()<int, X, float>(); } 61 } 62 63 template<typename> void f() { 64 // CHECK: define linkonce_odr {{.*}} @_ZZ1fIiEvvENKUlT_E_clIiEEDaS0_( 65 auto x = [](auto){}; 66 x(0); 67 } 68 void use_f() { f<int>(); } 69 70 template<typename> struct Y { 71 template<int> struct Z {}; 72 }; 73 74 template<typename ...T> void expanded() { 75 auto x = []<T..., template<T> typename...>{}; 76 auto y = []<int, template<int> typename>{}; 77 auto z = []<int, int, template<int> typename, template<int> typename>{}; 78 // FIXME: Should we really require 'template' for y and z? 79 x.template operator()<(T())..., Y<T>::template Z...>(); 80 y.template operator()<0, Y<int>::Z>(); 81 y.template operator()<1, Y<int>::Z>(); 82 z.template operator()<1, 2, Y<int>::Z, Y<float>::Z>(); 83 } 84 void use_expanded() { 85 // CHECK: @_ZZ8expandedIJEEvvENKUlvE_clIJEJEEEDav( 86 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTtTniEvE_clILi0EN1YIiE1ZEEEDav( 87 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTtTniEvE_clILi1EN1YIiE1ZEEEDav( 88 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTniTtTniETtTniEvE_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 89 expanded<>(); 90 91 // FIXME: Should we really be using J...E for arguments corresponding to an 92 // expanded parameter pack? 93 // Note that the <lambda-sig>s of 'x' and 'y' collide here, after pack expansion. 94 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE_clIJLi0EEJN1YIiE1ZEEEEDav( 95 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE0_clILi0EN1YIiE1ZEEEDav( 96 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE0_clILi1EN1YIiE1ZEEEDav( 97 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTniTtTniETtTniEvE_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 98 expanded<int>(); 99 100 // Note that the <lambda-sig>s of 'x' and 'z' collide here, after pack expansion. 101 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTniTtTniETtTniEvE_clIJLi0ELi0EEJN1YIiE1ZES4_EEEDav( 102 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTtTniEvE_clILi0EN1YIiE1ZEEEDav( 103 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTtTniEvE_clILi1EN1YIiE1ZEEEDav( 104 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTniTtTniETtTniEvE0_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 105 expanded<int, int>(); 106 } 107