1ef8f90caa14d85cffba2fea4b6bd425c3b22eea7Richard Trieu// RUN: %clang_cc1 -Wno-uninitialized -std=c++11 -verify %s
29bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
39bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithtemplate<int> struct c { c(int) = delete; typedef void val; operator int() const; };
49bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
59bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithint val;
69bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithint foobar;
79bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithstruct S {
89bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k1 = a < b < c, d > ::val, e1;
99bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k2 = a < b, c < d > ::val, e2;
109bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k3 = b < a < c, d > ::val, e3;
119bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k4 = b < c, x, y = d > ::val, e4;
129bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k5 = T1 < b, &S::operator=(int); // expected-error {{extra qualification}}
139bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k6 = T2 < b, &S::operator= >::val;
149bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k7 = T1 < b, &S::operator>(int); // expected-error {{extra qualification}}
159bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k8 = T2 < b, &S::operator> >::val;
169bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k9 = T3 < a < b, c >> (d), e5 = 1 > (e4);
179bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k10 = 0 < T3 < a < b, c >> (d
189bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      ) // expected-error {{expected ';' at end of declaration}}
199bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      , a > (e4);
209bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k11 = 0 < 1, c<3>::*ptr;
219bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int k12 = e < 0, int a<b<c>::* >(), e11;
229bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
239bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f1(
249bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = a < b < c, d > ::val,
259bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k2 = b < a < c, d > ::val,
269bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k3 = b < c, int x = 0 > ::val,
279bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k4 = a < b, T3 < int > >(), // expected-error {{must be an expression}}
289bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k5 = a < b, c < d > ::val,
299bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k6 = a < b, c < d > (n) // expected-error {{undeclared identifier 'n'}}
309bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
319bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
329bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f2a(
339bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    // T3<int> here is a parameter type, so must be declared before it is used.
349bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = c < b, T3 < int > x = 0 // expected-error {{unexpected end of default argument expression}}
359bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
369bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
379bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<typename, int=0> struct T3 { T3(int); operator int(); };
389bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
399bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f2b(
409bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = c < b, T3 < int > x  = 0 // ok
419bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
429bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
439bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  // This is a one-parameter function. Ensure we don't typo-correct it to
449bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  //     int = a < b, c < foobar > ()
459bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  // ... which would be a function with two parameters.
469bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int f3(int = a < b, c < goobar > ());
479bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  static constexpr int (S::*f3_test)(int) = &S::f3;
489bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
499bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f4(
509bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = a<1,2>::val,
519bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int missing_default // expected-error {{missing default argument on parameter}}
529bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
539bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
549bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f5(
559bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = b < c,
569bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int missing_default // expected-error {{missing default argument on parameter}}
579bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
589bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
599bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  void f6(
609bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k = b < c,
619bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    unsigned int (missing_default) // expected-error {{missing default argument on parameter}}
629bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  );
639bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
649bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<int, int=0> struct a { static const int val = 0; operator int(); }; // expected-note {{here}}
659bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  static const int b = 0, c = 1, d = 2, goobar = 3;
669bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<int, typename> struct e { operator int(); };
679bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
689bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int mp1 = 0 < 1,
699bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      a<b<c,b<c>::*mp2,
709bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      mp3 = 0 > a<b<c>::val,
719bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      a<b<c,b<c>::*mp4 = 0,
729bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      a<b<c,b<c>::*mp5 {0},
739bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith      a<b<c,b<c>::*mp6;
749bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
759bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  int np1 = e<0, int a<b<c,b<c>::*>();
769bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
779bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  static const int T1 = 4;
789bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<int, int &(S::*)(int)> struct T2 { static const int val = 0; };
799bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith};
809bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
819bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithnamespace NoAnnotationTokens {
829bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<bool> struct Bool { Bool(int); };
839bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  static const bool in_class = false;
849bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
859bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct Test {
869bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    // Check we don't keep around a Bool<false> annotation token here.
879bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int f(Bool<true> = X<Y, Bool<in_class> >(0));
889bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
899bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    // But it's OK if we do here.
909bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int g(Bool<true> = Z<Y, Bool<in_class> = Bool<false>(0));
919bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
929bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    static const bool in_class = true;
939bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<int, typename U> using X = U;
949bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    static const int Y = 0, Z = 0;
959bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
969bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith}
979bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
989bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithnamespace ImplicitInstantiation {
999bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template<typename T> struct HasError { typename T::error error; }; // expected-error {{has no members}}
1009bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1019bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct S {
1029bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    // This triggers the instantiation of the outer HasError<int> during
1039bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    // disambiguation, even though it uses the inner HasError<int>.
1049bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    void f(int a = X<Y, HasError<int>::Z >()); // expected-note {{in instantiation of}}
1059bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1069bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<typename, typename> struct X { operator int(); };
1079bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    typedef int Y;
1089bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<typename> struct HasError { typedef int Z; };
1099bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1109bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1119bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  HasError<int> hei;
1129bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith}
1139bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1149bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithnamespace CWG325 {
1159bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  template <int A, typename B> struct T { static int i; operator int(); };
1169bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  class C {
1179bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int Foo (int i = T<1, int>::i);
1189bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1199bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1209bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  class D {
1219bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int Foo (int i = T<1, int>::i);
1229bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template <int A, typename B> struct T {static int i;};
1239bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1249bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1259bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  const int a = 0;
1269bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  typedef int b;
1279bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  T<a,b> c;
1289bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct E {
1299bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int n = T<a,b>(c);
1309bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1319bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith}
1329bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1339bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithnamespace Operators {
1349bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct Y {};
1359bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  constexpr int operator,(const Y&, const Y&) { return 8; }
1369bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  constexpr int operator>(const Y&, const Y&) { return 8; }
1379bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  constexpr int operator<(const Y&, const Y&) { return 8; }
1389bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  constexpr int operator>>(const Y&, const Y&) { return 8; }
1399bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1409bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct X {
1419bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    typedef int (*Fn)(const Y&, const Y&);
1429bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1439bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    Fn a = operator,, b = operator<, c = operator>;
1449bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    void f(Fn a = operator,, Fn b = operator<, Fn c = operator>);
1459bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1469bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k1 = T1<0, operator<, operator>, operator<>::val, l1;
1479bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k2 = T1<0, operator>, operator,, operator,>::val, l2;
1489bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k3 = T2<0, operator,(Y{}, Y{}),  operator<(Y{}, Y{})>::val, l3;
1499bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k4 = T2<0, operator>(Y{}, Y{}),  operator,(Y{}, Y{})>::val, l4;
1509bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k5 = T3<0, operator>>>::val, l5;
1519bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int k6 = T4<0, T3<0, operator>>>>::val, l6;
1529bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1539bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<int, Fn, Fn, Fn> struct T1 { enum { val }; };
1549bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<int, int, int> struct T2 { enum { val }; };
1559bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<int, Fn> struct T3 { enum { val }; };
1569bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template<int, typename T> struct T4 : T {};
1579bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1589bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith}
1599bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith
1609bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smithnamespace ElaboratedTypeSpecifiers {
1619bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  struct S {
1629bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int f(int x = T<a, struct S>());
1639bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int h(int x = T<a, union __attribute__(()) U>());
1649bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int i(int x = T<a, enum E>());
1659bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    int j(int x = T<a, struct S::template T<0, enum E>>());
1669bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    template <int, typename> struct T { operator int(); };
1679bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    static const int a = 0;
1689bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith    enum E {};
1699bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith  };
1709bd3cdc3b78653275a36f15df81e1def3b2db8dbRichard Smith}
171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
172176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace PR20459 {
173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  template <typename EncTraits> struct A {
174176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines     void foo(int = EncTraits::template TypeEnc<int, int>::val); // ok
175176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  };
176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
177