]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c-aux-info.c
c-aux-info.c, [...]: Follow code formatting conventions.
[thirdparty/gcc.git] / gcc / c-aux-info.c
CommitLineData
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 8This file is part of GCC.
2bbd3819 9
1322177d
LB
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
12Software Foundation; either version 2, or (at your option) any later
13version.
2bbd3819 14
1322177d
LB
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
2bbd3819
RS
19
20You should have received a copy of the GNU General Public License
1322177d
LB
21along with GCC; see the file COPYING. If not, write to the Free
22Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2302111-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
34enum formals_style_enum {
35 ansi,
36 k_and_r_names,
37 k_and_r_decls
38};
39typedef enum formals_style_enum formals_style;
40
41
dff01034 42static const char *data_type;
2bbd3819 43
35b1a6fa
AJ
44static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
45static const char *gen_formal_list_for_type (tree, formals_style);
46static int deserves_ellipsis (tree);
47static const char *gen_formal_list_for_func_def (tree, formals_style);
48static const char *gen_type (const char *, tree, formals_style);
49static 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 65static char *
35b1a6fa 66affix_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 111static const char *
35b1a6fa 112gen_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
193static int
35b1a6fa 194deserves_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 228static const char *
35b1a6fa 229gen_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 301static const char *
35b1a6fa 302gen_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 472static const char *
35b1a6fa 473gen_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 544extern 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
550void
35b1a6fa
AJ
551gen_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}