1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
206245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregortemplate<typename T>
306245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorclass X0 {
406245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor  friend T;
506245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor};
606245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor
706245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorclass Y1 { };
806245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorenum E1 { };
906245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX0<Y1> x0a;
1006245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX0<Y1 *> x0b;
1106245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX0<int> x0c;
1206245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX0<E1> x0d;
1306245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor
1406245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregortemplate<typename T>
1506245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorclass X1 {
1606245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor  friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}}
1706245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor};
1806245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor
1906245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorstruct Y2 {
2006245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor  struct type { };
2106245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor};
2206245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor
2306245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregorstruct Y3 {
2406245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor  typedef int type;
2506245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor};
2606245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas Gregor
2706245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX1<Y2> x1a;
2806245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX1<Y3> x1b;
2906245bfb3ae40bb24a8bfb17eafeb266a4daf5caDouglas GregorX1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}}
30d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith
31ce6a10eaadd152f05103dfffe22ac20ef2c04615Nick Lewyckytemplate<typename T> class B;
32ce6a10eaadd152f05103dfffe22ac20ef2c04615Nick Lewycky
33d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smithtemplate<typename T>
34d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smithclass A {
35d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  T x;
36d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smithpublic:
37d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  class foo {};
38d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  static int y;
39ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  template <typename S> friend class B<S>::ty; // expected-warning {{dependent nested name specifier 'B<S>::' for friend class declaration is not supported}}
40d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith};
41d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith
42ce6426feda94ca716ee7743b71961850740eb08dRichard Smithtemplate<typename T> class B { typedef int ty; };
43ce6426feda94ca716ee7743b71961850740eb08dRichard Smith
44ce6426feda94ca716ee7743b71961850740eb08dRichard Smithtemplate<> class B<int> {
45ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  class ty {
46ce6426feda94ca716ee7743b71961850740eb08dRichard Smith    static int f(A<int> &a) { return a.y; } // ok, befriended
47ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  };
48ce6426feda94ca716ee7743b71961850740eb08dRichard Smith};
49ce6426feda94ca716ee7743b71961850740eb08dRichard Smithint f(A<char> &a) { return a.y; } // FIXME: should be an error
50ce6a10eaadd152f05103dfffe22ac20ef2c04615Nick Lewycky
51d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smithstruct {
52d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  // Ill-formed
53d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
54d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  unsigned friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
55d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  const volatile friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
56d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  int
57d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith          friend; // expected-error {{'friend' must appear first in a non-function declaration}}
58d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith
59d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  // OK
60d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  int friend foo(void);
61d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  friend int;
62d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  friend const volatile int;
63d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith      friend
64d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith
65d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith  float;
66ce6426feda94ca716ee7743b71961850740eb08dRichard Smith  template<typename T> friend class A<T>::foo; // expected-warning {{not supported}}
67d6f80daa84164ceeb8900da07f43b6a150edf713Richard Smith} a;
68ce6a10eaadd152f05103dfffe22ac20ef2c04615Nick Lewycky
69ce6a10eaadd152f05103dfffe22ac20ef2c04615Nick Lewyckyvoid testA() { (void)sizeof(A<int>); }
70