// RUN: %clang_cc1 -std=c++11 %s -verify

namespace PR15757 {
  struct S {
  };

  template<typename X, typename Y> struct T {
    template<typename A> T(X x, A &&a) {}

    template<typename A> explicit T(A &&a)
        noexcept(noexcept(T(X(), static_cast<A &&>(a))))
      : T(X(), static_cast<A &&>(a)) {}
  };

  template<typename X, typename Y> struct U : T<X, Y> {
    using T<X, Y>::T;
  };

  U<S, char> foo(char ch) { return U<S, char>(ch); }

  int main() {
    U<S, int> a(42);
    U<S, char> b('4');
    return 0;
  }
}

namespace WrongIdent {
  struct A {};
  struct B : A {};
  struct C : B {
    using B::A;
  };
}

namespace DefaultCtorConflict {
  struct A { A(int = 0); };
  struct B : A {
    using A::A;
  } b; // ok, not ambiguous, inherited constructor suppresses implicit default constructor
  struct C {
    B b;
  } c;
}

namespace InvalidConstruction {
  struct A { A(int); };
  struct B { B() = delete; };
  struct C : A, B { using A::A; };
  // Initialization here is performed as if by a defaulted default constructor,
  // which would be ill-formed (in the immediate context) in this case because
  // it would be defined as deleted.
  template<typename T> void f(decltype(T(0))*);
  template<typename T> int &f(...);
  int &r = f<C>(0);
}

namespace ExplicitConv {
  struct B {};
  struct D : B { // expected-note 3{{candidate}}
    using B::B;
  };
  struct X { explicit operator B(); } x;
  struct Y { explicit operator D(); } y;

  D dx(x); // expected-error {{no matching constructor}}
  D dy(y);
}

namespace NestedListInit {
  struct B { B(); } b; // expected-note 3{{candidate}}
  struct D : B { // expected-note 14{{not viable}}
    using B::B;
  };
  // This is a bit weird. We're allowed one pair of braces for overload
  // resolution, and one more pair of braces due to [over.ics.list]/2.
  B b1 = {b};
  B b2 = {{b}};
  B b3 = {{{b}}}; // expected-error {{no match}}
  // Per a proposed defect resolution, we don't get to call
  // D's version of B::B(const B&) here.
  D d0 = b; // expected-error {{no viable conversion}}
  D d1 = {b}; // expected-error {{no match}}
  D d2 = {{b}}; // expected-error {{no match}}
  D d3 = {{{b}}}; // expected-error {{no match}}
  D d4 = {{{{b}}}}; // expected-error {{no match}}
}

namespace PR31606 {
  // PR31606: as part of a proposed defect resolution, do not consider
  // inherited constructors that would be copy constructors for any class
  // between the declaring class and the constructed class (inclusive).
  struct Base {};

  struct A : Base {
    using Base::Base;
    bool operator==(A const &) const; // expected-note {{no known conversion from 'PR31606::B' to 'const PR31606::A' for 1st argument}}
  };

  struct B : Base {
    using Base::Base;
  };

  bool a = A{} == A{};
  // Note, we do *not* allow operator=='s argument to use the inherited A::A(Base&&) constructor to construct from B{}.
  bool b = A{} == B{}; // expected-error {{invalid operands}}
}

namespace implicit_member_srcloc {
  template<class T>
  struct S3 {
  };

  template<class T>
  struct S2 {
    S2(S3<T> &&);
  };

  template<class T>
  struct S1 : S2<T> {
    using S2<T>::S2;
    S1();
  };

  template<class T>
  struct S0 {
    S0();
    S0(S0&&) = default;
    S1<T> m1;
  };

  void foo1() {
    S0<int> s0;
  }
}
