1 // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s 2 3 // If we were even more clever, we'd tell the user to use one set of parens to 4 // get the size of this type, so they don't get errors after inserting typename. 5 6 namespace basic { 7 template <typename T> int type_f() { return sizeof T::type; } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}} 8 template <typename T> int type_g() { return sizeof(T::type); } // expected-warning {{missing 'typename' prior to dependent type name 'X::type'}} 9 template <typename T> int type_h() { return sizeof((T::type)); } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}} 10 template <typename T> int value_f() { return sizeof T::not_a_type; } 11 template <typename T> int value_g() { return sizeof(T::not_a_type); } 12 template <typename T> int value_h() { return sizeof((T::not_a_type)); } 13 struct X { 14 typedef int type; 15 static const int not_a_type; 16 }; 17 int bar() { 18 return 19 type_f<X>() + // expected-note-re {{in instantiation {{.*}} requested here}} 20 type_g<X>() + // expected-note-re {{in instantiation {{.*}} requested here}} 21 type_h<X>() + // expected-note-re {{in instantiation {{.*}} requested here}} 22 value_f<X>() + 23 value_f<X>() + 24 value_f<X>(); 25 } 26 } 27 28 namespace nested_sizeof { 29 template <typename T> 30 struct Foo { 31 enum { 32 // expected-warning@+2 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}} 33 // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}} 34 x1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(/*typename*/ T::InnerType)>), 35 // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}} 36 x2 = sizeof(typename T::template InnerTemplate<sizeof(/*typename*/ T::InnerType)>), 37 // expected-warning@+1 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}} 38 y1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(T::InnerVar)>), 39 y2 = sizeof(typename T::template InnerTemplate<sizeof(T::InnerVar)>), 40 z = sizeof(T::template InnerTemplate<sizeof(T::InnerVar)>::x), 41 }; 42 }; 43 struct Bar { 44 template <int N> 45 struct InnerTemplate { int x[N]; }; 46 typedef double InnerType; 47 static const int InnerVar = 42; 48 }; 49 template struct Foo<Bar>; // expected-note-re {{in instantiation {{.*}} requested here}} 50 } 51 52 namespace ambiguous_missing_parens { 53 // expected-error@+1 {{'Q::U' instantiated to a class template, not a function template}} 54 template <typename T> void f() { int a = sizeof T::template U<0> + 4; } 55 struct Q { 56 // expected-error@+1 {{class template declared here}} 57 template <int> struct U {}; 58 }; 59 // expected-note-re@+1 {{in instantiation {{.*}} requested here}} 60 template void f<Q>(); 61 } 62