]>
Commit | Line | Data |
---|---|---|
bd6dd845 MS |
1 | /* Help friends in C++. |
2 | Copyright (C) 1997 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GNU CC. | |
5 | ||
6 | GNU CC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GNU CC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU CC; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
20 | ||
21 | #include "config.h" | |
da20811c | 22 | #include <stdio.h> |
bd6dd845 MS |
23 | #include "tree.h" |
24 | #include "rtl.h" | |
25 | #include "cp-tree.h" | |
26 | #include "flags.h" | |
27 | #include "output.h" | |
28 | ||
49c249e1 JM |
29 | #ifdef HAVE_STRING_H |
30 | #include <string.h> | |
31 | #endif | |
32 | ||
33 | static void add_friend PROTO((tree, tree)); | |
34 | static void add_friends PROTO((tree, tree, tree)); | |
35 | ||
bd6dd845 MS |
36 | /* Friend data structures: |
37 | ||
38 | Lists of friend functions come from TYPE_DECL nodes. Since all | |
39 | aggregate types are automatically typedef'd, these nodes are guaranteed | |
40 | to exist. | |
41 | ||
42 | The TREE_PURPOSE of a friend list is the name of the friend, | |
43 | and its TREE_VALUE is another list. | |
44 | ||
45 | For each element of that list, either the TREE_VALUE or the TREE_PURPOSE | |
46 | will be filled in, but not both. The TREE_VALUE of that list is an | |
47 | individual function which is a friend. The TREE_PURPOSE of that list | |
48 | indicates a type in which all functions by that name are friends. | |
49 | ||
50 | Lists of friend classes come from _TYPE nodes. Love that consistency | |
51 | thang. */ | |
52 | ||
53 | int | |
54 | is_friend (type, supplicant) | |
55 | tree type, supplicant; | |
56 | { | |
57 | int declp; | |
58 | register tree list; | |
59 | ||
60 | if (supplicant == NULL_TREE || type == NULL_TREE) | |
61 | return 0; | |
62 | ||
63 | declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd'); | |
64 | ||
65 | if (declp) | |
66 | /* It's a function decl. */ | |
67 | { | |
68 | tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); | |
69 | tree name = DECL_NAME (supplicant); | |
70 | tree ctype; | |
71 | ||
72 | if (DECL_FUNCTION_MEMBER_P (supplicant)) | |
73 | ctype = DECL_CLASS_CONTEXT (supplicant); | |
74 | else | |
75 | ctype = NULL_TREE; | |
76 | ||
77 | for (; list ; list = TREE_CHAIN (list)) | |
78 | { | |
79 | if (name == TREE_PURPOSE (list)) | |
80 | { | |
81 | tree friends = TREE_VALUE (list); | |
82 | for (; friends ; friends = TREE_CHAIN (friends)) | |
83 | { | |
84 | if (ctype == TREE_PURPOSE (friends)) | |
85 | return 1; | |
86 | if (comptypes (TREE_TYPE (supplicant), | |
87 | TREE_TYPE (TREE_VALUE (friends)), 1)) | |
88 | return 1; | |
89 | } | |
90 | break; | |
91 | } | |
92 | } | |
93 | } | |
94 | else | |
95 | /* It's a type. */ | |
96 | { | |
97 | if (type == supplicant) | |
98 | return 1; | |
99 | ||
100 | list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type))); | |
101 | for (; list ; list = TREE_CHAIN (list)) | |
102 | if (supplicant == TREE_VALUE (list)) | |
103 | return 1; | |
104 | } | |
105 | ||
106 | { | |
107 | tree context; | |
108 | ||
109 | if (! declp) | |
110 | { | |
111 | /* Are we a nested or local class? If so, we aren't friends | |
112 | with the CONTEXT. */ | |
113 | if (IS_AGGR_TYPE (supplicant)) | |
114 | context = NULL_TREE; | |
115 | else | |
116 | context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant)); | |
117 | } | |
118 | else if (DECL_FUNCTION_MEMBER_P (supplicant)) | |
119 | context = DECL_CLASS_CONTEXT (supplicant); | |
120 | else | |
121 | context = NULL_TREE; | |
122 | ||
123 | if (context) | |
124 | return is_friend (type, context); | |
125 | } | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
130 | /* Add a new friend to the friends of the aggregate type TYPE. | |
131 | DECL is the FUNCTION_DECL of the friend being added. */ | |
132 | ||
133 | static void | |
134 | add_friend (type, decl) | |
135 | tree type, decl; | |
136 | { | |
137 | tree typedecl = TYPE_MAIN_DECL (type); | |
138 | tree list = DECL_FRIENDLIST (typedecl); | |
139 | tree name = DECL_NAME (decl); | |
140 | ||
141 | while (list) | |
142 | { | |
143 | if (name == TREE_PURPOSE (list)) | |
144 | { | |
145 | tree friends = TREE_VALUE (list); | |
146 | for (; friends ; friends = TREE_CHAIN (friends)) | |
147 | { | |
148 | if (decl == TREE_VALUE (friends)) | |
149 | { | |
150 | cp_warning ("`%D' is already a friend of class `%T'", | |
151 | decl, type); | |
152 | cp_warning_at ("previous friend declaration of `%D'", | |
153 | TREE_VALUE (friends)); | |
154 | return; | |
155 | } | |
156 | } | |
157 | TREE_VALUE (list) = tree_cons (error_mark_node, decl, | |
158 | TREE_VALUE (list)); | |
159 | return; | |
160 | } | |
161 | list = TREE_CHAIN (list); | |
162 | } | |
163 | DECL_FRIENDLIST (typedecl) | |
164 | = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), | |
165 | DECL_FRIENDLIST (typedecl)); | |
166 | if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) | |
167 | { | |
168 | tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); | |
169 | TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; | |
170 | if (parmtypes && TREE_CHAIN (parmtypes)) | |
171 | { | |
172 | tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes)); | |
173 | if (TREE_CODE (parmtype) == REFERENCE_TYPE | |
174 | && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl)) | |
175 | TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; | |
176 | } | |
177 | } | |
178 | } | |
179 | ||
180 | /* Declare that every member function NAME in FRIEND_TYPE | |
181 | (which may be NULL_TREE) is a friend of type TYPE. */ | |
182 | ||
183 | static void | |
184 | add_friends (type, name, friend_type) | |
185 | tree type, name, friend_type; | |
186 | { | |
187 | tree typedecl = TYPE_MAIN_DECL (type); | |
188 | tree list = DECL_FRIENDLIST (typedecl); | |
189 | ||
190 | while (list) | |
191 | { | |
192 | if (name == TREE_PURPOSE (list)) | |
193 | { | |
194 | tree friends = TREE_VALUE (list); | |
195 | while (friends && TREE_PURPOSE (friends) != friend_type) | |
196 | friends = TREE_CHAIN (friends); | |
197 | if (friends) | |
a703fb38 KG |
198 | { |
199 | if (friend_type) | |
200 | warning ("method `%s::%s' is already a friend of class", | |
201 | TYPE_NAME_STRING (friend_type), | |
202 | IDENTIFIER_POINTER (name)); | |
203 | else | |
204 | warning ("function `%s' is already a friend of class `%s'", | |
205 | IDENTIFIER_POINTER (name), | |
206 | IDENTIFIER_POINTER (DECL_NAME (typedecl))); | |
207 | } | |
bd6dd845 MS |
208 | else |
209 | TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE, | |
210 | TREE_VALUE (list)); | |
211 | return; | |
212 | } | |
213 | list = TREE_CHAIN (list); | |
214 | } | |
beb53fb8 JM |
215 | DECL_FRIENDLIST (typedecl) |
216 | = tree_cons (name, | |
217 | build_tree_list (friend_type, NULL_TREE), | |
218 | DECL_FRIENDLIST (typedecl)); | |
bd6dd845 MS |
219 | if (! strncmp (IDENTIFIER_POINTER (name), |
220 | IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]), | |
221 | strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR])))) | |
222 | { | |
223 | TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; | |
224 | sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists"); | |
225 | } | |
226 | } | |
227 | ||
228 | /* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already | |
229 | been defined, we make all of its member functions friends of | |
230 | TYPE. If not, we make it a pending friend, which can later be added | |
231 | when its definition is seen. If a type is defined, then its TYPE_DECL's | |
232 | DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend | |
233 | classes that are not defined. If a type has not yet been defined, | |
234 | then the DECL_WAITING_FRIENDS contains a list of types | |
235 | waiting to make it their friend. Note that these two can both | |
236 | be in use at the same time! */ | |
237 | ||
238 | void | |
239 | make_friend_class (type, friend_type) | |
240 | tree type, friend_type; | |
241 | { | |
242 | tree classes; | |
243 | ||
244 | if (IS_SIGNATURE (type)) | |
245 | { | |
246 | error ("`friend' declaration in signature definition"); | |
247 | return; | |
248 | } | |
249 | if (IS_SIGNATURE (friend_type)) | |
250 | { | |
251 | error ("signature type `%s' declared `friend'", | |
252 | IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type))); | |
253 | return; | |
254 | } | |
255 | if (type == friend_type) | |
256 | { | |
257 | pedwarn ("class `%s' is implicitly friends with itself", | |
258 | TYPE_NAME_STRING (type)); | |
259 | return; | |
260 | } | |
261 | ||
262 | GNU_xref_hier (TYPE_NAME_STRING (type), | |
263 | TYPE_NAME_STRING (friend_type), 0, 0, 1); | |
264 | ||
265 | classes = CLASSTYPE_FRIEND_CLASSES (type); | |
266 | while (classes && TREE_VALUE (classes) != friend_type) | |
267 | classes = TREE_CHAIN (classes); | |
268 | if (classes) | |
269 | warning ("class `%s' is already friends with class `%s'", | |
270 | TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type)); | |
271 | else | |
272 | { | |
273 | CLASSTYPE_FRIEND_CLASSES (type) | |
274 | = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); | |
275 | } | |
276 | } | |
277 | ||
278 | /* Main friend processor. This is large, and for modularity purposes, | |
279 | has been removed from grokdeclarator. It returns `void_type_node' | |
280 | to indicate that something happened, though a FIELD_DECL is | |
281 | not returned. | |
282 | ||
283 | CTYPE is the class this friend belongs to. | |
284 | ||
285 | DECLARATOR is the name of the friend. | |
286 | ||
287 | DECL is the FUNCTION_DECL that the friend is. | |
288 | ||
289 | In case we are parsing a friend which is part of an inline | |
290 | definition, we will need to store PARM_DECL chain that comes | |
291 | with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL. | |
292 | ||
293 | FLAGS is just used for `grokclassfn'. | |
294 | ||
295 | QUALS say what special qualifies should apply to the object | |
296 | pointed to by `this'. */ | |
297 | ||
298 | tree | |
299 | do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) | |
300 | tree ctype, declarator, decl, parmdecls; | |
301 | enum overload_flags flags; | |
302 | tree quals; | |
303 | int funcdef_flag; | |
304 | { | |
305 | /* Every decl that gets here is a friend of something. */ | |
306 | DECL_FRIEND_P (decl) = 1; | |
307 | ||
308 | if (ctype) | |
309 | { | |
310 | tree cname = TYPE_NAME (ctype); | |
311 | if (TREE_CODE (cname) == TYPE_DECL) | |
312 | cname = DECL_NAME (cname); | |
313 | ||
314 | /* A method friend. */ | |
315 | if (TREE_CODE (decl) == FUNCTION_DECL) | |
316 | { | |
317 | if (flags == NO_SPECIAL && ctype && declarator == cname) | |
318 | DECL_CONSTRUCTOR_P (decl) = 1; | |
319 | ||
320 | /* This will set up DECL_ARGUMENTS for us. */ | |
321 | grokclassfn (ctype, cname, decl, flags, quals); | |
322 | if (TYPE_SIZE (ctype) != 0) | |
323 | decl = check_classfn (ctype, decl); | |
324 | ||
325 | if (TREE_TYPE (decl) != error_mark_node) | |
326 | { | |
327 | if (TYPE_SIZE (ctype)) | |
328 | add_friend (current_class_type, decl); | |
329 | else | |
330 | { | |
331 | cp_error ("member `%D' declared as friend before type `%T' defined", | |
332 | decl, ctype); | |
333 | } | |
334 | } | |
335 | } | |
336 | else | |
337 | { | |
338 | /* Possibly a bunch of method friends. */ | |
339 | ||
340 | /* Get the class they belong to. */ | |
341 | tree ctype = IDENTIFIER_TYPE_VALUE (cname); | |
342 | tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0); | |
343 | ||
344 | if (fields) | |
345 | add_friends (current_class_type, declarator, ctype); | |
346 | else | |
347 | error ("method `%s' is not a member of class `%s'", | |
348 | IDENTIFIER_POINTER (declarator), | |
349 | IDENTIFIER_POINTER (cname)); | |
350 | decl = void_type_node; | |
351 | } | |
352 | } | |
353 | else if (TREE_CODE (decl) == FUNCTION_DECL | |
354 | && ((IDENTIFIER_LENGTH (declarator) == 4 | |
355 | && IDENTIFIER_POINTER (declarator)[0] == 'm' | |
356 | && ! strcmp (IDENTIFIER_POINTER (declarator), "main")) | |
357 | || (IDENTIFIER_LENGTH (declarator) > 10 | |
358 | && IDENTIFIER_POINTER (declarator)[0] == '_' | |
359 | && IDENTIFIER_POINTER (declarator)[1] == '_' | |
360 | && strncmp (IDENTIFIER_POINTER (declarator)+2, | |
361 | "builtin_", 8) == 0))) | |
362 | { | |
363 | /* raw "main", and builtin functions never gets overloaded, | |
364 | but they can become friends. */ | |
365 | add_friend (current_class_type, decl); | |
366 | DECL_FRIEND_P (decl) = 1; | |
367 | decl = void_type_node; | |
368 | } | |
369 | /* A global friend. | |
370 | @@ or possibly a friend from a base class ?!? */ | |
371 | else if (TREE_CODE (decl) == FUNCTION_DECL) | |
372 | { | |
373 | /* Friends must all go through the overload machinery, | |
374 | even though they may not technically be overloaded. | |
375 | ||
376 | Note that because classes all wind up being top-level | |
377 | in their scope, their friend wind up in top-level scope as well. */ | |
378 | DECL_ASSEMBLER_NAME (decl) | |
379 | = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)), | |
380 | TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); | |
381 | DECL_ARGUMENTS (decl) = parmdecls; | |
382 | if (funcdef_flag) | |
383 | DECL_CLASS_CONTEXT (decl) = current_class_type; | |
384 | ||
386b8a85 | 385 | if (! DECL_USE_TEMPLATE (decl)) |
37130ac3 JM |
386 | { |
387 | /* We can call pushdecl here, because the TREE_CHAIN of this | |
388 | FUNCTION_DECL is not needed for other purposes. Don't do this | |
389 | for a template instantiation. */ | |
390 | decl = pushdecl (decl); | |
391 | ||
392 | if (! funcdef_flag && ! flag_guiding_decls | |
393 | && current_template_parms && uses_template_parms (decl)) | |
394 | { | |
395 | static int explained; | |
396 | cp_warning ("friend declaration `%#D'", decl); | |
397 | warning (" will not be treated as a template instantiation"); | |
398 | if (! explained) | |
399 | { | |
400 | warning (" unless you compile with -fguiding-decls"); | |
401 | warning (" or add <> after the function name"); | |
402 | explained = 1; | |
403 | } | |
404 | } | |
405 | } | |
bd6dd845 MS |
406 | |
407 | make_decl_rtl (decl, NULL_PTR, 1); | |
408 | add_friend (current_class_type, decl); | |
409 | ||
410 | DECL_FRIEND_P (decl) = 1; | |
411 | } | |
412 | else | |
413 | { | |
414 | /* @@ Should be able to ingest later definitions of this function | |
415 | before use. */ | |
416 | tree decl = lookup_name_nonclass (declarator); | |
417 | if (decl == NULL_TREE) | |
418 | { | |
419 | warning ("implicitly declaring `%s' as struct", | |
420 | IDENTIFIER_POINTER (declarator)); | |
421 | decl = xref_tag (record_type_node, declarator, NULL_TREE, 1); | |
422 | decl = TYPE_MAIN_DECL (decl); | |
423 | } | |
424 | ||
425 | /* Allow abbreviated declarations of overloaded functions, | |
426 | but not if those functions are really class names. */ | |
427 | if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl))) | |
428 | { | |
429 | warning ("`friend %s' archaic, use `friend class %s' instead", | |
430 | IDENTIFIER_POINTER (declarator), | |
431 | IDENTIFIER_POINTER (declarator)); | |
432 | decl = TREE_TYPE (TREE_PURPOSE (decl)); | |
433 | } | |
434 | ||
435 | if (TREE_CODE (decl) == TREE_LIST) | |
436 | add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE); | |
437 | else | |
438 | make_friend_class (current_class_type, TREE_TYPE (decl)); | |
439 | decl = void_type_node; | |
440 | } | |
441 | return decl; | |
442 | } |