]>
Commit | Line | Data |
---|---|---|
2bbd3819 RS |
1 | /* Generate information regarding function declarations and definitions based |
2 | on information stored in GCC's tree structure. This code implements the | |
872d115f | 3 | -aux-info option. |
517cbe13 | 4 | Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998, |
5baeaac0 | 5 | 1999, 2000, 2003, 2004 Free Software Foundation, Inc. |
3826a3da | 6 | Contributed by Ron Guilmette (rfg@segfault.us.com). |
2bbd3819 | 7 | |
1322177d | 8 | This file is part of GCC. |
2bbd3819 | 9 | |
1322177d LB |
10 | GCC is free software; you can redistribute it and/or modify it under |
11 | the terms of the GNU General Public License as published by the Free | |
12 | Software Foundation; either version 2, or (at your option) any later | |
13 | version. | |
2bbd3819 | 14 | |
1322177d LB |
15 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
16 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 | for more details. | |
2bbd3819 RS |
19 | |
20 | You should have received a copy of the GNU General Public License | |
1322177d LB |
21 | along with GCC; see the file COPYING. If not, write to the Free |
22 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
23 | 02111-1307, USA. */ | |
2bbd3819 | 24 | |
2bbd3819 | 25 | #include "config.h" |
670ee920 | 26 | #include "system.h" |
4977bab6 ZW |
27 | #include "coretypes.h" |
28 | #include "tm.h" | |
2bbd3819 RS |
29 | #include "flags.h" |
30 | #include "tree.h" | |
31 | #include "c-tree.h" | |
5f1989e6 | 32 | #include "toplev.h" |
2bbd3819 | 33 | |
2bbd3819 RS |
34 | enum formals_style_enum { |
35 | ansi, | |
36 | k_and_r_names, | |
37 | k_and_r_decls | |
38 | }; | |
39 | typedef enum formals_style_enum formals_style; | |
40 | ||
41 | ||
dff01034 | 42 | static const char *data_type; |
2bbd3819 | 43 | |
35b1a6fa AJ |
44 | static char *affix_data_type (const char *) ATTRIBUTE_MALLOC; |
45 | static const char *gen_formal_list_for_type (tree, formals_style); | |
46 | static int deserves_ellipsis (tree); | |
47 | static const char *gen_formal_list_for_func_def (tree, formals_style); | |
48 | static const char *gen_type (const char *, tree, formals_style); | |
49 | static const char *gen_decl (tree, int, formals_style); | |
2bbd3819 | 50 | \f |
2bbd3819 RS |
51 | /* Given a string representing an entire type or an entire declaration |
52 | which only lacks the actual "data-type" specifier (at its left end), | |
53 | affix the data-type specifier to the left end of the given type | |
54 | specification or object declaration. | |
55 | ||
56 | Because of C language weirdness, the data-type specifier (which normally | |
57 | goes in at the very left end) may have to be slipped in just to the | |
58 | right of any leading "const" or "volatile" qualifiers (there may be more | |
59 | than one). Actually this may not be strictly necessary because it seems | |
60 | that GCC (at least) accepts `<data-type> const foo;' and treats it the | |
61 | same as `const <data-type> foo;' but people are accustomed to seeing | |
62 | `const char *foo;' and *not* `char const *foo;' so we try to create types | |
63 | that look as expected. */ | |
64 | ||
0f41302f | 65 | static char * |
35b1a6fa | 66 | affix_data_type (const char *param) |
2bbd3819 | 67 | { |
c1d49704 | 68 | char *const type_or_decl = ASTRDUP (param); |
2bbd3819 RS |
69 | char *p = type_or_decl; |
70 | char *qualifiers_then_data_type; | |
71 | char saved; | |
72 | ||
73 | /* Skip as many leading const's or volatile's as there are. */ | |
74 | ||
75 | for (;;) | |
76 | { | |
1394aabd | 77 | if (!strncmp (p, "volatile ", 9)) |
2bbd3819 RS |
78 | { |
79 | p += 9; | |
80 | continue; | |
81 | } | |
1394aabd | 82 | if (!strncmp (p, "const ", 6)) |
2bbd3819 RS |
83 | { |
84 | p += 6; | |
85 | continue; | |
86 | } | |
87 | break; | |
88 | } | |
89 | ||
90 | /* p now points to the place where we can insert the data type. We have to | |
91 | add a blank after the data-type of course. */ | |
92 | ||
93 | if (p == type_or_decl) | |
d4f2852f | 94 | return concat (data_type, " ", type_or_decl, NULL); |
2bbd3819 RS |
95 | |
96 | saved = *p; | |
97 | *p = '\0'; | |
d4f2852f | 98 | qualifiers_then_data_type = concat (type_or_decl, data_type, NULL); |
2bbd3819 | 99 | *p = saved; |
ad43d46f KG |
100 | return reconcat (qualifiers_then_data_type, |
101 | qualifiers_then_data_type, " ", p, NULL); | |
2bbd3819 RS |
102 | } |
103 | ||
104 | /* Given a tree node which represents some "function type", generate the | |
105 | source code version of a formal parameter list (of some given style) for | |
106 | this function type. Return the whole formal parameter list (including | |
107 | a pair of surrounding parens) as a string. Note that if the style | |
108 | we are currently aiming for is non-ansi, then we just return a pair | |
0f41302f | 109 | of empty parens here. */ |
2bbd3819 | 110 | |
dff01034 | 111 | static const char * |
35b1a6fa | 112 | gen_formal_list_for_type (tree fntype, formals_style style) |
2bbd3819 | 113 | { |
dff01034 | 114 | const char *formal_list = ""; |
2bbd3819 RS |
115 | tree formal_type; |
116 | ||
117 | if (style != ansi) | |
118 | return "()"; | |
119 | ||
120 | formal_type = TYPE_ARG_TYPES (fntype); | |
121 | while (formal_type && TREE_VALUE (formal_type) != void_type_node) | |
122 | { | |
dff01034 | 123 | const char *this_type; |
2bbd3819 RS |
124 | |
125 | if (*formal_list) | |
d4f2852f | 126 | formal_list = concat (formal_list, ", ", NULL); |
2bbd3819 RS |
127 | |
128 | this_type = gen_type ("", TREE_VALUE (formal_type), ansi); | |
e3da301d MS |
129 | formal_list |
130 | = ((strlen (this_type)) | |
d4f2852f KG |
131 | ? concat (formal_list, affix_data_type (this_type), NULL) |
132 | : concat (formal_list, data_type, NULL)); | |
2bbd3819 RS |
133 | |
134 | formal_type = TREE_CHAIN (formal_type); | |
135 | } | |
136 | ||
137 | /* If we got to here, then we are trying to generate an ANSI style formal | |
138 | parameters list. | |
139 | ||
140 | New style prototyped ANSI formal parameter lists should in theory always | |
141 | contain some stuff between the opening and closing parens, even if it is | |
142 | only "void". | |
143 | ||
144 | The brutal truth though is that there is lots of old K&R code out there | |
145 | which contains declarations of "pointer-to-function" parameters and | |
146 | these almost never have fully specified formal parameter lists associated | |
147 | with them. That is, the pointer-to-function parameters are declared | |
148 | with just empty parameter lists. | |
149 | ||
150 | In cases such as these, protoize should really insert *something* into | |
151 | the vacant parameter lists, but what? It has no basis on which to insert | |
152 | anything in particular. | |
153 | ||
154 | Here, we make life easy for protoize by trying to distinguish between | |
155 | K&R empty parameter lists and new-style prototyped parameter lists | |
156 | that actually contain "void". In the latter case we (obviously) want | |
157 | to output the "void" verbatim, and that what we do. In the former case, | |
158 | we do our best to give protoize something nice to insert. | |
159 | ||
3826a3da | 160 | This "something nice" should be something that is still valid (when |
2bbd3819 RS |
161 | re-compiled) but something that can clearly indicate to the user that |
162 | more typing information (for the parameter list) should be added (by | |
163 | hand) at some convenient moment. | |
164 | ||
d45cf215 | 165 | The string chosen here is a comment with question marks in it. */ |
2bbd3819 RS |
166 | |
167 | if (!*formal_list) | |
168 | { | |
169 | if (TYPE_ARG_TYPES (fntype)) | |
170 | /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */ | |
171 | formal_list = "void"; | |
172 | else | |
173 | formal_list = "/* ??? */"; | |
174 | } | |
175 | else | |
176 | { | |
177 | /* If there were at least some parameters, and if the formals-types-list | |
178 | petered out to a NULL (i.e. without being terminated by a | |
179 | void_type_node) then we need to tack on an ellipsis. */ | |
180 | if (!formal_type) | |
d4f2852f | 181 | formal_list = concat (formal_list, ", ...", NULL); |
2bbd3819 RS |
182 | } |
183 | ||
d4f2852f | 184 | return concat (" (", formal_list, ")", NULL); |
2bbd3819 RS |
185 | } |
186 | ||
187 | /* For the generation of an ANSI prototype for a function definition, we have | |
188 | to look at the formal parameter list of the function's own "type" to | |
189 | determine if the function's formal parameter list should end with an | |
da7d8304 | 190 | ellipsis. Given a tree node, the following function will return nonzero |
2bbd3819 RS |
191 | if the "function type" parameter list should end with an ellipsis. */ |
192 | ||
193 | static int | |
35b1a6fa | 194 | deserves_ellipsis (tree fntype) |
2bbd3819 RS |
195 | { |
196 | tree formal_type; | |
197 | ||
198 | formal_type = TYPE_ARG_TYPES (fntype); | |
199 | while (formal_type && TREE_VALUE (formal_type) != void_type_node) | |
200 | formal_type = TREE_CHAIN (formal_type); | |
201 | ||
202 | /* If there were at least some parameters, and if the formals-types-list | |
203 | petered out to a NULL (i.e. without being terminated by a void_type_node) | |
204 | then we need to tack on an ellipsis. */ | |
205 | ||
206 | return (!formal_type && TYPE_ARG_TYPES (fntype)); | |
207 | } | |
208 | ||
209 | /* Generate a parameter list for a function definition (in some given style). | |
210 | ||
211 | Note that this routine has to be separate (and different) from the code that | |
212 | generates the prototype parameter lists for function declarations, because | |
213 | in the case of a function declaration, all we have to go on is a tree node | |
214 | representing the function's own "function type". This can tell us the types | |
215 | of all of the formal parameters for the function, but it cannot tell us the | |
216 | actual *names* of each of the formal parameters. We need to output those | |
217 | parameter names for each function definition. | |
218 | ||
219 | This routine gets a pointer to a tree node which represents the actual | |
220 | declaration of the given function, and this DECL node has a list of formal | |
221 | parameter (variable) declarations attached to it. These formal parameter | |
222 | (variable) declaration nodes give us the actual names of the formal | |
223 | parameters for the given function definition. | |
224 | ||
225 | This routine returns a string which is the source form for the entire | |
226 | function formal parameter list. */ | |
227 | ||
dff01034 | 228 | static const char * |
35b1a6fa | 229 | gen_formal_list_for_func_def (tree fndecl, formals_style style) |
2bbd3819 | 230 | { |
dff01034 | 231 | const char *formal_list = ""; |
2bbd3819 RS |
232 | tree formal_decl; |
233 | ||
234 | formal_decl = DECL_ARGUMENTS (fndecl); | |
235 | while (formal_decl) | |
236 | { | |
dff01034 | 237 | const char *this_formal; |
2bbd3819 RS |
238 | |
239 | if (*formal_list && ((style == ansi) || (style == k_and_r_names))) | |
d4f2852f | 240 | formal_list = concat (formal_list, ", ", NULL); |
2bbd3819 RS |
241 | this_formal = gen_decl (formal_decl, 0, style); |
242 | if (style == k_and_r_decls) | |
d4f2852f | 243 | formal_list = concat (formal_list, this_formal, "; ", NULL); |
2bbd3819 | 244 | else |
d4f2852f | 245 | formal_list = concat (formal_list, this_formal, NULL); |
2bbd3819 RS |
246 | formal_decl = TREE_CHAIN (formal_decl); |
247 | } | |
248 | if (style == ansi) | |
249 | { | |
250 | if (!DECL_ARGUMENTS (fndecl)) | |
d4f2852f | 251 | formal_list = concat (formal_list, "void", NULL); |
2bbd3819 | 252 | if (deserves_ellipsis (TREE_TYPE (fndecl))) |
d4f2852f | 253 | formal_list = concat (formal_list, ", ...", NULL); |
2bbd3819 RS |
254 | } |
255 | if ((style == ansi) || (style == k_and_r_names)) | |
d4f2852f | 256 | formal_list = concat (" (", formal_list, ")", NULL); |
2bbd3819 RS |
257 | return formal_list; |
258 | } | |
259 | ||
260 | /* Generate a string which is the source code form for a given type (t). This | |
261 | routine is ugly and complex because the C syntax for declarations is ugly | |
262 | and complex. This routine is straightforward so long as *no* pointer types, | |
263 | array types, or function types are involved. | |
264 | ||
265 | In the simple cases, this routine will return the (string) value which was | |
266 | passed in as the "ret_val" argument. Usually, this starts out either as an | |
267 | empty string, or as the name of the declared item (i.e. the formal function | |
268 | parameter variable). | |
269 | ||
270 | This routine will also return with the global variable "data_type" set to | |
271 | some string value which is the "basic" data-type of the given complete type. | |
272 | This "data_type" string can be concatenated onto the front of the returned | |
273 | string after this routine returns to its caller. | |
274 | ||
275 | In complicated cases involving pointer types, array types, or function | |
276 | types, the C declaration syntax requires an "inside out" approach, i.e. if | |
277 | you have a type which is a "pointer-to-function" type, you need to handle | |
278 | the "pointer" part first, but it also has to be "innermost" (relative to | |
279 | the declaration stuff for the "function" type). Thus, is this case, you | |
280 | must prepend a "(*" and append a ")" to the name of the item (i.e. formal | |
281 | variable). Then you must append and prepend the other info for the | |
282 | "function type" part of the overall type. | |
283 | ||
284 | To handle the "innermost precedence" rules of complicated C declarators, we | |
285 | do the following (in this routine). The input parameter called "ret_val" | |
286 | is treated as a "seed". Each time gen_type is called (perhaps recursively) | |
287 | some additional strings may be appended or prepended (or both) to the "seed" | |
288 | string. If yet another (lower) level of the GCC tree exists for the given | |
289 | type (as in the case of a pointer type, an array type, or a function type) | |
290 | then the (wrapped) seed is passed to a (recursive) invocation of gen_type() | |
291 | this recursive invocation may again "wrap" the (new) seed with yet more | |
292 | declarator stuff, by appending, prepending (or both). By the time the | |
293 | recursion bottoms out, the "seed value" at that point will have a value | |
294 | which is (almost) the complete source version of the declarator (except | |
295 | for the data_type info). Thus, this deepest "seed" value is simply passed | |
296 | back up through all of the recursive calls until it is given (as the return | |
297 | value) to the initial caller of the gen_type() routine. All that remains | |
298 | to do at this point is for the initial caller to prepend the "data_type" | |
299 | string onto the returned "seed". */ | |
300 | ||
dff01034 | 301 | static const char * |
35b1a6fa | 302 | gen_type (const char *ret_val, tree t, formals_style style) |
2bbd3819 RS |
303 | { |
304 | tree chain_p; | |
305 | ||
f5880dbe JW |
306 | /* If there is a typedef name for this type, use it. */ |
307 | if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL) | |
2bbd3819 RS |
308 | data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); |
309 | else | |
310 | { | |
311 | switch (TREE_CODE (t)) | |
312 | { | |
313 | case POINTER_TYPE: | |
314 | if (TYPE_READONLY (t)) | |
d4f2852f | 315 | ret_val = concat ("const ", ret_val, NULL); |
2bbd3819 | 316 | if (TYPE_VOLATILE (t)) |
d4f2852f | 317 | ret_val = concat ("volatile ", ret_val, NULL); |
2bbd3819 | 318 | |
d4f2852f | 319 | ret_val = concat ("*", ret_val, NULL); |
2bbd3819 RS |
320 | |
321 | if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) | |
d4f2852f | 322 | ret_val = concat ("(", ret_val, ")", NULL); |
2bbd3819 RS |
323 | |
324 | ret_val = gen_type (ret_val, TREE_TYPE (t), style); | |
325 | ||
326 | return ret_val; | |
327 | ||
328 | case ARRAY_TYPE: | |
d0f062fb | 329 | if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) |
d4f2852f | 330 | ret_val = gen_type (concat (ret_val, "[]", NULL), |
2778b98d | 331 | TREE_TYPE (t), style); |
7e53036d | 332 | else if (int_size_in_bytes (t) == 0) |
d4f2852f | 333 | ret_val = gen_type (concat (ret_val, "[0]", NULL), |
2778b98d | 334 | TREE_TYPE (t), style); |
7e53036d RS |
335 | else |
336 | { | |
337 | int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); | |
338 | char buff[10]; | |
339 | sprintf (buff, "[%d]", size); | |
d4f2852f | 340 | ret_val = gen_type (concat (ret_val, buff, NULL), |
7e53036d RS |
341 | TREE_TYPE (t), style); |
342 | } | |
2bbd3819 RS |
343 | break; |
344 | ||
345 | case FUNCTION_TYPE: | |
2778b98d KG |
346 | ret_val = gen_type (concat (ret_val, |
347 | gen_formal_list_for_type (t, style), | |
d4f2852f | 348 | NULL), |
2778b98d | 349 | TREE_TYPE (t), style); |
2bbd3819 RS |
350 | break; |
351 | ||
352 | case IDENTIFIER_NODE: | |
353 | data_type = IDENTIFIER_POINTER (t); | |
354 | break; | |
355 | ||
356 | /* The following three cases are complicated by the fact that a | |
357 | user may do something really stupid, like creating a brand new | |
358 | "anonymous" type specification in a formal argument list (or as | |
359 | part of a function return type specification). For example: | |
360 | ||
361 | int f (enum { red, green, blue } color); | |
362 | ||
363 | In such cases, we have no name that we can put into the prototype | |
364 | to represent the (anonymous) type. Thus, we have to generate the | |
365 | whole darn type specification. Yuck! */ | |
366 | ||
367 | case RECORD_TYPE: | |
368 | if (TYPE_NAME (t)) | |
369 | data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); | |
370 | else | |
371 | { | |
372 | data_type = ""; | |
373 | chain_p = TYPE_FIELDS (t); | |
374 | while (chain_p) | |
375 | { | |
2778b98d | 376 | data_type = concat (data_type, gen_decl (chain_p, 0, ansi), |
d4f2852f | 377 | NULL); |
2bbd3819 | 378 | chain_p = TREE_CHAIN (chain_p); |
d4f2852f | 379 | data_type = concat (data_type, "; ", NULL); |
2bbd3819 | 380 | } |
d4f2852f | 381 | data_type = concat ("{ ", data_type, "}", NULL); |
2bbd3819 | 382 | } |
d4f2852f | 383 | data_type = concat ("struct ", data_type, NULL); |
2bbd3819 RS |
384 | break; |
385 | ||
386 | case UNION_TYPE: | |
387 | if (TYPE_NAME (t)) | |
388 | data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); | |
389 | else | |
390 | { | |
391 | data_type = ""; | |
392 | chain_p = TYPE_FIELDS (t); | |
393 | while (chain_p) | |
394 | { | |
2778b98d | 395 | data_type = concat (data_type, gen_decl (chain_p, 0, ansi), |
d4f2852f | 396 | NULL); |
2bbd3819 | 397 | chain_p = TREE_CHAIN (chain_p); |
d4f2852f | 398 | data_type = concat (data_type, "; ", NULL); |
2bbd3819 | 399 | } |
d4f2852f | 400 | data_type = concat ("{ ", data_type, "}", NULL); |
2bbd3819 | 401 | } |
d4f2852f | 402 | data_type = concat ("union ", data_type, NULL); |
2bbd3819 RS |
403 | break; |
404 | ||
405 | case ENUMERAL_TYPE: | |
406 | if (TYPE_NAME (t)) | |
407 | data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); | |
408 | else | |
409 | { | |
410 | data_type = ""; | |
411 | chain_p = TYPE_VALUES (t); | |
412 | while (chain_p) | |
413 | { | |
414 | data_type = concat (data_type, | |
d4f2852f | 415 | IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL); |
2bbd3819 RS |
416 | chain_p = TREE_CHAIN (chain_p); |
417 | if (chain_p) | |
d4f2852f | 418 | data_type = concat (data_type, ", ", NULL); |
2bbd3819 | 419 | } |
d4f2852f | 420 | data_type = concat ("{ ", data_type, " }", NULL); |
2bbd3819 | 421 | } |
d4f2852f | 422 | data_type = concat ("enum ", data_type, NULL); |
2bbd3819 RS |
423 | break; |
424 | ||
425 | case TYPE_DECL: | |
426 | data_type = IDENTIFIER_POINTER (DECL_NAME (t)); | |
427 | break; | |
35b1a6fa | 428 | |
2bbd3819 RS |
429 | case INTEGER_TYPE: |
430 | data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); | |
431 | /* Normally, `unsigned' is part of the deal. Not so if it comes | |
35b1a6fa | 432 | with a type qualifier. */ |
8df83eae | 433 | if (TYPE_UNSIGNED (t) && TYPE_QUALS (t)) |
35b1a6fa | 434 | data_type = concat ("unsigned ", data_type, NULL); |
2bbd3819 RS |
435 | break; |
436 | ||
437 | case REAL_TYPE: | |
438 | data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); | |
439 | break; | |
440 | ||
441 | case VOID_TYPE: | |
442 | data_type = "void"; | |
443 | break; | |
444 | ||
61d2941a RK |
445 | case ERROR_MARK: |
446 | data_type = "[ERROR]"; | |
447 | break; | |
448 | ||
2bbd3819 | 449 | default: |
366de0ce | 450 | gcc_unreachable (); |
2bbd3819 RS |
451 | } |
452 | } | |
453 | if (TYPE_READONLY (t)) | |
d4f2852f | 454 | ret_val = concat ("const ", ret_val, NULL); |
2bbd3819 | 455 | if (TYPE_VOLATILE (t)) |
d4f2852f | 456 | ret_val = concat ("volatile ", ret_val, NULL); |
3932261a | 457 | if (TYPE_RESTRICT (t)) |
d4f2852f | 458 | ret_val = concat ("restrict ", ret_val, NULL); |
2bbd3819 RS |
459 | return ret_val; |
460 | } | |
461 | ||
462 | /* Generate a string (source) representation of an entire entity declaration | |
463 | (using some particular style for function types). | |
464 | ||
465 | The given entity may be either a variable or a function. | |
466 | ||
da7d8304 | 467 | If the "is_func_definition" parameter is nonzero, assume that the thing |
2bbd3819 RS |
468 | we are generating a declaration for is a FUNCTION_DECL node which is |
469 | associated with a function definition. In this case, we can assume that | |
470 | an attached list of DECL nodes for function formal arguments is present. */ | |
471 | ||
dff01034 | 472 | static const char * |
35b1a6fa | 473 | gen_decl (tree decl, int is_func_definition, formals_style style) |
2bbd3819 | 474 | { |
dff01034 | 475 | const char *ret_val; |
2bbd3819 RS |
476 | |
477 | if (DECL_NAME (decl)) | |
478 | ret_val = IDENTIFIER_POINTER (DECL_NAME (decl)); | |
479 | else | |
480 | ret_val = ""; | |
481 | ||
482 | /* If we are just generating a list of names of formal parameters, we can | |
483 | simply return the formal parameter name (with no typing information | |
484 | attached to it) now. */ | |
485 | ||
486 | if (style == k_and_r_names) | |
487 | return ret_val; | |
488 | ||
489 | /* Note that for the declaration of some entity (either a function or a | |
490 | data object, like for instance a parameter) if the entity itself was | |
491 | declared as either const or volatile, then const and volatile properties | |
492 | are associated with just the declaration of the entity, and *not* with | |
493 | the `type' of the entity. Thus, for such declared entities, we have to | |
494 | generate the qualifiers here. */ | |
495 | ||
496 | if (TREE_THIS_VOLATILE (decl)) | |
d4f2852f | 497 | ret_val = concat ("volatile ", ret_val, NULL); |
2bbd3819 | 498 | if (TREE_READONLY (decl)) |
d4f2852f | 499 | ret_val = concat ("const ", ret_val, NULL); |
2bbd3819 RS |
500 | |
501 | data_type = ""; | |
502 | ||
503 | /* For FUNCTION_DECL nodes, there are two possible cases here. First, if | |
504 | this FUNCTION_DECL node was generated from a function "definition", then | |
505 | we will have a list of DECL_NODE's, one for each of the function's formal | |
506 | parameters. In this case, we can print out not only the types of each | |
507 | formal, but also each formal's name. In the second case, this | |
508 | FUNCTION_DECL node came from an actual function declaration (and *not* | |
509 | a definition). In this case, we do nothing here because the formal | |
510 | argument type-list will be output later, when the "type" of the function | |
511 | is added to the string we are building. Note that the ANSI-style formal | |
512 | parameter list is considered to be a (suffix) part of the "type" of the | |
513 | function. */ | |
514 | ||
515 | if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition) | |
516 | { | |
2778b98d | 517 | ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi), |
d4f2852f | 518 | NULL); |
2bbd3819 RS |
519 | |
520 | /* Since we have already added in the formals list stuff, here we don't | |
521 | add the whole "type" of the function we are considering (which | |
522 | would include its parameter-list info), rather, we only add in | |
523 | the "type" of the "type" of the function, which is really just | |
524 | the return-type of the function (and does not include the parameter | |
525 | list info). */ | |
526 | ||
527 | ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style); | |
528 | } | |
529 | else | |
530 | ret_val = gen_type (ret_val, TREE_TYPE (decl), style); | |
531 | ||
532 | ret_val = affix_data_type (ret_val); | |
533 | ||
5baeaac0 | 534 | if (TREE_CODE (decl) != FUNCTION_DECL && C_DECL_REGISTER (decl)) |
d4f2852f | 535 | ret_val = concat ("register ", ret_val, NULL); |
2bbd3819 | 536 | if (TREE_PUBLIC (decl)) |
d4f2852f | 537 | ret_val = concat ("extern ", ret_val, NULL); |
2bbd3819 | 538 | if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) |
d4f2852f | 539 | ret_val = concat ("static ", ret_val, NULL); |
2bbd3819 RS |
540 | |
541 | return ret_val; | |
542 | } | |
543 | ||
0f41302f | 544 | extern FILE *aux_info_file; |
2bbd3819 RS |
545 | |
546 | /* Generate and write a new line of info to the aux-info (.X) file. This | |
547 | routine is called once for each function declaration, and once for each | |
548 | function definition (even the implicit ones). */ | |
549 | ||
550 | void | |
35b1a6fa AJ |
551 | gen_aux_info_record (tree fndecl, int is_definition, int is_implicit, |
552 | int is_prototyped) | |
2bbd3819 RS |
553 | { |
554 | if (flag_gen_aux_info) | |
555 | { | |
556 | static int compiled_from_record = 0; | |
a281759f | 557 | expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (fndecl)); |
2bbd3819 RS |
558 | |
559 | /* Each output .X file must have a header line. Write one now if we | |
560 | have not yet done so. */ | |
561 | ||
3f75a254 | 562 | if (!compiled_from_record++) |
2bbd3819 | 563 | { |
7d57b4ca | 564 | /* The first line tells which directory file names are relative to. |
872d115f | 565 | Currently, -aux-info works only for files in the working |
7d57b4ca RS |
566 | directory, so just use a `.' as a placeholder for now. */ |
567 | fprintf (aux_info_file, "/* compiled from: . */\n"); | |
2bbd3819 RS |
568 | } |
569 | ||
d45cf215 | 570 | /* Write the actual line of auxiliary info. */ |
2bbd3819 RS |
571 | |
572 | fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;", | |
a281759f | 573 | xloc.file, xloc.line, |
2bbd3819 RS |
574 | (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O', |
575 | (is_definition) ? 'F' : 'C', | |
576 | gen_decl (fndecl, is_definition, ansi)); | |
577 | ||
578 | /* If this is an explicit function declaration, we need to also write | |
579 | out an old-style (i.e. K&R) function header, just in case the user | |
580 | wants to run unprotoize. */ | |
581 | ||
582 | if (is_definition) | |
583 | { | |
584 | fprintf (aux_info_file, " /*%s %s*/", | |
585 | gen_formal_list_for_func_def (fndecl, k_and_r_names), | |
586 | gen_formal_list_for_func_def (fndecl, k_and_r_decls)); | |
587 | } | |
588 | ||
589 | fprintf (aux_info_file, "\n"); | |
590 | } | |
591 | } |