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