// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fenable-matrix %s template // expected-note{{declared here}} void matrix_template_1() { using matrix1_t = float __attribute__((matrix_type(T, T))); // expected-error{{'T' does not refer to a value}} } template // expected-note{{declared here}} void matrix_template_2() { using matrix1_t = float __attribute__((matrix_type(C, C))); // expected-error{{'C' does not refer to a value}} } template void matrix_template_3() { using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{zero matrix size}} } void instantiate_template_3() { matrix_template_3<1, 10>(); matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0U, 10U>' requested here}} } template void matrix_template_4() { using matrix1_t = float __attribute__((matrix_type(Rows, Cols))); // expected-error{{matrix row size too large}} } void instantiate_template_4() { matrix_template_4<2, 10>(); matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10U>' requested here}} } template using matrix = T __attribute__((matrix_type(R, C))); template void use_matrix(matrix &m) {} // expected-note@-1 {{candidate function [with T = float, R = 10]}} template void use_matrix(matrix &m) {} // expected-note@-1 {{candidate function [with T = float, C = 10]}} void test_ambigous_deduction1() { matrix m; use_matrix(m); // expected-error@-1 {{call to 'use_matrix' is ambiguous}} } template void type_conflict(matrix &m, T x) {} // expected-note@-1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('float' vs. 'char *')}} void test_type_conflict(char *p) { matrix m; type_conflict(m, p); // expected-error@-1 {{no matching function for call to 'type_conflict'}} } template matrix use_matrix_2(matrix &m) {} // expected-note@-1 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}} // expected-note@-2 {{candidate function template not viable: requires single argument 'm', but 2 arguments were provided}} template void use_matrix_2(matrix &m1, matrix &m2) {} // expected-note@-1 {{candidate function [with R = 3, C = 11] not viable: no known conversion from 'matrix' (aka 'int __attribute__((matrix_type(5, 6)))') to 'matrix &' (aka 'int __attribute__((matrix_type(5, 5)))&') for 1st argument}} // expected-note@-2 {{candidate template ignored: deduced type 'matrix' of 2nd parameter does not match adjusted type 'matrix' of argument [with R = 3, C = 4]}} template void use_matrix_2(matrix &m1, matrix &m2) {} // expected-note@-1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}} // 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]}} template void use_matrix_3(matrix &m) {} // 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]}} void test_use_matrix_2() { matrix m1; matrix r1 = use_matrix_2(m1); // expected-error@-1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 5UL + 1, 6UL + 2>'}} matrix m2; matrix r2 = use_matrix_2(m2); // expected-error@-1 {{cannot initialize a variable of type 'matrix<[...], 5, 8>' with an rvalue of type 'matrix<[...], 4UL + 1, 5UL + 2>'}} matrix m3; use_matrix_2(m1, m3); // expected-error@-1 {{no matching function for call to 'use_matrix_2'}} matrix m4; use_matrix_2(m4, m4); // expected-error@-1 {{no matching function for call to 'use_matrix_2'}} matrix m5; use_matrix_3(m5); // expected-error@-1 {{no matching function for call to 'use_matrix_3'}} } template struct make1 { typedef T __attribute__((matrix_type(R, C))) type; }; void test_make1() { make1::type x; } template struct make2 { typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{zero matrix size}} }; int test_make2() { make2 x; // expected-note{{in instantiation of}} } template struct make3 { typedef T __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type 's'}} }; struct s {}; int test_make3() { make3 x; // expected-note{{in instantiation of}} } template struct make4 { typedef T __attribute__((matrix_type(R, C))) type; }; int test_make4() { make4::type x; } typedef int *int_ptr; template struct make5 { typedef int_ptr __attribute__((matrix_type(R, C))) type; // expected-error{{invalid matrix element type}} }; template struct make6 { typedef int __attribute__((matrix_type(R, C))) type; }; int test_make6() { make6<4, 4>::type x; make6<2, 2>::type y; } namespace Deduction { template struct X0; template struct X0 { static const unsigned value = 0; }; template struct X0 { static const unsigned value = 1; }; template struct X0 { static const unsigned value = 2; }; template <> struct X0 { static const unsigned value = 3; }; typedef int __attribute__((matrix_type(2, 3))) int2; typedef int __attribute__((matrix_type(4, 3))) int4; typedef float __attribute__((matrix_type(2, 3))) float2; typedef float __attribute__((matrix_type(4, 3))) float4; int array0[X0::value == 0 ? 1 : -1]; int array1[X0::value == 1 ? 1 : -1]; int array2[X0::value == 2 ? 1 : -1]; int array3[X0::value == 3 ? 1 : -1]; } // namespace Deduction