1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 
3 class C {
4     struct S; // expected-note {{previously declared 'private' here}}
5 public:
6 
7     struct S {}; // expected-error {{'S' redeclared with 'public' access}}
8 };
9 
10 struct S {
11     class C; // expected-note {{previously declared 'public' here}}
12 
13 private:
14     class C { }; // expected-error {{'C' redeclared with 'private' access}}
15 };
16 
17 class T {
18 protected:
19     template<typename T> struct A; // expected-note {{previously declared 'protected' here}}
20 
21 private:
22     template<typename T> struct A {}; // expected-error {{'A' redeclared with 'private' access}}
23 };
24 
25 // PR5573
26 namespace test1 {
27   class A {
28   private:
29     class X; // expected-note {{previously declared 'private' here}}
30   public:
31     class X; // expected-error {{'X' redeclared with 'public' access}}
32     class X {};
33   };
34 }
35 
36 // PR15209
37 namespace PR15209 {
38   namespace alias_templates {
39     template<typename T1, typename T2> struct U { };
40     template<typename T1> using W = U<T1, float>;
41 
42     class A {
43       typedef int I;
44       static constexpr I x = 0; // expected-note {{implicitly declared private here}}
45       static constexpr I y = 42; // expected-note {{implicitly declared private here}}
46       friend W<int>;
47     };
48 
49     template<typename T1>
50     struct U<T1, float>  {
51       int v_;
52       // the following will trigger for U<float, float> instantiation, via W<float>
53       U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
54     };
55 
56     template<typename T1>
57     struct U<T1, int> {
58       int v_;
59       U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
60     };
61 
62     template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}
63 
64     void f()
65     {
66       W<int>();
67       // we should issue diagnostics for the following
68       W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
69     }
70   }
71 
72   namespace templates {
73     class A {
74       typedef int I;  // expected-note {{implicitly declared private here}}
75       static constexpr I x = 0; // expected-note {{implicitly declared private here}}
76 
77       template<int> friend struct B;
78       template<int> struct C;
79       template<template<int> class T> friend struct TT;
80       template<typename T> friend void funct(T);
81     };
82     template<A::I> struct B { };
83 
84     template<A::I> struct A::C { };
85 
86     template<template<A::I> class T> struct TT {
87       T<A::x> t;
88     };
89 
90     template struct TT<B>;
91     template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
92     template struct TT<D>;
93 
94     // function template case
95     template<typename T>
96     void funct(T)
97     {
98       (void)A::x;
99     }
100 
101     template void funct<int>(int);
102 
103     void f()
104     {
105       (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
106     }
107   }
108 }
109