110d565efSmrg /* Generate information regarding function declarations and definitions based
210d565efSmrg    on information stored in GCC's tree structure.  This code implements the
310d565efSmrg    -aux-info option.
4*ec02198aSmrg    Copyright (C) 1989-2020 Free Software Foundation, Inc.
510d565efSmrg    Contributed by Ron Guilmette (rfg@segfault.us.com).
610d565efSmrg 
710d565efSmrg This file is part of GCC.
810d565efSmrg 
910d565efSmrg GCC is free software; you can redistribute it and/or modify it under
1010d565efSmrg the terms of the GNU General Public License as published by the Free
1110d565efSmrg Software Foundation; either version 3, or (at your option) any later
1210d565efSmrg version.
1310d565efSmrg 
1410d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1510d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1610d565efSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1710d565efSmrg for more details.
1810d565efSmrg 
1910d565efSmrg You should have received a copy of the GNU General Public License
2010d565efSmrg along with GCC; see the file COPYING3.  If not see
2110d565efSmrg <http://www.gnu.org/licenses/>.  */
2210d565efSmrg 
2310d565efSmrg #include "config.h"
2410d565efSmrg #include "system.h"
2510d565efSmrg #include "coretypes.h"
2610d565efSmrg #include "tm.h"
2710d565efSmrg #include "c-tree.h"
2810d565efSmrg 
2910d565efSmrg enum formals_style {
3010d565efSmrg   ansi,
3110d565efSmrg   k_and_r_names,
3210d565efSmrg   k_and_r_decls
3310d565efSmrg };
3410d565efSmrg 
3510d565efSmrg 
3610d565efSmrg static const char *data_type;
3710d565efSmrg 
3810d565efSmrg static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
3910d565efSmrg static const char *gen_formal_list_for_type (tree, formals_style);
4010d565efSmrg static const char *gen_formal_list_for_func_def (tree, formals_style);
4110d565efSmrg static const char *gen_type (const char *, tree, formals_style);
4210d565efSmrg static const char *gen_decl (tree, int, formals_style);
4310d565efSmrg 
4410d565efSmrg /* Given a string representing an entire type or an entire declaration
4510d565efSmrg    which only lacks the actual "data-type" specifier (at its left end),
4610d565efSmrg    affix the data-type specifier to the left end of the given type
4710d565efSmrg    specification or object declaration.
4810d565efSmrg 
4910d565efSmrg    Because of C language weirdness, the data-type specifier (which normally
5010d565efSmrg    goes in at the very left end) may have to be slipped in just to the
5110d565efSmrg    right of any leading "const" or "volatile" qualifiers (there may be more
5210d565efSmrg    than one).  Actually this may not be strictly necessary because it seems
5310d565efSmrg    that GCC (at least) accepts `<data-type> const foo;' and treats it the
5410d565efSmrg    same as `const <data-type> foo;' but people are accustomed to seeing
5510d565efSmrg    `const char *foo;' and *not* `char const *foo;' so we try to create types
5610d565efSmrg    that look as expected.  */
5710d565efSmrg 
5810d565efSmrg static char *
affix_data_type(const char * param)5910d565efSmrg affix_data_type (const char *param)
6010d565efSmrg {
6110d565efSmrg   char *const type_or_decl = ASTRDUP (param);
6210d565efSmrg   char *p = type_or_decl;
6310d565efSmrg   char *qualifiers_then_data_type;
6410d565efSmrg   char saved;
6510d565efSmrg 
6610d565efSmrg   /* Skip as many leading const's or volatile's as there are.  */
6710d565efSmrg 
6810d565efSmrg   for (;;)
6910d565efSmrg     {
7010d565efSmrg       if (!strncmp (p, "volatile ", 9))
7110d565efSmrg 	{
7210d565efSmrg 	  p += 9;
7310d565efSmrg 	  continue;
7410d565efSmrg 	}
7510d565efSmrg       if (!strncmp (p, "const ", 6))
7610d565efSmrg 	{
7710d565efSmrg 	  p += 6;
7810d565efSmrg 	  continue;
7910d565efSmrg 	}
8010d565efSmrg       break;
8110d565efSmrg     }
8210d565efSmrg 
8310d565efSmrg   /* p now points to the place where we can insert the data type.  We have to
8410d565efSmrg      add a blank after the data-type of course.  */
8510d565efSmrg 
8610d565efSmrg   if (p == type_or_decl)
8710d565efSmrg     return concat (data_type, " ", type_or_decl, NULL);
8810d565efSmrg 
8910d565efSmrg   saved = *p;
9010d565efSmrg   *p = '\0';
9110d565efSmrg   qualifiers_then_data_type = concat (type_or_decl, data_type, NULL);
9210d565efSmrg   *p = saved;
9310d565efSmrg   return reconcat (qualifiers_then_data_type,
9410d565efSmrg 		   qualifiers_then_data_type, " ", p, NULL);
9510d565efSmrg }
9610d565efSmrg 
9710d565efSmrg /* Given a tree node which represents some "function type", generate the
9810d565efSmrg    source code version of a formal parameter list (of some given style) for
9910d565efSmrg    this function type.  Return the whole formal parameter list (including
10010d565efSmrg    a pair of surrounding parens) as a string.   Note that if the style
10110d565efSmrg    we are currently aiming for is non-ansi, then we just return a pair
10210d565efSmrg    of empty parens here.  */
10310d565efSmrg 
10410d565efSmrg static const char *
gen_formal_list_for_type(tree fntype,formals_style style)10510d565efSmrg gen_formal_list_for_type (tree fntype, formals_style style)
10610d565efSmrg {
10710d565efSmrg   const char *formal_list = "";
10810d565efSmrg   tree formal_type;
10910d565efSmrg 
11010d565efSmrg   if (style != ansi)
11110d565efSmrg     return "()";
11210d565efSmrg 
11310d565efSmrg   formal_type = TYPE_ARG_TYPES (fntype);
11410d565efSmrg   while (formal_type && TREE_VALUE (formal_type) != void_type_node)
11510d565efSmrg     {
11610d565efSmrg       const char *this_type;
11710d565efSmrg 
11810d565efSmrg       if (*formal_list)
11910d565efSmrg 	formal_list = concat (formal_list, ", ", NULL);
12010d565efSmrg 
12110d565efSmrg       this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
12210d565efSmrg       formal_list
12310d565efSmrg 	= ((strlen (this_type))
12410d565efSmrg 	   ? concat (formal_list, affix_data_type (this_type), NULL)
12510d565efSmrg 	   : concat (formal_list, data_type, NULL));
12610d565efSmrg 
12710d565efSmrg       formal_type = TREE_CHAIN (formal_type);
12810d565efSmrg     }
12910d565efSmrg 
13010d565efSmrg   /* If we got to here, then we are trying to generate an ANSI style formal
13110d565efSmrg      parameters list.
13210d565efSmrg 
13310d565efSmrg      New style prototyped ANSI formal parameter lists should in theory always
13410d565efSmrg      contain some stuff between the opening and closing parens, even if it is
13510d565efSmrg      only "void".
13610d565efSmrg 
13710d565efSmrg      The brutal truth though is that there is lots of old K&R code out there
13810d565efSmrg      which contains declarations of "pointer-to-function" parameters and
13910d565efSmrg      these almost never have fully specified formal parameter lists associated
14010d565efSmrg      with them.  That is, the pointer-to-function parameters are declared
14110d565efSmrg      with just empty parameter lists.
14210d565efSmrg 
14310d565efSmrg      In cases such as these, protoize should really insert *something* into
14410d565efSmrg      the vacant parameter lists, but what?  It has no basis on which to insert
14510d565efSmrg      anything in particular.
14610d565efSmrg 
14710d565efSmrg      Here, we make life easy for protoize by trying to distinguish between
14810d565efSmrg      K&R empty parameter lists and new-style prototyped parameter lists
14910d565efSmrg      that actually contain "void".  In the latter case we (obviously) want
15010d565efSmrg      to output the "void" verbatim, and that what we do.  In the former case,
15110d565efSmrg      we do our best to give protoize something nice to insert.
15210d565efSmrg 
15310d565efSmrg      This "something nice" should be something that is still valid (when
15410d565efSmrg      re-compiled) but something that can clearly indicate to the user that
15510d565efSmrg      more typing information (for the parameter list) should be added (by
15610d565efSmrg      hand) at some convenient moment.
15710d565efSmrg 
15810d565efSmrg      The string chosen here is a comment with question marks in it.  */
15910d565efSmrg 
16010d565efSmrg   if (!*formal_list)
16110d565efSmrg     {
16210d565efSmrg       if (prototype_p (fntype))
16310d565efSmrg 	/* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node);  */
16410d565efSmrg 	formal_list = "void";
16510d565efSmrg       else
16610d565efSmrg 	formal_list = "/* ??? */";
16710d565efSmrg     }
16810d565efSmrg   else
16910d565efSmrg     {
17010d565efSmrg       /* If there were at least some parameters, and if the formals-types-list
17110d565efSmrg 	 petered out to a NULL (i.e. without being terminated by a
17210d565efSmrg 	 void_type_node) then we need to tack on an ellipsis.  */
17310d565efSmrg       if (!formal_type)
17410d565efSmrg 	formal_list = concat (formal_list, ", ...", NULL);
17510d565efSmrg     }
17610d565efSmrg 
17710d565efSmrg   return concat (" (", formal_list, ")", NULL);
17810d565efSmrg }
17910d565efSmrg 
18010d565efSmrg /* Generate a parameter list for a function definition (in some given style).
18110d565efSmrg 
18210d565efSmrg    Note that this routine has to be separate (and different) from the code that
18310d565efSmrg    generates the prototype parameter lists for function declarations, because
18410d565efSmrg    in the case of a function declaration, all we have to go on is a tree node
18510d565efSmrg    representing the function's own "function type".  This can tell us the types
18610d565efSmrg    of all of the formal parameters for the function, but it cannot tell us the
18710d565efSmrg    actual *names* of each of the formal parameters.  We need to output those
18810d565efSmrg    parameter names for each function definition.
18910d565efSmrg 
19010d565efSmrg    This routine gets a pointer to a tree node which represents the actual
19110d565efSmrg    declaration of the given function, and this DECL node has a list of formal
19210d565efSmrg    parameter (variable) declarations attached to it.  These formal parameter
19310d565efSmrg    (variable) declaration nodes give us the actual names of the formal
19410d565efSmrg    parameters for the given function definition.
19510d565efSmrg 
19610d565efSmrg    This routine returns a string which is the source form for the entire
19710d565efSmrg    function formal parameter list.  */
19810d565efSmrg 
19910d565efSmrg static const char *
gen_formal_list_for_func_def(tree fndecl,formals_style style)20010d565efSmrg gen_formal_list_for_func_def (tree fndecl, formals_style style)
20110d565efSmrg {
20210d565efSmrg   const char *formal_list = "";
20310d565efSmrg   tree formal_decl;
20410d565efSmrg 
20510d565efSmrg   formal_decl = DECL_ARGUMENTS (fndecl);
20610d565efSmrg   while (formal_decl)
20710d565efSmrg     {
20810d565efSmrg       const char *this_formal;
20910d565efSmrg 
21010d565efSmrg       if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
21110d565efSmrg 	formal_list = concat (formal_list, ", ", NULL);
21210d565efSmrg       this_formal = gen_decl (formal_decl, 0, style);
21310d565efSmrg       if (style == k_and_r_decls)
21410d565efSmrg 	formal_list = concat (formal_list, this_formal, "; ", NULL);
21510d565efSmrg       else
21610d565efSmrg 	formal_list = concat (formal_list, this_formal, NULL);
21710d565efSmrg       formal_decl = TREE_CHAIN (formal_decl);
21810d565efSmrg     }
21910d565efSmrg   if (style == ansi)
22010d565efSmrg     {
22110d565efSmrg       if (!DECL_ARGUMENTS (fndecl))
22210d565efSmrg 	formal_list = concat (formal_list, "void", NULL);
22310d565efSmrg       if (stdarg_p (TREE_TYPE (fndecl)))
22410d565efSmrg 	formal_list = concat (formal_list, ", ...", NULL);
22510d565efSmrg     }
22610d565efSmrg   if ((style == ansi) || (style == k_and_r_names))
22710d565efSmrg     formal_list = concat (" (", formal_list, ")", NULL);
22810d565efSmrg   return formal_list;
22910d565efSmrg }
23010d565efSmrg 
23110d565efSmrg /* Generate a string which is the source code form for a given type (t).  This
23210d565efSmrg    routine is ugly and complex because the C syntax for declarations is ugly
23310d565efSmrg    and complex.  This routine is straightforward so long as *no* pointer types,
23410d565efSmrg    array types, or function types are involved.
23510d565efSmrg 
23610d565efSmrg    In the simple cases, this routine will return the (string) value which was
23710d565efSmrg    passed in as the "ret_val" argument.  Usually, this starts out either as an
23810d565efSmrg    empty string, or as the name of the declared item (i.e. the formal function
23910d565efSmrg    parameter variable).
24010d565efSmrg 
24110d565efSmrg    This routine will also return with the global variable "data_type" set to
24210d565efSmrg    some string value which is the "basic" data-type of the given complete type.
24310d565efSmrg    This "data_type" string can be concatenated onto the front of the returned
24410d565efSmrg    string after this routine returns to its caller.
24510d565efSmrg 
24610d565efSmrg    In complicated cases involving pointer types, array types, or function
24710d565efSmrg    types, the C declaration syntax requires an "inside out" approach, i.e. if
24810d565efSmrg    you have a type which is a "pointer-to-function" type, you need to handle
24910d565efSmrg    the "pointer" part first, but it also has to be "innermost" (relative to
25010d565efSmrg    the declaration stuff for the "function" type).  Thus, is this case, you
25110d565efSmrg    must prepend a "(*" and append a ")" to the name of the item (i.e. formal
25210d565efSmrg    variable).  Then you must append and prepend the other info for the
25310d565efSmrg    "function type" part of the overall type.
25410d565efSmrg 
25510d565efSmrg    To handle the "innermost precedence" rules of complicated C declarators, we
25610d565efSmrg    do the following (in this routine).  The input parameter called "ret_val"
25710d565efSmrg    is treated as a "seed".  Each time gen_type is called (perhaps recursively)
25810d565efSmrg    some additional strings may be appended or prepended (or both) to the "seed"
25910d565efSmrg    string.  If yet another (lower) level of the GCC tree exists for the given
26010d565efSmrg    type (as in the case of a pointer type, an array type, or a function type)
26110d565efSmrg    then the (wrapped) seed is passed to a (recursive) invocation of gen_type()
26210d565efSmrg    this recursive invocation may again "wrap" the (new) seed with yet more
26310d565efSmrg    declarator stuff, by appending, prepending (or both).  By the time the
26410d565efSmrg    recursion bottoms out, the "seed value" at that point will have a value
26510d565efSmrg    which is (almost) the complete source version of the declarator (except
26610d565efSmrg    for the data_type info).  Thus, this deepest "seed" value is simply passed
26710d565efSmrg    back up through all of the recursive calls until it is given (as the return
26810d565efSmrg    value) to the initial caller of the gen_type() routine.  All that remains
26910d565efSmrg    to do at this point is for the initial caller to prepend the "data_type"
27010d565efSmrg    string onto the returned "seed".  */
27110d565efSmrg 
27210d565efSmrg static const char *
gen_type(const char * ret_val,tree t,formals_style style)27310d565efSmrg gen_type (const char *ret_val, tree t, formals_style style)
27410d565efSmrg {
27510d565efSmrg   tree chain_p;
27610d565efSmrg 
27710d565efSmrg   /* If there is a typedef name for this type, use it.  */
27810d565efSmrg   if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
27910d565efSmrg     data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
28010d565efSmrg   else
28110d565efSmrg     {
28210d565efSmrg       switch (TREE_CODE (t))
28310d565efSmrg 	{
28410d565efSmrg 	case POINTER_TYPE:
28510d565efSmrg 	  if (TYPE_ATOMIC (t))
28610d565efSmrg 	    ret_val = concat ("_Atomic ", ret_val, NULL);
28710d565efSmrg 	  if (TYPE_READONLY (t))
28810d565efSmrg 	    ret_val = concat ("const ", ret_val, NULL);
28910d565efSmrg 	  if (TYPE_VOLATILE (t))
29010d565efSmrg 	    ret_val = concat ("volatile ", ret_val, NULL);
29110d565efSmrg 
29210d565efSmrg 	  ret_val = concat ("*", ret_val, NULL);
29310d565efSmrg 
29410d565efSmrg 	  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
29510d565efSmrg 	    ret_val = concat ("(", ret_val, ")", NULL);
29610d565efSmrg 
29710d565efSmrg 	  ret_val = gen_type (ret_val, TREE_TYPE (t), style);
29810d565efSmrg 
29910d565efSmrg 	  return ret_val;
30010d565efSmrg 
30110d565efSmrg 	case ARRAY_TYPE:
30210d565efSmrg 	  if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
30310d565efSmrg 	    ret_val = gen_type (concat (ret_val, "[]", NULL),
30410d565efSmrg 				TREE_TYPE (t), style);
30510d565efSmrg 	  else if (int_size_in_bytes (t) == 0)
30610d565efSmrg 	    ret_val = gen_type (concat (ret_val, "[0]", NULL),
30710d565efSmrg 				TREE_TYPE (t), style);
30810d565efSmrg 	  else
30910d565efSmrg 	    {
31010d565efSmrg 	      char buff[23];
31110d565efSmrg 	      sprintf (buff, "[" HOST_WIDE_INT_PRINT_DEC"]",
31210d565efSmrg 		       int_size_in_bytes (t)
31310d565efSmrg 		       / int_size_in_bytes (TREE_TYPE (t)));
31410d565efSmrg 	      ret_val = gen_type (concat (ret_val, buff, NULL),
31510d565efSmrg 				  TREE_TYPE (t), style);
31610d565efSmrg 	    }
31710d565efSmrg 	  break;
31810d565efSmrg 
31910d565efSmrg 	case FUNCTION_TYPE:
32010d565efSmrg 	  ret_val = gen_type (concat (ret_val,
32110d565efSmrg 				      gen_formal_list_for_type (t, style),
32210d565efSmrg 				      NULL),
32310d565efSmrg 			      TREE_TYPE (t), style);
32410d565efSmrg 	  break;
32510d565efSmrg 
32610d565efSmrg 	case IDENTIFIER_NODE:
32710d565efSmrg 	  data_type = IDENTIFIER_POINTER (t);
32810d565efSmrg 	  break;
32910d565efSmrg 
33010d565efSmrg 	/* The following three cases are complicated by the fact that a
33110d565efSmrg 	   user may do something really stupid, like creating a brand new
33210d565efSmrg 	   "anonymous" type specification in a formal argument list (or as
33310d565efSmrg 	   part of a function return type specification).  For example:
33410d565efSmrg 
33510d565efSmrg 		int f (enum { red, green, blue } color);
33610d565efSmrg 
33710d565efSmrg 	   In such cases, we have no name that we can put into the prototype
33810d565efSmrg 	   to represent the (anonymous) type.  Thus, we have to generate the
33910d565efSmrg 	   whole darn type specification.  Yuck!  */
34010d565efSmrg 
34110d565efSmrg 	case RECORD_TYPE:
34210d565efSmrg 	  if (TYPE_NAME (t))
34310d565efSmrg 	    data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
34410d565efSmrg 	  else
34510d565efSmrg 	    {
34610d565efSmrg 	      data_type = "";
34710d565efSmrg 	      chain_p = TYPE_FIELDS (t);
34810d565efSmrg 	      while (chain_p)
34910d565efSmrg 		{
35010d565efSmrg 		  data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
35110d565efSmrg 				      NULL);
35210d565efSmrg 		  chain_p = TREE_CHAIN (chain_p);
35310d565efSmrg 		  data_type = concat (data_type, "; ", NULL);
35410d565efSmrg 		}
35510d565efSmrg 	      data_type = concat ("{ ", data_type, "}", NULL);
35610d565efSmrg 	    }
35710d565efSmrg 	  data_type = concat ("struct ", data_type, NULL);
35810d565efSmrg 	  break;
35910d565efSmrg 
36010d565efSmrg 	case UNION_TYPE:
36110d565efSmrg 	  if (TYPE_NAME (t))
36210d565efSmrg 	    data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
36310d565efSmrg 	  else
36410d565efSmrg 	    {
36510d565efSmrg 	      data_type = "";
36610d565efSmrg 	      chain_p = TYPE_FIELDS (t);
36710d565efSmrg 	      while (chain_p)
36810d565efSmrg 		{
36910d565efSmrg 		  data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
37010d565efSmrg 				      NULL);
37110d565efSmrg 		  chain_p = TREE_CHAIN (chain_p);
37210d565efSmrg 		  data_type = concat (data_type, "; ", NULL);
37310d565efSmrg 		}
37410d565efSmrg 	      data_type = concat ("{ ", data_type, "}", NULL);
37510d565efSmrg 	    }
37610d565efSmrg 	  data_type = concat ("union ", data_type, NULL);
37710d565efSmrg 	  break;
37810d565efSmrg 
37910d565efSmrg 	case ENUMERAL_TYPE:
38010d565efSmrg 	  if (TYPE_NAME (t))
38110d565efSmrg 	    data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
38210d565efSmrg 	  else
38310d565efSmrg 	    {
38410d565efSmrg 	      data_type = "";
38510d565efSmrg 	      chain_p = TYPE_VALUES (t);
38610d565efSmrg 	      while (chain_p)
38710d565efSmrg 		{
38810d565efSmrg 		  data_type = concat (data_type,
38910d565efSmrg 			IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL);
39010d565efSmrg 		  chain_p = TREE_CHAIN (chain_p);
39110d565efSmrg 		  if (chain_p)
39210d565efSmrg 		    data_type = concat (data_type, ", ", NULL);
39310d565efSmrg 		}
39410d565efSmrg 	      data_type = concat ("{ ", data_type, " }", NULL);
39510d565efSmrg 	    }
39610d565efSmrg 	  data_type = concat ("enum ", data_type, NULL);
39710d565efSmrg 	  break;
39810d565efSmrg 
39910d565efSmrg 	case TYPE_DECL:
40010d565efSmrg 	  data_type = IDENTIFIER_POINTER (DECL_NAME (t));
40110d565efSmrg 	  break;
40210d565efSmrg 
40310d565efSmrg 	case INTEGER_TYPE:
40410d565efSmrg 	case FIXED_POINT_TYPE:
40510d565efSmrg 	  data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
40610d565efSmrg 	  /* Normally, `unsigned' is part of the deal.  Not so if it comes
40710d565efSmrg 	     with a type qualifier.  */
40810d565efSmrg 	  if (TYPE_UNSIGNED (t) && TYPE_QUALS (t))
40910d565efSmrg 	    data_type = concat ("unsigned ", data_type, NULL);
41010d565efSmrg 	  break;
41110d565efSmrg 
41210d565efSmrg 	case REAL_TYPE:
41310d565efSmrg 	  data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
41410d565efSmrg 	  break;
41510d565efSmrg 
41610d565efSmrg 	case VOID_TYPE:
41710d565efSmrg 	  data_type = "void";
41810d565efSmrg 	  break;
41910d565efSmrg 
42010d565efSmrg 	case ERROR_MARK:
42110d565efSmrg 	  data_type = "[ERROR]";
42210d565efSmrg 	  break;
42310d565efSmrg 
42410d565efSmrg 	default:
42510d565efSmrg 	  gcc_unreachable ();
42610d565efSmrg 	}
42710d565efSmrg     }
42810d565efSmrg   if (TYPE_ATOMIC (t))
42910d565efSmrg     ret_val = concat ("_Atomic ", ret_val, NULL);
43010d565efSmrg   if (TYPE_READONLY (t))
43110d565efSmrg     ret_val = concat ("const ", ret_val, NULL);
43210d565efSmrg   if (TYPE_VOLATILE (t))
43310d565efSmrg     ret_val = concat ("volatile ", ret_val, NULL);
43410d565efSmrg   if (TYPE_RESTRICT (t))
43510d565efSmrg     ret_val = concat ("restrict ", ret_val, NULL);
43610d565efSmrg   return ret_val;
43710d565efSmrg }
43810d565efSmrg 
43910d565efSmrg /* Generate a string (source) representation of an entire entity declaration
44010d565efSmrg    (using some particular style for function types).
44110d565efSmrg 
44210d565efSmrg    The given entity may be either a variable or a function.
44310d565efSmrg 
44410d565efSmrg    If the "is_func_definition" parameter is nonzero, assume that the thing
44510d565efSmrg    we are generating a declaration for is a FUNCTION_DECL node which is
44610d565efSmrg    associated with a function definition.  In this case, we can assume that
44710d565efSmrg    an attached list of DECL nodes for function formal arguments is present.  */
44810d565efSmrg 
44910d565efSmrg static const char *
gen_decl(tree decl,int is_func_definition,formals_style style)45010d565efSmrg gen_decl (tree decl, int is_func_definition, formals_style style)
45110d565efSmrg {
45210d565efSmrg   const char *ret_val;
45310d565efSmrg 
45410d565efSmrg   if (DECL_NAME (decl))
45510d565efSmrg     ret_val = IDENTIFIER_POINTER (DECL_NAME (decl));
45610d565efSmrg   else
45710d565efSmrg     ret_val = "";
45810d565efSmrg 
45910d565efSmrg   /* If we are just generating a list of names of formal parameters, we can
46010d565efSmrg      simply return the formal parameter name (with no typing information
46110d565efSmrg      attached to it) now.  */
46210d565efSmrg 
46310d565efSmrg   if (style == k_and_r_names)
46410d565efSmrg     return ret_val;
46510d565efSmrg 
46610d565efSmrg   /* Note that for the declaration of some entity (either a function or a
46710d565efSmrg      data object, like for instance a parameter) if the entity itself was
46810d565efSmrg      declared as either const or volatile, then const and volatile properties
46910d565efSmrg      are associated with just the declaration of the entity, and *not* with
47010d565efSmrg      the `type' of the entity.  Thus, for such declared entities, we have to
47110d565efSmrg      generate the qualifiers here.  */
47210d565efSmrg 
47310d565efSmrg   if (TREE_THIS_VOLATILE (decl))
47410d565efSmrg     ret_val = concat ("volatile ", ret_val, NULL);
47510d565efSmrg   if (TREE_READONLY (decl))
47610d565efSmrg     ret_val = concat ("const ", ret_val, NULL);
47710d565efSmrg 
47810d565efSmrg   data_type = "";
47910d565efSmrg 
48010d565efSmrg   /* For FUNCTION_DECL nodes, there are two possible cases here.  First, if
48110d565efSmrg      this FUNCTION_DECL node was generated from a function "definition", then
48210d565efSmrg      we will have a list of DECL_NODE's, one for each of the function's formal
48310d565efSmrg      parameters.  In this case, we can print out not only the types of each
48410d565efSmrg      formal, but also each formal's name.  In the second case, this
48510d565efSmrg      FUNCTION_DECL node came from an actual function declaration (and *not*
48610d565efSmrg      a definition).  In this case, we do nothing here because the formal
48710d565efSmrg      argument type-list will be output later, when the "type" of the function
48810d565efSmrg      is added to the string we are building.  Note that the ANSI-style formal
48910d565efSmrg      parameter list is considered to be a (suffix) part of the "type" of the
49010d565efSmrg      function.  */
49110d565efSmrg 
49210d565efSmrg   if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition)
49310d565efSmrg     {
49410d565efSmrg       ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi),
49510d565efSmrg 			NULL);
49610d565efSmrg 
49710d565efSmrg       /* Since we have already added in the formals list stuff, here we don't
49810d565efSmrg 	 add the whole "type" of the function we are considering (which
49910d565efSmrg 	 would include its parameter-list info), rather, we only add in
50010d565efSmrg 	 the "type" of the "type" of the function, which is really just
50110d565efSmrg 	 the return-type of the function (and does not include the parameter
50210d565efSmrg 	 list info).  */
50310d565efSmrg 
50410d565efSmrg       ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style);
50510d565efSmrg     }
50610d565efSmrg   else
50710d565efSmrg     ret_val = gen_type (ret_val, TREE_TYPE (decl), style);
50810d565efSmrg 
50910d565efSmrg   ret_val = affix_data_type (ret_val);
51010d565efSmrg 
51110d565efSmrg   if (TREE_CODE (decl) != FUNCTION_DECL && C_DECL_REGISTER (decl))
51210d565efSmrg     ret_val = concat ("register ", ret_val, NULL);
51310d565efSmrg   if (TREE_PUBLIC (decl))
51410d565efSmrg     ret_val = concat ("extern ", ret_val, NULL);
51510d565efSmrg   if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
51610d565efSmrg     ret_val = concat ("static ", ret_val, NULL);
51710d565efSmrg 
51810d565efSmrg   return ret_val;
51910d565efSmrg }
52010d565efSmrg 
52110d565efSmrg extern FILE *aux_info_file;
52210d565efSmrg 
52310d565efSmrg /* Generate and write a new line of info to the aux-info (.X) file.  This
52410d565efSmrg    routine is called once for each function declaration, and once for each
52510d565efSmrg    function definition (even the implicit ones).  */
52610d565efSmrg 
52710d565efSmrg void
gen_aux_info_record(tree fndecl,int is_definition,int is_implicit,int is_prototyped)52810d565efSmrg gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
52910d565efSmrg 		     int is_prototyped)
53010d565efSmrg {
53110d565efSmrg   if (flag_gen_aux_info)
53210d565efSmrg     {
53310d565efSmrg       static int compiled_from_record = 0;
53410d565efSmrg       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (fndecl));
53510d565efSmrg 
53610d565efSmrg       /* Each output .X file must have a header line.  Write one now if we
53710d565efSmrg 	 have not yet done so.  */
53810d565efSmrg 
53910d565efSmrg       if (!compiled_from_record++)
54010d565efSmrg 	{
54110d565efSmrg 	  /* The first line tells which directory file names are relative to.
54210d565efSmrg 	     Currently, -aux-info works only for files in the working
54310d565efSmrg 	     directory, so just use a `.' as a placeholder for now.  */
54410d565efSmrg 	  fprintf (aux_info_file, "/* compiled from: . */\n");
54510d565efSmrg 	}
54610d565efSmrg 
54710d565efSmrg       /* Write the actual line of auxiliary info.  */
54810d565efSmrg 
54910d565efSmrg       fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
55010d565efSmrg 	       xloc.file, xloc.line,
55110d565efSmrg 	       (is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O',
55210d565efSmrg 	       (is_definition) ? 'F' : 'C',
55310d565efSmrg 	       gen_decl (fndecl, is_definition, ansi));
55410d565efSmrg 
55510d565efSmrg       /* If this is an explicit function declaration, we need to also write
55610d565efSmrg 	 out an old-style (i.e. K&R) function header, just in case the user
55710d565efSmrg 	 wants to run unprotoize.  */
55810d565efSmrg 
55910d565efSmrg       if (is_definition)
56010d565efSmrg 	{
56110d565efSmrg 	  fprintf (aux_info_file, " /*%s %s*/",
56210d565efSmrg 		   gen_formal_list_for_func_def (fndecl, k_and_r_names),
56310d565efSmrg 		   gen_formal_list_for_func_def (fndecl, k_and_r_decls));
56410d565efSmrg 	}
56510d565efSmrg 
56610d565efSmrg       fprintf (aux_info_file, "\n");
56710d565efSmrg     }
56810d565efSmrg }
569