Home | History | Annotate | Download | only in SemaTemplate
      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