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__S_E_clIJiiEJLi1ELi2EEEEDaS2_( 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 template<typename> void f() { 58 // CHECK: define linkonce_odr {{.*}} @_ZZ1fIiEvvENKUlT_E_clIiEEDaS0_( 59 auto x = [](auto){}; 60 x(0); 61 } 62 void use_f() { f<int>(); } 63 64 template<typename> struct Y { 65 template<int> struct Z {}; 66 }; 67 68 template<typename ...T> void expanded() { 69 auto x = []<T..., template<T> typename...>{}; 70 auto y = []<int, template<int> typename>{}; 71 auto z = []<int, int, template<int> typename, template<int> typename>{}; 72 // FIXME: Should we really require 'template' for y and z? 73 x.template operator()<(T())..., Y<T>::template Z...>(); 74 y.template operator()<0, Y<int>::Z>(); 75 y.template operator()<1, Y<int>::Z>(); 76 z.template operator()<1, 2, Y<int>::Z, Y<float>::Z>(); 77 } 78 void use_expanded() { 79 // CHECK: @_ZZ8expandedIJEEvvENKUlvE_clIJEJEEEDav( 80 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTtTniEvE_clILi0EN1YIiE1ZEEEDav( 81 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTtTniEvE_clILi1EN1YIiE1ZEEEDav( 82 // CHECK: @_ZZ8expandedIJEEvvENKUlTniTniTtTniETtTniEvE_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 83 expanded<>(); 84 85 // FIXME: Should we really be using J...E for arguments corresponding to an 86 // expanded parameter pack? 87 // Note that the <lambda-sig>s of 'x' and 'y' collide here, after pack expansion. 88 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE_clIJLi0EEJN1YIiE1ZEEEEDav( 89 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE0_clILi0EN1YIiE1ZEEEDav( 90 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTtTniEvE0_clILi1EN1YIiE1ZEEEDav( 91 // CHECK: @_ZZ8expandedIJiEEvvENKUlTniTniTtTniETtTniEvE_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 92 expanded<int>(); 93 94 // Note that the <lambda-sig>s of 'x' and 'z' collide here, after pack expansion. 95 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTniTtTniETtTniEvE_clIJLi0ELi0EEJN1YIiE1ZES4_EEEDav( 96 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTtTniEvE_clILi0EN1YIiE1ZEEEDav( 97 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTtTniEvE_clILi1EN1YIiE1ZEEEDav( 98 // CHECK: @_ZZ8expandedIJiiEEvvENKUlTniTniTtTniETtTniEvE0_clILi1ELi2EN1YIiE1ZENS2_IfE1ZEEEDav( 99 expanded<int, int>(); 100 } 101