reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T, typename U> 
struct is_same {
  static const bool value = false;
};

template<typename T>
struct is_same<T, T> {
  static const bool value = true;
};

template<typename MetaFun, typename T1, typename T2>
struct metafun_apply2 {
  typedef typename MetaFun::template apply<T1, T2> inner;
  typedef typename inner::type type;
};

template<typename T, typename U> struct pair;

struct make_pair {
  template<typename T1, typename T2>
  struct apply {
    typedef pair<T1, T2> type;
  };
};

int a0[is_same<metafun_apply2<make_pair, int, float>::type, 
               pair<int, float> >::value? 1 : -1];
int a1[is_same<
         typename make_pair::template apply<int, float>, 
#if __cplusplus <= 199711L // C++03 and earlier modes
         // expected-warning@-2 {{'template' keyword outside of a template}}
         // expected-warning@-3 {{'typename' occurs outside of a template}}
#endif
         make_pair::apply<int, float>
       >::value? 1 : -1];

template<typename MetaFun>
struct swap_and_apply2 {
  template<typename T1, typename T2>
  struct apply {
    typedef typename MetaFun::template apply<T2, T1> new_metafun;
    typedef typename new_metafun::type type;
  };
};

int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, 
               pair<float, int> >::value? 1 : -1];

template<typename MetaFun>
struct swap_and_apply2b {
  template<typename T1, typename T2>
  struct apply {
    typedef typename MetaFun::template apply<T2, T1>::type type;
  };
};

int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type, 
               pair<float, int> >::value? 1 : -1];

template<typename T>
struct X0 {
  template<typename U, typename V>
  struct Inner;
  
  void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
  void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}

  void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
  void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}

  void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
  void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
};

namespace PR6236 {
  template<typename T, typename U> struct S { };
  
  template<typename T> struct S<T, T> {
    template<typename U> struct K { };
    
    void f() {
      typedef typename S<T, T>::template K<T> Foo;
    }
  };
}

namespace PR6268 {
  template <typename T>
  struct Outer {
    template <typename U>
    struct Inner {};

    template <typename U>
    typename Outer<T>::template Inner<U>
    foo(typename Outer<T>::template Inner<U>);
  };

  template <typename T>
  template <typename U>
  typename Outer<T>::template Inner<U>
  Outer<T>::foo(typename Outer<T>::template Inner<U>) {
    return Inner<U>();
  }
}

namespace PR6463 {
  struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
  struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}

  template<typename T>
  struct A : B, C { 
    type& a(); // expected-error{{found in multiple base classes}}
    int x; 
  };

  // FIXME: Improve source location info here.
  template<typename T>
  typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
    return x;
  }
}

namespace PR7419 {
  template <typename T> struct S {
    typedef typename T::Y T2;
    typedef typename T2::Z T3;
    typedef typename T3::W T4;
    T4 *f();

    typedef typename T::template Y<int> TT2;
    typedef typename TT2::template Z<float> TT3;
    typedef typename TT3::template W<double> TT4;
    TT4 g();
  };

  template <typename T> typename T::Y::Z::W *S<T>::f() { }
  template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
}

namespace rdar8740998 {
  template<typename T>
  struct X : public T {
    using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
    // expected-error{{dependent using declaration resolved to type without 'typename'}}

    void f() {
      typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
    }
  };

  struct HasIterator {
    typedef int *iterator; // expected-note{{target of using declaration}}
  };

  void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
    xi.f();
  }
}

namespace rdar9068589 {
  // From GCC PR c++/13950
  template <class T> struct Base {};
  template <class T> struct Derived: public Base<T> {
    typename Derived::template Base<double>* p1;
  };
}