c-aux-info.c revision 132718
146283Sdfr/* Generate information regarding function declarations and definitions based
246283Sdfr   on information stored in GCC's tree structure.  This code implements the
346283Sdfr   -aux-info option.
446283Sdfr   Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
546283Sdfr   1999, 2000, 2003 Free Software Foundation, Inc.
646283Sdfr   Contributed by Ron Guilmette (rfg@segfault.us.com).
746283Sdfr
846283SdfrThis file is part of GCC.
946283Sdfr
1046283SdfrGCC is free software; you can redistribute it and/or modify it under
1146283Sdfrthe terms of the GNU General Public License as published by the Free
1246283SdfrSoftware Foundation; either version 2, or (at your option) any later
1346283Sdfrversion.
1446283Sdfr
1546283SdfrGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1646283SdfrWARRANTY; without even the implied warranty of MERCHANTABILITY or
1746283SdfrFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1846283Sdfrfor more details.
1946283Sdfr
2046283SdfrYou should have received a copy of the GNU General Public License
2146283Sdfralong with GCC; see the file COPYING.  If not, write to the Free
2246283SdfrSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2346283Sdfr02111-1307, USA.  */
2446283Sdfr
2546283Sdfr#include "config.h"
2646283Sdfr#include "system.h"
2746283Sdfr#include "coretypes.h"
2846283Sdfr#include "tm.h"
2946283Sdfr#include "flags.h"
3046283Sdfr#include "tree.h"
3146283Sdfr#include "c-tree.h"
3246283Sdfr#include "toplev.h"
3346283Sdfr
3446283Sdfrenum formals_style_enum {
3546283Sdfr  ansi,
3646283Sdfr  k_and_r_names,
3746283Sdfr  k_and_r_decls
3846283Sdfr};
3946283Sdfrtypedef enum formals_style_enum formals_style;
4046283Sdfr
4146283Sdfr
4246283Sdfrstatic const char *data_type;
4346283Sdfr
4446283Sdfrstatic char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
4546283Sdfrstatic const char *gen_formal_list_for_type (tree, formals_style);
4646283Sdfrstatic int   deserves_ellipsis (tree);
4746283Sdfrstatic const char *gen_formal_list_for_func_def (tree, formals_style);
4846283Sdfrstatic const char *gen_type (const char *, tree, formals_style);
4946283Sdfrstatic const char *gen_decl (tree, int, formals_style);
5046283Sdfr
5146283Sdfr/* Given a string representing an entire type or an entire declaration
5246283Sdfr   which only lacks the actual "data-type" specifier (at its left end),
5346283Sdfr   affix the data-type specifier to the left end of the given type
5446283Sdfr   specification or object declaration.
5546283Sdfr
5646283Sdfr   Because of C language weirdness, the data-type specifier (which normally
5746283Sdfr   goes in at the very left end) may have to be slipped in just to the
5846283Sdfr   right of any leading "const" or "volatile" qualifiers (there may be more
5946283Sdfr   than one).  Actually this may not be strictly necessary because it seems
6046283Sdfr   that GCC (at least) accepts `<data-type> const foo;' and treats it the
6146283Sdfr   same as `const <data-type> foo;' but people are accustomed to seeing
6246283Sdfr   `const char *foo;' and *not* `char const *foo;' so we try to create types
6346283Sdfr   that look as expected.  */
6446283Sdfr
6546283Sdfrstatic char *
6646283Sdfraffix_data_type (const char *param)
6746283Sdfr{
6846283Sdfr  char *const type_or_decl = ASTRDUP (param);
6946283Sdfr  char *p = type_or_decl;
7046283Sdfr  char *qualifiers_then_data_type;
7146283Sdfr  char saved;
7246283Sdfr
7346283Sdfr  /* Skip as many leading const's or volatile's as there are.  */
7446283Sdfr
7546283Sdfr  for (;;)
7646283Sdfr    {
7746283Sdfr      if (!strncmp (p, "volatile ", 9))
7846283Sdfr        {
7946283Sdfr          p += 9;
8046283Sdfr          continue;
8146283Sdfr        }
8246283Sdfr      if (!strncmp (p, "const ", 6))
8346283Sdfr        {
8446283Sdfr          p += 6;
8546283Sdfr          continue;
8646283Sdfr        }
8746283Sdfr      break;
8846283Sdfr    }
8946283Sdfr
9046283Sdfr  /* p now points to the place where we can insert the data type.  We have to
9146283Sdfr     add a blank after the data-type of course.  */
9246283Sdfr
9346283Sdfr  if (p == type_or_decl)
9446283Sdfr    return concat (data_type, " ", type_or_decl, NULL);
9546283Sdfr
9646283Sdfr  saved = *p;
9746283Sdfr  *p = '\0';
9846283Sdfr  qualifiers_then_data_type = concat (type_or_decl, data_type, NULL);
9946283Sdfr  *p = saved;
10046283Sdfr  return reconcat (qualifiers_then_data_type,
10146283Sdfr		   qualifiers_then_data_type, " ", p, NULL);
10246283Sdfr}
10346283Sdfr
10446283Sdfr/* Given a tree node which represents some "function type", generate the
10546283Sdfr   source code version of a formal parameter list (of some given style) for
10646283Sdfr   this function type.  Return the whole formal parameter list (including
10746283Sdfr   a pair of surrounding parens) as a string.   Note that if the style
10846283Sdfr   we are currently aiming for is non-ansi, then we just return a pair
10946283Sdfr   of empty parens here.  */
11046283Sdfr
11146283Sdfrstatic const char *
11246283Sdfrgen_formal_list_for_type (tree fntype, formals_style style)
11346283Sdfr{
11446283Sdfr  const char *formal_list = "";
11546283Sdfr  tree formal_type;
11646283Sdfr
11746283Sdfr  if (style != ansi)
11846283Sdfr    return "()";
11946283Sdfr
12046283Sdfr  formal_type = TYPE_ARG_TYPES (fntype);
12146283Sdfr  while (formal_type && TREE_VALUE (formal_type) != void_type_node)
12246283Sdfr    {
12346283Sdfr      const char *this_type;
12446283Sdfr
12546283Sdfr      if (*formal_list)
12646283Sdfr        formal_list = concat (formal_list, ", ", NULL);
12746283Sdfr
12846283Sdfr      this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
12946283Sdfr      formal_list
13046283Sdfr	= ((strlen (this_type))
13146283Sdfr	   ? concat (formal_list, affix_data_type (this_type), NULL)
13246283Sdfr	   : concat (formal_list, data_type, NULL));
13346283Sdfr
13446283Sdfr      formal_type = TREE_CHAIN (formal_type);
13546283Sdfr    }
13646283Sdfr
13746283Sdfr  /* If we got to here, then we are trying to generate an ANSI style formal
13846283Sdfr     parameters list.
13946283Sdfr
14046283Sdfr     New style prototyped ANSI formal parameter lists should in theory always
14146283Sdfr     contain some stuff between the opening and closing parens, even if it is
14246283Sdfr     only "void".
14346283Sdfr
14446283Sdfr     The brutal truth though is that there is lots of old K&R code out there
14546283Sdfr     which contains declarations of "pointer-to-function" parameters and
14646283Sdfr     these almost never have fully specified formal parameter lists associated
14746283Sdfr     with them.  That is, the pointer-to-function parameters are declared
14846283Sdfr     with just empty parameter lists.
14946283Sdfr
15046283Sdfr     In cases such as these, protoize should really insert *something* into
15146283Sdfr     the vacant parameter lists, but what?  It has no basis on which to insert
15246283Sdfr     anything in particular.
15346283Sdfr
15446283Sdfr     Here, we make life easy for protoize by trying to distinguish between
15546283Sdfr     K&R empty parameter lists and new-style prototyped parameter lists
15646283Sdfr     that actually contain "void".  In the latter case we (obviously) want
15746283Sdfr     to output the "void" verbatim, and that what we do.  In the former case,
15846283Sdfr     we do our best to give protoize something nice to insert.
15946283Sdfr
16046283Sdfr     This "something nice" should be something that is still valid (when
16146283Sdfr     re-compiled) but something that can clearly indicate to the user that
16246283Sdfr     more typing information (for the parameter list) should be added (by
16346283Sdfr     hand) at some convenient moment.
16446283Sdfr
16546283Sdfr     The string chosen here is a comment with question marks in it.  */
16646283Sdfr
16746283Sdfr  if (!*formal_list)
16846283Sdfr    {
16946283Sdfr      if (TYPE_ARG_TYPES (fntype))
17046283Sdfr        /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node);  */
17146283Sdfr        formal_list = "void";
17246283Sdfr      else
17346283Sdfr        formal_list = "/* ??? */";
17446283Sdfr    }
17546283Sdfr  else
17646283Sdfr    {
17746283Sdfr      /* If there were at least some parameters, and if the formals-types-list
17846283Sdfr         petered out to a NULL (i.e. without being terminated by a
17946283Sdfr         void_type_node) then we need to tack on an ellipsis.  */
18046283Sdfr      if (!formal_type)
18146283Sdfr        formal_list = concat (formal_list, ", ...", NULL);
18246283Sdfr    }
18346283Sdfr
18446283Sdfr  return concat (" (", formal_list, ")", NULL);
18546283Sdfr}
18646283Sdfr
18746283Sdfr/* For the generation of an ANSI prototype for a function definition, we have
18846283Sdfr   to look at the formal parameter list of the function's own "type" to
18946283Sdfr   determine if the function's formal parameter list should end with an
19046283Sdfr   ellipsis.  Given a tree node, the following function will return nonzero
19146283Sdfr   if the "function type" parameter list should end with an ellipsis.  */
19246283Sdfr
19346283Sdfrstatic int
19446283Sdfrdeserves_ellipsis (tree fntype)
19546283Sdfr{
19646283Sdfr  tree formal_type;
19746283Sdfr
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
228static const char *
229gen_formal_list_for_func_def (tree fndecl, formals_style style)
230{
231  const char *formal_list = "";
232  tree formal_decl;
233
234  formal_decl = DECL_ARGUMENTS (fndecl);
235  while (formal_decl)
236    {
237      const char *this_formal;
238
239      if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
240        formal_list = concat (formal_list, ", ", NULL);
241      this_formal = gen_decl (formal_decl, 0, style);
242      if (style == k_and_r_decls)
243        formal_list = concat (formal_list, this_formal, "; ", NULL);
244      else
245        formal_list = concat (formal_list, this_formal, NULL);
246      formal_decl = TREE_CHAIN (formal_decl);
247    }
248  if (style == ansi)
249    {
250      if (!DECL_ARGUMENTS (fndecl))
251        formal_list = concat (formal_list, "void", NULL);
252      if (deserves_ellipsis (TREE_TYPE (fndecl)))
253        formal_list = concat (formal_list, ", ...", NULL);
254    }
255  if ((style == ansi) || (style == k_and_r_names))
256    formal_list = concat (" (", formal_list, ")", NULL);
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
301static const char *
302gen_type (const char *ret_val, tree t, formals_style style)
303{
304  tree chain_p;
305
306  /* If there is a typedef name for this type, use it.  */
307  if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
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))
315            ret_val = concat ("const ", ret_val, NULL);
316          if (TYPE_VOLATILE (t))
317            ret_val = concat ("volatile ", ret_val, NULL);
318
319          ret_val = concat ("*", ret_val, NULL);
320
321	  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
322	    ret_val = concat ("(", ret_val, ")", NULL);
323
324          ret_val = gen_type (ret_val, TREE_TYPE (t), style);
325
326          return ret_val;
327
328        case ARRAY_TYPE:
329	  if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
330	    ret_val = gen_type (concat (ret_val, "[]", NULL),
331				TREE_TYPE (t), style);
332	  else if (int_size_in_bytes (t) == 0)
333	    ret_val = gen_type (concat (ret_val, "[0]", NULL),
334				TREE_TYPE (t), style);
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);
340	      ret_val = gen_type (concat (ret_val, buff, NULL),
341				  TREE_TYPE (t), style);
342	    }
343          break;
344
345        case FUNCTION_TYPE:
346          ret_val = gen_type (concat (ret_val,
347				      gen_formal_list_for_type (t, style),
348				      NULL),
349			      TREE_TYPE (t), style);
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		{
376		  data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
377				      NULL);
378		  chain_p = TREE_CHAIN (chain_p);
379		  data_type = concat (data_type, "; ", NULL);
380		}
381	      data_type = concat ("{ ", data_type, "}", NULL);
382	    }
383	  data_type = concat ("struct ", data_type, NULL);
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		{
395		  data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
396				      NULL);
397		  chain_p = TREE_CHAIN (chain_p);
398		  data_type = concat (data_type, "; ", NULL);
399		}
400	      data_type = concat ("{ ", data_type, "}", NULL);
401	    }
402	  data_type = concat ("union ", data_type, NULL);
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,
415			IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL);
416		  chain_p = TREE_CHAIN (chain_p);
417		  if (chain_p)
418		    data_type = concat (data_type, ", ", NULL);
419		}
420	      data_type = concat ("{ ", data_type, " }", NULL);
421	    }
422	  data_type = concat ("enum ", data_type, NULL);
423	  break;
424
425        case TYPE_DECL:
426          data_type = IDENTIFIER_POINTER (DECL_NAME (t));
427          break;
428
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
432	     with a type qualifier.  */
433          if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
434	    data_type = concat ("unsigned ", data_type, NULL);
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
445	case ERROR_MARK:
446	  data_type = "[ERROR]";
447	  break;
448
449        default:
450          abort ();
451        }
452    }
453  if (TYPE_READONLY (t))
454    ret_val = concat ("const ", ret_val, NULL);
455  if (TYPE_VOLATILE (t))
456    ret_val = concat ("volatile ", ret_val, NULL);
457  if (TYPE_RESTRICT (t))
458    ret_val = concat ("restrict ", ret_val, NULL);
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
467   If the "is_func_definition" parameter is nonzero, assume that the thing
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
472static const char *
473gen_decl (tree decl, int is_func_definition, formals_style style)
474{
475  const char *ret_val;
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))
497    ret_val = concat ("volatile ", ret_val, NULL);
498  if (TREE_READONLY (decl))
499    ret_val = concat ("const ", ret_val, NULL);
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    {
517      ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi),
518			NULL);
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
534  if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
535    ret_val = concat ("register ", ret_val, NULL);
536  if (TREE_PUBLIC (decl))
537    ret_val = concat ("extern ", ret_val, NULL);
538  if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
539    ret_val = concat ("static ", ret_val, NULL);
540
541  return ret_val;
542}
543
544extern FILE *aux_info_file;
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
551gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
552		     int is_prototyped)
553{
554  if (flag_gen_aux_info)
555    {
556      static int compiled_from_record = 0;
557
558      /* Each output .X file must have a header line.  Write one now if we
559	 have not yet done so.  */
560
561      if (! compiled_from_record++)
562	{
563	  /* The first line tells which directory file names are relative to.
564	     Currently, -aux-info works only for files in the working
565	     directory, so just use a `.' as a placeholder for now.  */
566	  fprintf (aux_info_file, "/* compiled from: . */\n");
567	}
568
569      /* Write the actual line of auxiliary info.  */
570
571      fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
572	       DECL_SOURCE_FILE (fndecl),
573	       DECL_SOURCE_LINE (fndecl),
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}
592