// RUN: %clang_cc1 -fsyntax-only -verify %s struct A0 { struct K { }; }; template <typename T> struct B0: A0 { static void f() { K k; } }; namespace E1 { typedef double A; template<class T> class B { typedef int A; }; template<class T> struct X : B<T> { A* blarg(double *dp) { return dp; } }; } namespace E2 { struct A { struct B; int *a; int Y; }; int a; template<class T> struct Y : T { struct B { /* ... */ }; B b; void f(int i) { a = i; } Y* p; }; Y<A> ya; } namespace PR14402 { template<typename T> struct A { typedef int n; int f(); struct B {}; struct C : B { // OK, can't be sure whether we derive from A yet. using A::n; int g() { return f(); } }; struct D { using A::n; // expected-error {{using declaration refers into 'A<T>::', which is not a base class of 'D'}} int g() { return f(); } // expected-error {{call to non-static member function 'f' of 'A' from nested type 'D'}} }; struct E { char &f(); }; struct F : E { // FIXME: Reject this prior to instantiation; f() is known to return int. char &g() { return f(); } // expected-error@-1 {{'PR14402::A<int>::f' is not a member of class 'PR14402::A<int>::F'}} // expected-error@-2 {{non-const lvalue reference to type 'char' cannot bind to a temporary of type 'int'}} }; }; template<> struct A<int>::B : A<int> {}; A<int>::C::n n = A<int>::C().g(); // 'not a member' char &r = A<int>::F().g(); // expected-note {{in instantiation of}} template<> struct A<char>::E : A<char> {}; // 'cannot bind to a temporary' char &s = A<char>::F().g(); // expected-note {{in instantiation of}} struct X; struct X { void f(); }; struct X; template<typename T> struct Y : X { void g() { X::f(); } }; }