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
  170
  171
  172
  173
  174
  175
  176
// RUN: %clang_cc1 -Wno-uninitialized -std=c++11 -verify %s

template<int> struct c { c(int) = delete; typedef void val; operator int() const; };

int val;
int foobar;
struct S {
  int k1 = a < b < c, d > ::val, e1;
  int k2 = a < b, c < d > ::val, e2;
  int k3 = b < a < c, d > ::val, e3;
  int k4 = b < c, x, y = d > ::val, e4;
  int k5 = T1 < b, &S::operator=(int); // expected-error {{extra qualification}}
  int k6 = T2 < b, &S::operator= >::val;
  int k7 = T1 < b, &S::operator>(int); // expected-error {{extra qualification}}
  int k8 = T2 < b, &S::operator> >::val;
  int k9 = T3 < a < b, c >> (d), e5 = 1 > (e4);
  int k10 = 0 < T3 < a < b, c >> (d
      ) // expected-error {{expected ';' at end of declaration}}
      , a > (e4);
  int k11 = 0 < 1, c<3>::*ptr;
  int k12 = e < 0, int a<b<c>::* >(), e11;

  void f1(
    int k1 = a < b < c, d > ::val,
    int k2 = b < a < c, d > ::val,
    int k3 = b < c, int x = 0 > ::val,
    int k4 = a < b, T3 < int > >(), // expected-error {{must be an expression}}
    int k5 = a < b, c < d > ::val,
    int k6 = a < b, c < d > (n) // expected-error {{undeclared identifier 'n'}}
  );

  void f2a(
    // T3<int> here is a parameter type, so must be declared before it is used.
    int k1 = c < b, T3 < int > x = 0 // expected-error {{no template named 'T3'}}
  );

  template<typename, int=0> struct T3 { T3(int); operator int(); };

  void f2b(
    int k1 = c < b, T3 < int > x  = 0 // ok
  );

  // This is a one-parameter function. Ensure we don't typo-correct it to
  //     int = a < b, c < foobar > ()
  // ... which would be a function with two parameters.
  int f3(int = a < b, c < goobar > ());
  static constexpr int (S::*f3_test)(int) = &S::f3;

  void f4(
    int k1 = a<1,2>::val,
    int missing_default // expected-error {{missing default argument on parameter}}
  );

  void f5(
    int k1 = b < c,
    int missing_default // expected-error {{missing default argument on parameter}}
  );

  void f6(
    int k = b < c,
    unsigned int (missing_default) // expected-error {{missing default argument on parameter}}
  );

  template<int, int=0> struct a { static const int val = 0; operator int(); }; // expected-note {{here}}
  static const int b = 0, c = 1, d = 2, goobar = 3;
  template<int, typename> struct e { operator int(); };

  int mp1 = 0 < 1,
      a<b<c,b<c>::*mp2,
      mp3 = 0 > a<b<c>::val,
      a<b<c,b<c>::*mp4 = 0,
      a<b<c,b<c>::*mp5 {0},
      a<b<c,b<c>::*mp6;

  int np1 = e<0, int a<b<c,b<c>::*>();

  static const int T1 = 4;
  template<int, int &(S::*)(int)> struct T2 { static const int val = 0; };
};

namespace NoAnnotationTokens {
  template<bool> struct Bool { Bool(int); };
  static const bool in_class = false;

  struct Test {
    // Check we don't keep around a Bool<false> annotation token here.
    int f(Bool<true> = X<Y, Bool<in_class> >(0));

    // But it's OK if we do here.
    int g(Bool<true> = Z<Y, Bool<in_class> = Bool<false>(0));

    static const bool in_class = true;
    template<int, typename U> using X = U;
    static const int Y = 0, Z = 0;
  };
}

namespace ImplicitInstantiation {
  template<typename T> struct HasError { typename T::error error; }; // expected-error {{has no members}}

  struct S {
    // This triggers the instantiation of the outer HasError<int> during
    // disambiguation, even though it uses the inner HasError<int>.
    void f(int a = X<Y, HasError<int>::Z >()); // expected-note {{in instantiation of}}

    template<typename, typename> struct X { operator int(); };
    typedef int Y;
    template<typename> struct HasError { typedef int Z; };
  };

  HasError<int> hei;
}

namespace CWG325 {
  template <int A, typename B> struct T { static int i; operator int(); };
  class C {
    int Foo (int i = T<1, int>::i);
  };

  class D {
    int Foo (int i = T<1, int>::i);
    template <int A, typename B> struct T {static int i;};
  };

  const int a = 0;
  typedef int b;
  T<a,b> c;
  struct E {
    int n = T<a,b>(c);
  };
}

namespace Operators {
  struct Y {};
  constexpr int operator,(const Y&, const Y&) { return 8; }
  constexpr int operator>(const Y&, const Y&) { return 8; }
  constexpr int operator<(const Y&, const Y&) { return 8; }
  constexpr int operator>>(const Y&, const Y&) { return 8; }

  struct X {
    typedef int (*Fn)(const Y&, const Y&);

    Fn a = operator,, b = operator<, c = operator>;
    void f(Fn a = operator,, Fn b = operator<, Fn c = operator>);

    int k1 = T1<0, operator<, operator>, operator<>::val, l1;
    int k2 = T1<0, operator>, operator,, operator,>::val, l2;
    int k3 = T2<0, operator,(Y{}, Y{}),  operator<(Y{}, Y{})>::val, l3;
    int k4 = T2<0, operator>(Y{}, Y{}),  operator,(Y{}, Y{})>::val, l4;
    int k5 = T3<0, operator>>>::val, l5;
    int k6 = T4<0, T3<0, operator>>>>::val, l6;

    template<int, Fn, Fn, Fn> struct T1 { enum { val }; };
    template<int, int, int> struct T2 { enum { val }; };
    template<int, Fn> struct T3 { enum { val }; };
    template<int, typename T> struct T4 : T {};
  };
}

namespace ElaboratedTypeSpecifiers {
  struct S {
    int f(int x = T<a, struct S>());
    int h(int x = T<a, union __attribute__(()) U>());
    int i(int x = T<a, enum E>());
    int j(int x = T<a, struct S::template T<0, enum E>>());
    template <int, typename> struct T { operator int(); };
    static const int a = 0;
    enum E {};
  };
}

namespace PR20459 {
  template <typename EncTraits> struct A {
     void foo(int = EncTraits::template TypeEnc<int, int>::val); // ok
  };
}