OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [c-aux-info.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.