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