Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 namespace N {
      3   struct A {
      4     typedef int type;
      5   };
      6 
      7   struct B {
      8   };
      9 
     10   struct C {
     11     struct type { };
     12     int type; // expected-note 2{{referenced member 'type' is declared here}}
     13   };
     14 }
     15 
     16 int i;
     17 
     18 typename N::A::type *ip1 = &i; // expected-warning{{'typename' occurs outside of a template}}
     19 typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} \
     20 // expected-warning{{'typename' occurs outside of a template}}
     21 typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} \
     22 // expected-warning{{'typename' occurs outside of a template}}
     23 
     24 void test(double d) {
     25   typename N::A::type f(typename N::A::type(a)); // expected-warning{{disambiguated as a function declaration}} \
     26   // expected-note{{add a pair of parentheses}} expected-warning 2{{'typename' occurs outside of a template}}
     27   int five = f(5);
     28 
     29   using namespace N;
     30   for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' occurs outside of a template}}
     31     five += 1;
     32 
     33   const typename N::A::type f2(d); // expected-warning{{'typename' occurs outside of a template}}
     34 }
     35 
     36 namespace N {
     37   template<typename T>
     38   struct X {
     39     typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \
     40     // expected-error {{no type named 'type' in 'B'}} \
     41     // FIXME: location info for error above isn't very good \
     42     // expected-error 2{{typename specifier refers to non-type member 'type'}} \
     43     // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
     44   };
     45 }
     46 
     47 N::X<N::A>::type *ip4 = &i;
     48 N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}}
     49 N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}}
     50 
     51 N::X<int>::type fail1; // expected-note{{in instantiation of template class 'N::X<int>' requested here}}
     52 
     53 template<typename T>
     54 struct Y {
     55   typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
     56   // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
     57 };
     58 
     59 struct A {
     60   typedef int type;
     61 };
     62 
     63 struct B {
     64 };
     65 
     66 struct C {
     67   struct type { };
     68   int type; // expected-note{{referenced member 'type' is declared here}}
     69 };
     70 
     71 ::Y<A>::type ip7 = &i;
     72 ::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
     73 ::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
     74 
     75 template<typename T> struct D {
     76   typedef typename T::foo foo;  // expected-error {{type 'long' cannot be used prior to '::' because it has no members}}
     77   typedef typename foo::bar bar;
     78 };
     79 
     80 D<long> struct_D;  // expected-note {{in instantiation of template class 'D<long>' requested here}}
     81 
     82 template<typename T> struct E {
     83   typedef typename T::foo foo;
     84   typedef typename foo::bar bar;  // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}}
     85 };
     86 
     87 struct F {
     88   typedef double foo;
     89 };
     90 
     91 E<F> struct_E; // expected-note {{in instantiation of template class 'E<F>' requested here}}
     92 
     93 template<typename T> struct G {
     94   typedef typename T::foo foo;
     95   typedef typename foo::bar bar;
     96 };
     97 
     98 struct H {
     99   struct foo {
    100     typedef double bar;
    101   };
    102 };
    103 
    104 G<H> struct_G;
    105 
    106 namespace PR10925 {
    107   template< int mydim, typename Traits >
    108   class BasicGeometry
    109   {
    110     typedef int some_type_t;
    111   };
    112 
    113   template<class ctype, int mydim, int coorddim>
    114   class MockGeometry : BasicGeometry<mydim, int>{
    115     using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
    116   };
    117 }
    118 
    119 
    120 namespace missing_typename {
    121 template <class T1, class T2> struct pair {}; // expected-note 7 {{template parameter is declared here}}
    122 
    123 template <class T1, class T2>
    124 struct map {
    125   typedef T1* iterator;
    126 };
    127 
    128 template <class T>
    129 class ExampleClass1 {
    130   struct ExampleItem;
    131 
    132 
    133   struct ExampleItemSet {
    134     typedef ExampleItem* iterator;
    135     ExampleItem* operator[](unsigned);
    136   };
    137 
    138   void foo() {
    139     pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
    140     pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
    141     pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
    142   }
    143   pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
    144 
    145 
    146   typedef map<int, ExampleItem*> ExampleItemMap;
    147 
    148   static void bar() {
    149     pair<ExampleItemMap::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
    150   }
    151   pair<ExampleItemMap::iterator, int> entry; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
    152   pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}}
    153 };
    154 } // namespace missing_typename
    155