1 |
280 |
jeremybenn |
/* Generate information regarding function declarations and definitions based
|
2 |
|
|
on information stored in GCC's tree structure. This code implements the
|
3 |
|
|
-aux-info option.
|
4 |
|
|
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
|
5 |
|
|
1999, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
|
6 |
|
|
Contributed by Ron Guilmette (rfg@segfault.us.com).
|
7 |
|
|
|
8 |
|
|
This file is part of GCC.
|
9 |
|
|
|
10 |
|
|
GCC is free software; you can redistribute it and/or modify it under
|
11 |
|
|
the terms of the GNU General Public License as published by the Free
|
12 |
|
|
Software Foundation; either version 3, or (at your option) any later
|
13 |
|
|
version.
|
14 |
|
|
|
15 |
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
16 |
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
17 |
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
18 |
|
|
for more details.
|
19 |
|
|
|
20 |
|
|
You should have received a copy of the GNU General Public License
|
21 |
|
|
along with GCC; see the file COPYING3. If not see
|
22 |
|
|
<http://www.gnu.org/licenses/>. */
|
23 |
|
|
|
24 |
|
|
#include "config.h"
|
25 |
|
|
#include "system.h"
|
26 |
|
|
#include "coretypes.h"
|
27 |
|
|
#include "tm.h"
|
28 |
|
|
#include "flags.h"
|
29 |
|
|
#include "tree.h"
|
30 |
|
|
#include "c-tree.h"
|
31 |
|
|
#include "toplev.h"
|
32 |
|
|
|
33 |
|
|
enum formals_style_enum {
|
34 |
|
|
ansi,
|
35 |
|
|
k_and_r_names,
|
36 |
|
|
k_and_r_decls
|
37 |
|
|
};
|
38 |
|
|
typedef enum formals_style_enum formals_style;
|
39 |
|
|
|
40 |
|
|
|
41 |
|
|
static const char *data_type;
|
42 |
|
|
|
43 |
|
|
static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
|
44 |
|
|
static const char *gen_formal_list_for_type (tree, formals_style);
|
45 |
|
|
static int deserves_ellipsis (tree);
|
46 |
|
|
static const char *gen_formal_list_for_func_def (tree, formals_style);
|
47 |
|
|
static const char *gen_type (const char *, tree, formals_style);
|
48 |
|
|
static const char *gen_decl (tree, int, formals_style);
|
49 |
|
|
|
50 |
|
|
/* Given a string representing an entire type or an entire declaration
|
51 |
|
|
which only lacks the actual "data-type" specifier (at its left end),
|
52 |
|
|
affix the data-type specifier to the left end of the given type
|
53 |
|
|
specification or object declaration.
|
54 |
|
|
|
55 |
|
|
Because of C language weirdness, the data-type specifier (which normally
|
56 |
|
|
goes in at the very left end) may have to be slipped in just to the
|
57 |
|
|
right of any leading "const" or "volatile" qualifiers (there may be more
|
58 |
|
|
than one). Actually this may not be strictly necessary because it seems
|
59 |
|
|
that GCC (at least) accepts `<data-type> const foo;' and treats it the
|
60 |
|
|
same as `const <data-type> foo;' but people are accustomed to seeing
|
61 |
|
|
`const char *foo;' and *not* `char const *foo;' so we try to create types
|
62 |
|
|
that look as expected. */
|
63 |
|
|
|
64 |
|
|
static char *
|
65 |
|
|
affix_data_type (const char *param)
|
66 |
|
|
{
|
67 |
|
|
char *const type_or_decl = ASTRDUP (param);
|
68 |
|
|
char *p = type_or_decl;
|
69 |
|
|
char *qualifiers_then_data_type;
|
70 |
|
|
char saved;
|
71 |
|
|
|
72 |
|
|
/* Skip as many leading const's or volatile's as there are. */
|
73 |
|
|
|
74 |
|
|
for (;;)
|
75 |
|
|
{
|
76 |
|
|
if (!strncmp (p, "volatile ", 9))
|
77 |
|
|
{
|
78 |
|
|
p += 9;
|
79 |
|
|
continue;
|
80 |
|
|
}
|
81 |
|
|
if (!strncmp (p, "const ", 6))
|
82 |
|
|
{
|
83 |
|
|
p += 6;
|
84 |
|
|
continue;
|
85 |
|
|
}
|
86 |
|
|
break;
|
87 |
|
|
}
|
88 |
|
|
|
89 |
|
|
/* p now points to the place where we can insert the data type. We have to
|
90 |
|
|
add a blank after the data-type of course. */
|
91 |
|
|
|
92 |
|
|
if (p == type_or_decl)
|
93 |
|
|
return concat (data_type, " ", type_or_decl, NULL);
|
94 |
|
|
|
95 |
|
|
saved = *p;
|
96 |
|
|
*p = '\0';
|
97 |
|
|
qualifiers_then_data_type = concat (type_or_decl, data_type, NULL);
|
98 |
|
|
*p = saved;
|
99 |
|
|
return reconcat (qualifiers_then_data_type,
|
100 |
|
|
qualifiers_then_data_type, " ", p, NULL);
|
101 |
|
|
}
|
102 |
|
|
|
103 |
|
|
/* Given a tree node which represents some "function type", generate the
|
104 |
|
|
source code version of a formal parameter list (of some given style) for
|
105 |
|
|
this function type. Return the whole formal parameter list (including
|
106 |
|
|
a pair of surrounding parens) as a string. Note that if the style
|
107 |
|
|
we are currently aiming for is non-ansi, then we just return a pair
|
108 |
|
|
of empty parens here. */
|
109 |
|
|
|
110 |
|
|
static const char *
|
111 |
|
|
gen_formal_list_for_type (tree fntype, formals_style style)
|
112 |
|
|
{
|
113 |
|
|
const char *formal_list = "";
|
114 |
|
|
tree formal_type;
|
115 |
|
|
|
116 |
|
|
if (style != ansi)
|
117 |
|
|
return "()";
|
118 |
|
|
|
119 |
|
|
formal_type = TYPE_ARG_TYPES (fntype);
|
120 |
|
|
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
|
121 |
|
|
{
|
122 |
|
|
const char *this_type;
|
123 |
|
|
|
124 |
|
|
if (*formal_list)
|
125 |
|
|
formal_list = concat (formal_list, ", ", NULL);
|
126 |
|
|
|
127 |
|
|
this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
|
128 |
|
|
formal_list
|
129 |
|
|
= ((strlen (this_type))
|
130 |
|
|
? concat (formal_list, affix_data_type (this_type), NULL)
|
131 |
|
|
: concat (formal_list, data_type, NULL));
|
132 |
|
|
|
133 |
|
|
formal_type = TREE_CHAIN (formal_type);
|
134 |
|
|
}
|
135 |
|
|
|
136 |
|
|
/* If we got to here, then we are trying to generate an ANSI style formal
|
137 |
|
|
parameters list.
|
138 |
|
|
|
139 |
|
|
New style prototyped ANSI formal parameter lists should in theory always
|
140 |
|
|
contain some stuff between the opening and closing parens, even if it is
|
141 |
|
|
only "void".
|
142 |
|
|
|
143 |
|
|
The brutal truth though is that there is lots of old K&R code out there
|
144 |
|
|
which contains declarations of "pointer-to-function" parameters and
|
145 |
|
|
these almost never have fully specified formal parameter lists associated
|
146 |
|
|
with them. That is, the pointer-to-function parameters are declared
|
147 |
|
|
with just empty parameter lists.
|
148 |
|
|
|
149 |
|
|
In cases such as these, protoize should really insert *something* into
|
150 |
|
|
the vacant parameter lists, but what? It has no basis on which to insert
|
151 |
|
|
anything in particular.
|
152 |
|
|
|
153 |
|
|
Here, we make life easy for protoize by trying to distinguish between
|
154 |
|
|
K&R empty parameter lists and new-style prototyped parameter lists
|
155 |
|
|
that actually contain "void". In the latter case we (obviously) want
|
156 |
|
|
to output the "void" verbatim, and that what we do. In the former case,
|
157 |
|
|
we do our best to give protoize something nice to insert.
|
158 |
|
|
|
159 |
|
|
This "something nice" should be something that is still valid (when
|
160 |
|
|
re-compiled) but something that can clearly indicate to the user that
|
161 |
|
|
more typing information (for the parameter list) should be added (by
|
162 |
|
|
hand) at some convenient moment.
|
163 |
|
|
|
164 |
|
|
The string chosen here is a comment with question marks in it. */
|
165 |
|
|
|
166 |
|
|
if (!*formal_list)
|
167 |
|
|
{
|
168 |
|
|
if (TYPE_ARG_TYPES (fntype))
|
169 |
|
|
/* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */
|
170 |
|
|
formal_list = "void";
|
171 |
|
|
else
|
172 |
|
|
formal_list = "/* ??? */";
|
173 |
|
|
}
|
174 |
|
|
else
|
175 |
|
|
{
|
176 |
|
|
/* If there were at least some parameters, and if the formals-types-list
|
177 |
|
|
petered out to a NULL (i.e. without being terminated by a
|
178 |
|
|
void_type_node) then we need to tack on an ellipsis. */
|
179 |
|
|
if (!formal_type)
|
180 |
|
|
formal_list = concat (formal_list, ", ...", NULL);
|
181 |
|
|
}
|
182 |
|
|
|
183 |
|
|
return concat (" (", formal_list, ")", NULL);
|
184 |
|
|
}
|
185 |
|
|
|
186 |
|
|
/* For the generation of an ANSI prototype for a function definition, we have
|
187 |
|
|
to look at the formal parameter list of the function's own "type" to
|
188 |
|
|
determine if the function's formal parameter list should end with an
|
189 |
|
|
ellipsis. Given a tree node, the following function will return nonzero
|
190 |
|
|
if the "function type" parameter list should end with an ellipsis. */
|
191 |
|
|
|
192 |
|
|
static int
|
193 |
|
|
deserves_ellipsis (tree fntype)
|
194 |
|
|
{
|
195 |
|
|
tree formal_type;
|
196 |
|
|
|
197 |
|
|
formal_type = TYPE_ARG_TYPES (fntype);
|
198 |
|
|
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
|
199 |
|
|
formal_type = TREE_CHAIN (formal_type);
|
200 |
|
|
|
201 |
|
|
/* If there were at least some parameters, and if the formals-types-list
|
202 |
|
|
petered out to a NULL (i.e. without being terminated by a void_type_node)
|
203 |
|
|
then we need to tack on an ellipsis. */
|
204 |
|
|
|
205 |
|
|
return (!formal_type && TYPE_ARG_TYPES (fntype));
|
206 |
|
|
}
|
207 |
|
|
|
208 |
|
|
/* Generate a parameter list for a function definition (in some given style).
|
209 |
|
|
|
210 |
|
|
Note that this routine has to be separate (and different) from the code that
|
211 |
|
|
generates the prototype parameter lists for function declarations, because
|
212 |
|
|
in the case of a function declaration, all we have to go on is a tree node
|
213 |
|
|
representing the function's own "function type". This can tell us the types
|
214 |
|
|
of all of the formal parameters for the function, but it cannot tell us the
|
215 |
|
|
actual *names* of each of the formal parameters. We need to output those
|
216 |
|
|
parameter names for each function definition.
|
217 |
|
|
|
218 |
|
|
This routine gets a pointer to a tree node which represents the actual
|
219 |
|
|
declaration of the given function, and this DECL node has a list of formal
|
220 |
|
|
parameter (variable) declarations attached to it. These formal parameter
|
221 |
|
|
(variable) declaration nodes give us the actual names of the formal
|
222 |
|
|
parameters for the given function definition.
|
223 |
|
|
|
224 |
|
|
This routine returns a string which is the source form for the entire
|
225 |
|
|
function formal parameter list. */
|
226 |
|
|
|
227 |
|
|
static const char *
|
228 |
|
|
gen_formal_list_for_func_def (tree fndecl, formals_style style)
|
229 |
|
|
{
|
230 |
|
|
const char *formal_list = "";
|
231 |
|
|
tree formal_decl;
|
232 |
|
|
|
233 |
|
|
formal_decl = DECL_ARGUMENTS (fndecl);
|
234 |
|
|
while (formal_decl)
|
235 |
|
|
{
|
236 |
|
|
const char *this_formal;
|
237 |
|
|
|
238 |
|
|
if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
|
239 |
|
|
formal_list = concat (formal_list, ", ", NULL);
|
240 |
|
|
this_formal = gen_decl (formal_decl, 0, style);
|
241 |
|
|
if (style == k_and_r_decls)
|
242 |
|
|
formal_list = concat (formal_list, this_formal, "; ", NULL);
|
243 |
|
|
else
|
244 |
|
|
formal_list = concat (formal_list, this_formal, NULL);
|
245 |
|
|
formal_decl = TREE_CHAIN (formal_decl);
|
246 |
|
|
}
|
247 |
|
|
if (style == ansi)
|
248 |
|
|
{
|
249 |
|
|
if (!DECL_ARGUMENTS (fndecl))
|
250 |
|
|
formal_list = concat (formal_list, "void", NULL);
|
251 |
|
|
if (deserves_ellipsis (TREE_TYPE (fndecl)))
|
252 |
|
|
formal_list = concat (formal_list, ", ...", NULL);
|
253 |
|
|
}
|
254 |
|
|
if ((style == ansi) || (style == k_and_r_names))
|
255 |
|
|
formal_list = concat (" (", formal_list, ")", NULL);
|
256 |
|
|
return formal_list;
|
257 |
|
|
}
|
258 |
|
|
|
259 |
|
|
/* Generate a string which is the source code form for a given type (t). This
|
260 |
|
|
routine is ugly and complex because the C syntax for declarations is ugly
|
261 |
|
|
and complex. This routine is straightforward so long as *no* pointer types,
|
262 |
|
|
array types, or function types are involved.
|
263 |
|
|
|
264 |
|
|
In the simple cases, this routine will return the (string) value which was
|
265 |
|
|
passed in as the "ret_val" argument. Usually, this starts out either as an
|
266 |
|
|
empty string, or as the name of the declared item (i.e. the formal function
|
267 |
|
|
parameter variable).
|
268 |
|
|
|
269 |
|
|
This routine will also return with the global variable "data_type" set to
|
270 |
|
|
some string value which is the "basic" data-type of the given complete type.
|
271 |
|
|
This "data_type" string can be concatenated onto the front of the returned
|
272 |
|
|
string after this routine returns to its caller.
|
273 |
|
|
|
274 |
|
|
In complicated cases involving pointer types, array types, or function
|
275 |
|
|
types, the C declaration syntax requires an "inside out" approach, i.e. if
|
276 |
|
|
you have a type which is a "pointer-to-function" type, you need to handle
|
277 |
|
|
the "pointer" part first, but it also has to be "innermost" (relative to
|
278 |
|
|
the declaration stuff for the "function" type). Thus, is this case, you
|
279 |
|
|
must prepend a "(*" and append a ")" to the name of the item (i.e. formal
|
280 |
|
|
variable). Then you must append and prepend the other info for the
|
281 |
|
|
"function type" part of the overall type.
|
282 |
|
|
|
283 |
|
|
To handle the "innermost precedence" rules of complicated C declarators, we
|
284 |
|
|
do the following (in this routine). The input parameter called "ret_val"
|
285 |
|
|
is treated as a "seed". Each time gen_type is called (perhaps recursively)
|
286 |
|
|
some additional strings may be appended or prepended (or both) to the "seed"
|
287 |
|
|
string. If yet another (lower) level of the GCC tree exists for the given
|
288 |
|
|
type (as in the case of a pointer type, an array type, or a function type)
|
289 |
|
|
then the (wrapped) seed is passed to a (recursive) invocation of gen_type()
|
290 |
|
|
this recursive invocation may again "wrap" the (new) seed with yet more
|
291 |
|
|
declarator stuff, by appending, prepending (or both). By the time the
|
292 |
|
|
recursion bottoms out, the "seed value" at that point will have a value
|
293 |
|
|
which is (almost) the complete source version of the declarator (except
|
294 |
|
|
for the data_type info). Thus, this deepest "seed" value is simply passed
|
295 |
|
|
back up through all of the recursive calls until it is given (as the return
|
296 |
|
|
value) to the initial caller of the gen_type() routine. All that remains
|
297 |
|
|
to do at this point is for the initial caller to prepend the "data_type"
|
298 |
|
|
string onto the returned "seed". */
|
299 |
|
|
|
300 |
|
|
static const char *
|
301 |
|
|
gen_type (const char *ret_val, tree t, formals_style style)
|
302 |
|
|
{
|
303 |
|
|
tree chain_p;
|
304 |
|
|
|
305 |
|
|
/* If there is a typedef name for this type, use it. */
|
306 |
|
|
if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
|
307 |
|
|
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
308 |
|
|
else
|
309 |
|
|
{
|
310 |
|
|
switch (TREE_CODE (t))
|
311 |
|
|
{
|
312 |
|
|
case POINTER_TYPE:
|
313 |
|
|
if (TYPE_READONLY (t))
|
314 |
|
|
ret_val = concat ("const ", ret_val, NULL);
|
315 |
|
|
if (TYPE_VOLATILE (t))
|
316 |
|
|
ret_val = concat ("volatile ", ret_val, NULL);
|
317 |
|
|
|
318 |
|
|
ret_val = concat ("*", ret_val, NULL);
|
319 |
|
|
|
320 |
|
|
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|
321 |
|
|
ret_val = concat ("(", ret_val, ")", NULL);
|
322 |
|
|
|
323 |
|
|
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
|
324 |
|
|
|
325 |
|
|
return ret_val;
|
326 |
|
|
|
327 |
|
|
case ARRAY_TYPE:
|
328 |
|
|
if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
|
329 |
|
|
ret_val = gen_type (concat (ret_val, "[]", NULL),
|
330 |
|
|
TREE_TYPE (t), style);
|
331 |
|
|
else if (int_size_in_bytes (t) == 0)
|
332 |
|
|
ret_val = gen_type (concat (ret_val, "[0]", NULL),
|
333 |
|
|
TREE_TYPE (t), style);
|
334 |
|
|
else
|
335 |
|
|
{
|
336 |
|
|
int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t)));
|
337 |
|
|
char buff[10];
|
338 |
|
|
sprintf (buff, "[%d]", size);
|
339 |
|
|
ret_val = gen_type (concat (ret_val, buff, NULL),
|
340 |
|
|
TREE_TYPE (t), style);
|
341 |
|
|
}
|
342 |
|
|
break;
|
343 |
|
|
|
344 |
|
|
case FUNCTION_TYPE:
|
345 |
|
|
ret_val = gen_type (concat (ret_val,
|
346 |
|
|
gen_formal_list_for_type (t, style),
|
347 |
|
|
NULL),
|
348 |
|
|
TREE_TYPE (t), style);
|
349 |
|
|
break;
|
350 |
|
|
|
351 |
|
|
case IDENTIFIER_NODE:
|
352 |
|
|
data_type = IDENTIFIER_POINTER (t);
|
353 |
|
|
break;
|
354 |
|
|
|
355 |
|
|
/* The following three cases are complicated by the fact that a
|
356 |
|
|
user may do something really stupid, like creating a brand new
|
357 |
|
|
"anonymous" type specification in a formal argument list (or as
|
358 |
|
|
part of a function return type specification). For example:
|
359 |
|
|
|
360 |
|
|
int f (enum { red, green, blue } color);
|
361 |
|
|
|
362 |
|
|
In such cases, we have no name that we can put into the prototype
|
363 |
|
|
to represent the (anonymous) type. Thus, we have to generate the
|
364 |
|
|
whole darn type specification. Yuck! */
|
365 |
|
|
|
366 |
|
|
case RECORD_TYPE:
|
367 |
|
|
if (TYPE_NAME (t))
|
368 |
|
|
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
369 |
|
|
else
|
370 |
|
|
{
|
371 |
|
|
data_type = "";
|
372 |
|
|
chain_p = TYPE_FIELDS (t);
|
373 |
|
|
while (chain_p)
|
374 |
|
|
{
|
375 |
|
|
data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
|
376 |
|
|
NULL);
|
377 |
|
|
chain_p = TREE_CHAIN (chain_p);
|
378 |
|
|
data_type = concat (data_type, "; ", NULL);
|
379 |
|
|
}
|
380 |
|
|
data_type = concat ("{ ", data_type, "}", NULL);
|
381 |
|
|
}
|
382 |
|
|
data_type = concat ("struct ", data_type, NULL);
|
383 |
|
|
break;
|
384 |
|
|
|
385 |
|
|
case UNION_TYPE:
|
386 |
|
|
if (TYPE_NAME (t))
|
387 |
|
|
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
388 |
|
|
else
|
389 |
|
|
{
|
390 |
|
|
data_type = "";
|
391 |
|
|
chain_p = TYPE_FIELDS (t);
|
392 |
|
|
while (chain_p)
|
393 |
|
|
{
|
394 |
|
|
data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
|
395 |
|
|
NULL);
|
396 |
|
|
chain_p = TREE_CHAIN (chain_p);
|
397 |
|
|
data_type = concat (data_type, "; ", NULL);
|
398 |
|
|
}
|
399 |
|
|
data_type = concat ("{ ", data_type, "}", NULL);
|
400 |
|
|
}
|
401 |
|
|
data_type = concat ("union ", data_type, NULL);
|
402 |
|
|
break;
|
403 |
|
|
|
404 |
|
|
case ENUMERAL_TYPE:
|
405 |
|
|
if (TYPE_NAME (t))
|
406 |
|
|
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
407 |
|
|
else
|
408 |
|
|
{
|
409 |
|
|
data_type = "";
|
410 |
|
|
chain_p = TYPE_VALUES (t);
|
411 |
|
|
while (chain_p)
|
412 |
|
|
{
|
413 |
|
|
data_type = concat (data_type,
|
414 |
|
|
IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL);
|
415 |
|
|
chain_p = TREE_CHAIN (chain_p);
|
416 |
|
|
if (chain_p)
|
417 |
|
|
data_type = concat (data_type, ", ", NULL);
|
418 |
|
|
}
|
419 |
|
|
data_type = concat ("{ ", data_type, " }", NULL);
|
420 |
|
|
}
|
421 |
|
|
data_type = concat ("enum ", data_type, NULL);
|
422 |
|
|
break;
|
423 |
|
|
|
424 |
|
|
case TYPE_DECL:
|
425 |
|
|
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
|
426 |
|
|
break;
|
427 |
|
|
|
428 |
|
|
case INTEGER_TYPE:
|
429 |
|
|
case FIXED_POINT_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 (TYPE_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 |
|
|
gcc_unreachable ();
|
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 |
|
|
|
472 |
|
|
static const char *
|
473 |
|
|
gen_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 && C_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 |
|
|
|
544 |
|
|
extern 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 |
|
|
|
550 |
|
|
void
|
551 |
|
|
gen_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 |
|
|
expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (fndecl));
|
558 |
|
|
|
559 |
|
|
/* Each output .X file must have a header line. Write one now if we
|
560 |
|
|
have not yet done so. */
|
561 |
|
|
|
562 |
|
|
if (!compiled_from_record++)
|
563 |
|
|
{
|
564 |
|
|
/* The first line tells which directory file names are relative to.
|
565 |
|
|
Currently, -aux-info works only for files in the working
|
566 |
|
|
directory, so just use a `.' as a placeholder for now. */
|
567 |
|
|
fprintf (aux_info_file, "/* compiled from: . */\n");
|
568 |
|
|
}
|
569 |
|
|
|
570 |
|
|
/* Write the actual line of auxiliary info. */
|
571 |
|
|
|
572 |
|
|
fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
|
573 |
|
|
xloc.file, xloc.line,
|
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 |
|
|
}
|