Annotation of gcc/c-aux-info.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.