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