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