1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fenable-matrix %s 2 3 template <typename T> // expected-note{{declared here}} 4 void matrix_template_1() { 5 using matrix1_t = float __attribute__((matrix_type(T, T))); // expected-error{{'T' does not refer to a value}} 6 } 7 8 template <class C> // expected-note{{declared here}} 9 void matrix_template_2() { 10 using matrix1_t = float __attribute__((matrix_type(C, C))); // expected-error{{'C' does not refer to a value}} 11 } 12 13 template <unsigned Rows, unsigned Cols> 14 void matrix_template_3() { 15 using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{zero matrix size}} 16 } 17 18 void instantiate_template_3() { 19 matrix_template_3<1, 10>(); 20 matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0U, 10U>' requested here}} 21 } 22 23 template <int Rows, unsigned Cols> 24 void matrix_template_4() { 25 using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{matrix row size too large}} 26 } 27 28 void instantiate_template_4() { 29 matrix_template_4<2, 10>(); 30 matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10U>' requested here}} 31 } 32 33 template <class T, unsigned long R, unsigned long C> 34 using matrix = T __attribute__((matrix_type(R, C))); 35 36 template <class T, unsigned long R> 37 void use_matrix(matrix<T, R, 10> &m) {} 38 // expected-note@-1 {{candidate function [with T = float, R = 10]}} 39 40 template <class T, unsigned long C> 41 void use_matrix(matrix<T, 10, C> &m) {} 42 // expected-note@-1 {{candidate function [with T = float, C = 10]}} 43 44 void test_ambigous_deduction1() { 45 matrix<float, 10, 10> m; 46 use_matrix(m); 47 // expected-error@-1 {{call to 'use_matrix' is ambiguous}} 48 } 49 50 template <class T, long R> 51 void type_conflict(matrix<T, R, 10> &m, T x) {} 52 // expected-note@-1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('float' vs. 'char *')}} 53 54 void test_type_conflict(char *p) { 55 matrix<float, 10, 10> m; 56 type_conflict(m, p); 57 // expected-error@-1 {{no matching function for call to 'type_conflict'}} 58 } 59 60 template <unsigned long R, unsigned long C> 61 matrix<float, R + 1, C + 2> use_matrix_2(matrix<int, R, C> &m) {} 62 // expected-note@-1 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}} 63 // expected-note@-2 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}} 64 65 template <unsigned long R, unsigned long C> 66 void use_matrix_2(matrix<int, R + 2, C / 2> &m1, matrix<float, R, C> &m2) {} 67 // expected-note@-1 {{candidate function [with R = 3, C = 11] not viable: no known conversion from 'matrix<int, 5, 6>' (aka 'int __attribute__((matrix_type(5, 6)))') to 'matrix<int, 3UL + 2, 11UL / 2> &' (aka 'int __attribute__((matrix_type(5, 5)))&') for 1st argument}} 68 // expected-note@-2 {{candidate template ignored: deduced type 'matrix<float, 3UL, 4UL>' of 2nd parameter does not match adjusted type 'matrix<int, 3, 4>' of argument [with R = 3, C = 4]}} 69 70 template <typename T, unsigned long R, unsigned long C> 71 void use_matrix_2(matrix<T, R + C, C> &m1, matrix<T, R, C - R> &m2) {} 72 // expected-note@-1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}} 73 // expected-note@-2 {{candidate template ignored: deduced type 'matrix<[...], 3UL + 4UL, 4UL>' of 1st parameter does not match adjusted type 'matrix<[...], 3, 4>' of argument [with T = int, R = 3, C = 4]}} 74 75 template <typename T, unsigned long R> 76 void use_matrix_3(matrix<T, R - 2, R> &m) {} 77 // expected-note@-1 {{candidate template ignored: deduced type 'matrix<[...], 5UL - 2, 5UL>' of 1st parameter does not match adjusted type 'matrix<[...], 5, 5>' of argument [with T = unsigned int, R = 5]}} 78 79 void test_use_matrix_2() { 80 matrix<int, 5, 6> m1; 81 matrix<float, 5, 8> r1 = use_matrix_2(m1); 82 // expected-error@-1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 5UL + 1, 6UL + 2>'}} 83 84 matrix<int, 4, 5> m2; 85 matrix<float, 5, 8> r2 = use_matrix_2(m2); 86 // expected-error@-1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 4UL + 1, 5UL + 2>'}} 87 88 matrix<float, 3, 11> m3; 89 use_matrix_2(m1, m3); 90 // expected-error@-1 {{no matching function for call to 'use_matrix_2'}} 91 92 matrix<int, 3, 4> m4; 93 use_matrix_2(m4, m4); 94 // expected-error@-1 {{no matching function for call to 'use_matrix_2'}} 95 96 matrix<unsigned, 5, 5> m5; 97 use_matrix_3(m5); 98 // expected-error@-1 {{no matching function for call to 'use_matrix_3'}} 99 } 100 template <typename T, unsigned R, unsigned C> 101 struct make1 { 102 typedef T __attribute__((matrix_type(R, C))) type; 103 }; 104 105 void test_make1() { 106 make1<int, 5, 4>::type x; 107 } 108 109 template <typename T, unsigned R, unsigned C> 110 struct make2 { 111 typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{zero matrix size}} 112 }; 113 114 int test_make2() { 115 make2<int, 0, 1> x; // expected-note{{in instantiation of}} 116 } 117 118 template <typename T, unsigned R, unsigned C> 119 struct make3 { 120 typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type 's'}} 121 }; 122 123 struct s {}; 124 125 int test_make3() { 126 make3<s, 3, 3> x; // expected-note{{in instantiation of}} 127 } 128 129 template <typename T, T R, unsigned C> 130 struct make4 { 131 typedef T __attribute__((matrix_type(R, C))) type; 132 }; 133 134 int test_make4() { 135 make4<int, 4, 5>::type x; 136 } 137 138 typedef int *int_ptr; 139 template <unsigned R, unsigned C> 140 struct make5 { 141 typedef int_ptr __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type}} 142 }; 143 144 template <int R, unsigned C> 145 struct make6 { 146 typedef int __attribute__((matrix_type(R, C))) type; 147 }; 148 149 int test_make6() { 150 make6<4, 4>::type x; 151 152 make6<2, 2>::type y; 153 } 154 155 namespace Deduction { 156 template <typename T> 157 struct X0; 158 159 template <typename T, unsigned N> 160 struct X0<T __attribute__((matrix_type(N, 3)))> { 161 static const unsigned value = 0; 162 }; 163 164 template <typename T> 165 struct X0<T __attribute__((matrix_type(4, 3)))> { 166 static const unsigned value = 1; 167 }; 168 169 template <unsigned N> 170 struct X0<float __attribute__((matrix_type(N, 3)))> { 171 static const unsigned value = 2; 172 }; 173 174 template <> 175 struct X0<float __attribute__((matrix_type(4, 3)))> { 176 static const unsigned value = 3; 177 }; 178 179 typedef int __attribute__((matrix_type(2, 3))) int2; 180 typedef int __attribute__((matrix_type(4, 3))) int4; 181 typedef float __attribute__((matrix_type(2, 3))) float2; 182 typedef float __attribute__((matrix_type(4, 3))) float4; 183 184 int array0[X0<int2>::value == 0 ? 1 : -1]; 185 int array1[X0<int4>::value == 1 ? 1 : -1]; 186 int array2[X0<float2>::value == 2 ? 1 : -1]; 187 int array3[X0<float4>::value == 3 ? 1 : -1]; 188 } // namespace Deduction 189