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 {
type_f()7 template <typename T> int type_f() { return sizeof T::type; } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
type_g()8 template <typename T> int type_g() { return sizeof(T::type); } // expected-warning {{missing 'typename' prior to dependent type name 'X::type'}}
type_h()9 template <typename T> int type_h() { return sizeof((T::type)); } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
value_f()10 template <typename T> int value_f() { return sizeof T::not_a_type; }
value_g()11 template <typename T> int value_g() { return sizeof(T::not_a_type); }
value_h()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 };
bar()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}}
f()54 template <typename T> void f() { int a = sizeof T::template U<0> + 4; }
55 struct Q {
56 // expected-note@+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