1 //===--- fwd_decl_nested_class.cc - test input file for iwyu --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // Various tests of the handling of the forward declaration of nested
11 // classes. For some uses the forward declaration is needed, for
12 // others it isn't.
13
TplFn()14 template<typename T> void TplFn() { T t; (void)t; }
15
16 class Foo {
17 class NoUsage; // Unnecessary -- defined inline later in the class.
18 class NoUsageDefinedOutOfLine; // Necessary -- part of the public API.
19 class UsedAsPtrInMethod; // Unnecessary -- all uses see the later dfn.
20 class UsedFullyInMethod; // Unnecessary -- all uses see the later dfn.
21 class UsedFullyInInitializer; // Unnecessary -- same as in a method.
22 class UsedImplicitlyInInitializer; // Unnecessary -- same as explicit use.
23 class UsedInTypedef; // Necessary -- this use doesn't see the later dfn.
24 class UsedAsPtrArg; // Necessary -- this use doesn't see the later dfn.
25 class UsedAsPtrReturn; // Necessary -- this use doesn't see the later dfn.
26 class UsedAsPtrMember; // Necessary -- this use doesn't see the later dfn.
27 class UsedAsFriend; // Necessary -- used as part of a friend declaration
28
29 friend class Foo::UsedAsFriend;
30
Foo()31 Foo() : init_(UsedFullyInInitializer()) { }
~Foo()32 ~Foo() { }
33
34 // If a nested class is used in a body of a method, no preceding
35 // declaration/definition is needed.
Bar1()36 void Bar1() {
37 UsedAsPtrInMethod* x;
38 }
Bar2()39 void Bar2() {
40 UsedFullyInMethod x;
41 UsedFullyInMethodNotForwardDeclared y;
42 // Make sure we don't have trouble saying we're inside a method
43 // even when templates get in the way.
44 TplFn<UsedFullyInMethodNotForwardDeclared>();
45 }
46
47 // If a nested class is used in a typedef, a preceding declaration
48 // is needed.
49 typedef UsedInTypedef UsedInTypedefType;
50
51 // If a nested class is used in a method declaration, a preceding
52 // declaration is needed.
53 void Bar3(UsedAsPtrArg* p);
54 UsedAsPtrReturn* Bar4();
55
56 UsedAsPtrMember* x_;
57
58 class NoUsage { };
59 class UsedAsPtrInMethod { };
60 class UsedFullyInMethod { };
61 class UsedFullyInInitializer { };
62 class UsedImplicitlyInInitializer { };
63 class UsedImplicitlyInInitializerNeverDeclared { };
64 class UsedAsPtrArg { };
65 class UsedAsPtrReturn { };
66 class UsedAsPtrMember { };
67 struct UsedFullyInMethodNotForwardDeclared { };
68 class UsedAsFriend { };
69
70 UsedFullyInInitializer init_;
71 UsedImplicitlyInInitializer implicit_;
72 UsedImplicitlyInInitializerNeverDeclared implicit_never_declared_;
73 UsedImplicitlyInInitializerNeverDeclared* implicit_never_declared_ptr_;
74 };
75
76 class Foo::NoUsageDefinedOutOfLine {};
77
78 // Now do the same thing again, but the nested classes are all templated.
79
80 class Outer {
81 template<typename T> class NoUsage; // Unnecessary
82 template<typename T> class NoUsageDefinedOutOfLine; // Necessary
83 template<typename T> class NoUsageDefinedOutOfLine; // Unnecessary
84 template<typename T> class UsedAsPtrInMethod; // Unnecessary
85 template<typename T> class UsedFullyInMethod; // Unnecessary
86 template<typename T> class UsedFullyInInitializer; // Unnecessary
87 template<typename T> class UsedImplicitlyInInitializer; // Unnecessary
88 template<typename T> class UsedInTypedef; // Necessary
89 template<typename T> class UsedAsPtrArg; // Necessary
90 template<typename T> class UsedAsPtrReturn; // Necessary
91 template<typename T> class UsedAsPtrMember; // Necessary
92 template<typename T> class UsedAsFriend; // Necessary
93
94 friend class Outer::UsedAsFriend<int>;
95
Outer()96 Outer() : init_(UsedFullyInInitializer<int>()) { }
~Outer()97 ~Outer() { }
98
99 // If a nested class is used in a body of a method, no preceding
100 // declaration/definition is needed.
Bar1()101 void Bar1() {
102 UsedAsPtrInMethod<int>* x;
103 }
Bar2()104 void Bar2() {
105 UsedFullyInMethod<int> x;
106 UsedFullyInMethodNotForwardDeclared<int> y;
107 TplFn<UsedFullyInMethodNotForwardDeclared<int> >();
108 }
109
110 // If a nested class is used in a typedef, a preceding declaration
111 // is needed.
112 typedef UsedInTypedef<int> UsedInTypedefType;
113
114 // If a nested class is used in a method declaration, a preceding
115 // declaration is needed.
116 void Bar3(UsedAsPtrArg<int>* p);
117 UsedAsPtrReturn<int>* Bar4();
118
119 UsedAsPtrMember<int>* x_;
120
121 template<typename T> class NoUsage { };
122 template<typename T> class UsedAsPtrInMethod { };
123 template<typename T> class UsedFullyInMethod { };
124 template<typename T> class UsedFullyInInitializer { };
125 template<typename T> class UsedImplicitlyInInitializer { };
126 template<typename T> class UsedImplicitlyInInitializerNeverDeclared { };
127 template<typename T> class UsedAsPtrArg { };
128 template<typename T> class UsedAsPtrReturn { };
129 template<typename T> class UsedAsPtrMember { };
130 template<typename T> class UsedFullyInMethodNotForwardDeclared { };
131 template<typename T> class UsedAsFriend { };
132
133 UsedFullyInInitializer<int> init_;
134 UsedImplicitlyInInitializer<int> implicit_;
135 UsedImplicitlyInInitializerNeverDeclared<int> implicit_never_declared_;
136 UsedImplicitlyInInitializerNeverDeclared<int>* implicit_never_declared_ptr_;
137 };
138
139 template<typename T> class Outer::NoUsageDefinedOutOfLine {};
140
141
142 // Now do the same thing again, but the containing class is templated
143
144 template<class T>
145 class Container {
146 class NoUsage; // Unnecessary
147 class UsedAsPtrInMethod; // Unnecessary
148 class UsedFullyInMethod; // Unnecessary
149 class UsedFullyInInitializer; // Unnecessary
150 class UsedImplicitlyInInitializer; // Unnecessary
151 class UsedInTypedef; // Necessary
152 class UsedAsPtrArg; // Necessary
153 class UsedAsPtrReturn; // Necessary
154 class UsedAsPtrMember; // Necessary
155 class UsedAsFriend; // Necessary
156
157 friend class Container<T>::UsedAsFriend;
158
Container()159 Container() : init_(UsedFullyInInitializer()) { }
~Container()160 ~Container() { }
161
162 // If a nested class is used in a body of a method, no preceding
163 // declaration/definition is needed.
Bar1()164 void Bar1() {
165 UsedAsPtrInMethod* x;
166 }
Bar2()167 void Bar2() {
168 UsedFullyInMethod x;
169 UsedFullyInMethodNotForwardDeclared y;
170 TplFn<UsedFullyInMethodNotForwardDeclared>();
171 }
172
173 // If a nested class is used in a typedef, a preceding declaration
174 // is needed.
175 typedef UsedInTypedef UsedInTypedefType;
176
177 // If a nested class is used in a method declaration, a preceding
178 // declaration is needed.
179 void Bar3(UsedAsPtrArg* p);
180 UsedAsPtrReturn* Bar4();
181
182 UsedAsPtrMember* x_;
183
184 class NoUsage { };
185 class UsedAsPtrInMethod { };
186 class UsedFullyInMethod { };
187 class UsedFullyInInitializer { };
188 class UsedImplicitlyInInitializer { };
189 class UsedImplicitlyInInitializerNeverDeclared { };
190 class UsedAsPtrArg { };
191 class UsedAsPtrReturn { };
192 class UsedAsPtrMember { };
193 class UsedFullyInMethodNotForwardDeclared { };
194 class UsedAsFriend { };
195
196 UsedFullyInInitializer init_;
197 UsedImplicitlyInInitializer implicit_;
198 UsedImplicitlyInInitializerNeverDeclared implicit_never_declared_;
199 UsedImplicitlyInInitializerNeverDeclared* implicit_never_declared_ptr_;
200 };
201
202 /**** IWYU_SUMMARY
203
204 tests/cxx/fwd_decl_nested_class.cc should add these lines:
205
206 tests/cxx/fwd_decl_nested_class.cc should remove these lines:
207 - class Container::NoUsage; // lines XX-XX
208 - class Container::UsedAsPtrInMethod; // lines XX-XX
209 - class Container::UsedFullyInInitializer; // lines XX-XX
210 - class Container::UsedFullyInMethod; // lines XX-XX
211 - class Container::UsedImplicitlyInInitializer; // lines XX-XX
212 - class Foo::NoUsage; // lines XX-XX
213 - class Foo::UsedAsPtrInMethod; // lines XX-XX
214 - class Foo::UsedFullyInInitializer; // lines XX-XX
215 - class Foo::UsedFullyInMethod; // lines XX-XX
216 - class Foo::UsedImplicitlyInInitializer; // lines XX-XX
217 - template <typename T> class Outer::NoUsage; // lines XX-XX
218 - template <typename T> class Outer::NoUsageDefinedOutOfLine; // lines XX-XX
219 - template <typename T> class Outer::UsedAsPtrInMethod; // lines XX-XX
220 - template <typename T> class Outer::UsedFullyInInitializer; // lines XX-XX
221 - template <typename T> class Outer::UsedFullyInMethod; // lines XX-XX
222 - template <typename T> class Outer::UsedImplicitlyInInitializer; // lines XX-XX
223
224 The full include-list for tests/cxx/fwd_decl_nested_class.cc:
225 class Container::UsedAsFriend; // lines XX-XX
226 class Container::UsedAsPtrArg; // lines XX-XX
227 class Container::UsedAsPtrMember; // lines XX-XX
228 class Container::UsedAsPtrReturn; // lines XX-XX
229 class Container::UsedInTypedef; // lines XX-XX
230 class Foo::NoUsageDefinedOutOfLine; // lines XX-XX
231 class Foo::UsedAsFriend; // lines XX-XX
232 class Foo::UsedAsPtrArg; // lines XX-XX
233 class Foo::UsedAsPtrMember; // lines XX-XX
234 class Foo::UsedAsPtrReturn; // lines XX-XX
235 class Foo::UsedInTypedef; // lines XX-XX
236 template <typename T> class Outer::NoUsageDefinedOutOfLine; // lines XX-XX
237 template <typename T> class Outer::UsedAsFriend; // lines XX-XX
238 template <typename T> class Outer::UsedAsPtrArg; // lines XX-XX
239 template <typename T> class Outer::UsedAsPtrMember; // lines XX-XX
240 template <typename T> class Outer::UsedAsPtrReturn; // lines XX-XX
241 template <typename T> class Outer::UsedInTypedef; // lines XX-XX
242
243 ***** IWYU_SUMMARY */
244