1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3class C {
4    struct S; // expected-note {{previously declared 'private' here}}
5public:
6
7    struct S {}; // expected-error {{'S' redeclared with 'public' access}}
8};
9
10struct S {
11    class C; // expected-note {{previously declared 'public' here}}
12
13private:
14    class C { }; // expected-error {{'C' redeclared with 'private' access}}
15};
16
17class T {
18protected:
19    template<typename T> struct A; // expected-note {{previously declared 'protected' here}}
20
21private:
22    template<typename T> struct A {}; // expected-error {{'A' redeclared with 'private' access}}
23};
24
25// PR5573
26namespace test1 {
27  class A {
28  private:
29    class X; // expected-note {{previously declared 'private' here}} \
30             // expected-note {{previous declaration is here}}
31  public:
32    class X; // expected-error {{'X' redeclared with 'public' access}} \
33             // expected-warning {{class member cannot be redeclared}}
34    class X {};
35  };
36}
37
38// PR15209
39namespace PR15209 {
40  namespace alias_templates {
41    template<typename T1, typename T2> struct U { };
42    template<typename T1> using W = U<T1, float>;
43
44    class A {
45      typedef int I;
46      static constexpr I x = 0; // expected-note {{implicitly declared private here}}
47      static constexpr I y = 42; // expected-note {{implicitly declared private here}}
48      friend W<int>;
49    };
50
51    template<typename T1>
52    struct U<T1, float>  {
53      int v_;
54      // the following will trigger for U<float, float> instantiation, via W<float>
55      U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
56    };
57
58    template<typename T1>
59    struct U<T1, int> {
60      int v_;
61      U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
62    };
63
64    template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}
65
66    void f()
67    {
68      W<int>();
69      // we should issue diagnostics for the following
70      W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
71    }
72  }
73
74  namespace templates {
75    class A {
76      typedef int I;  // expected-note {{implicitly declared private here}}
77      static constexpr I x = 0; // expected-note {{implicitly declared private here}}
78
79      template<int> friend struct B;
80      template<int> struct C;
81      template<template<int> class T> friend struct TT;
82      template<typename T> friend void funct(T);
83    };
84    template<A::I> struct B { };
85
86    template<A::I> struct A::C { };
87
88    template<template<A::I> class T> struct TT {
89      T<A::x> t;
90    };
91
92    template struct TT<B>;
93    template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
94    template struct TT<D>;
95
96    // function template case
97    template<typename T>
98    void funct(T)
99    {
100      (void)A::x;
101    }
102
103    template void funct<int>(int);
104
105    void f()
106    {
107      (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
108    }
109  }
110}
111
112namespace PR7434 {
113  namespace comment0 {
114    template <typename T> struct X;
115    namespace N {
116    class Y {
117      template<typename T> friend struct X;
118      int t; // expected-note {{here}}
119    };
120    }
121    template<typename T> struct X {
122      X() { (void)N::Y().t; } // expected-error {{private}}
123    };
124    X<char> x;
125  }
126  namespace comment2 {
127    struct X;
128    namespace N {
129    class Y {
130      friend struct X;
131      int t; // expected-note {{here}}
132    };
133    }
134    struct X {
135      X() { (void)N::Y().t; } // expected-error {{private}}
136    };
137  }
138}
139
140namespace LocalExternVar {
141  class test {
142  private:
143    struct private_struct { // expected-note 2{{here}}
144      int x;
145    };
146    int use_private();
147  };
148
149  int test::use_private() {
150    extern int array[sizeof(test::private_struct)]; // ok
151    return array[0];
152  }
153
154  int f() {
155    extern int array[sizeof(test::private_struct)]; // expected-error {{private}}
156    return array[0];
157  }
158
159  int array[sizeof(test::private_struct)]; // expected-error {{private}}
160}
161