Annotation of GNUtools/cc/tree.c, revision 1.1

1.1     ! root        1: /* Language-independent node constructors for parse phase of GNU compiler.
        !             2:    Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: 
        !            21: /* This file contains the low level primitives for operating on tree nodes,
        !            22:    including allocation, list operations, interning of identifiers,
        !            23:    construction of data type nodes and statement nodes,
        !            24:    and construction of type conversion nodes.  It also contains
        !            25:    tables index by tree code that describe how to take apart
        !            26:    nodes of that code.
        !            27: 
        !            28:    It is intended to be language-independent, but occasionally
        !            29:    calls language-dependent routines defined (for C) in typecheck.c.
        !            30: 
        !            31:    The low-level allocation routines oballoc and permalloc
        !            32:    are used also for allocating many other kinds of objects
        !            33:    by all passes of the compiler.  */
        !            34: 
        !            35: #include "config.h"
        !            36: #include "flags.h"
        !            37: #include "tree.h"
        !            38: #include "objc-act.h"
        !            39: #include "function.h"
        !            40: #include "obstack.h"
        !            41: #include "gvarargs.h"
        !            42: #include <stdio.h>
        !            43: 
        !            44: #define obstack_chunk_alloc xmalloc
        !            45: #define obstack_chunk_free free
        !            46: 
        !            47: /* Tree nodes of permanent duration are allocated in this obstack.
        !            48:    They are the identifier nodes, and everything outside of
        !            49:    the bodies and parameters of function definitions.  */
        !            50: 
        !            51: struct obstack permanent_obstack;
        !            52: 
        !            53: /* The initial RTL, and all ..._TYPE nodes, in a function
        !            54:    are allocated in this obstack.  Usually they are freed at the
        !            55:    end of the function, but if the function is inline they are saved.
        !            56:    For top-level functions, this is maybepermanent_obstack.
        !            57:    Separate obstacks are made for nested functions.  */
        !            58: 
        !            59: struct obstack *function_maybepermanent_obstack;
        !            60: 
        !            61: /* This is the function_maybepermanent_obstack for top-level functions.  */
        !            62: 
        !            63: struct obstack maybepermanent_obstack;
        !            64: 
        !            65: /* The contents of the current function definition are allocated
        !            66:    in this obstack, and all are freed at the end of the function.
        !            67:    For top-level functions, this is temporary_obstack.
        !            68:    Separate obstacks are made for nested functions.  */
        !            69: 
        !            70: struct obstack *function_obstack;
        !            71: 
        !            72: /* This is used for reading initializers of global variables.  */
        !            73: 
        !            74: struct obstack temporary_obstack;
        !            75: 
        !            76: /* The tree nodes of an expression are allocated
        !            77:    in this obstack, and all are freed at the end of the expression.  */
        !            78: 
        !            79: struct obstack momentary_obstack;
        !            80: 
        !            81: /* The tree nodes of a declarator are allocated
        !            82:    in this obstack, and all are freed when the declarator
        !            83:    has been parsed.  */
        !            84: 
        !            85: static struct obstack temp_decl_obstack;
        !            86: 
        !            87: /* This points at either permanent_obstack
        !            88:    or the current function_maybepermanent_obstack.  */
        !            89: 
        !            90: struct obstack *saveable_obstack;
        !            91: 
        !            92: /* This is same as saveable_obstack during parse and expansion phase;
        !            93:    it points to the current function's obstack during optimization.
        !            94:    This is the obstack to be used for creating rtl objects.  */
        !            95: 
        !            96: struct obstack *rtl_obstack;
        !            97: 
        !            98: /* This points at either permanent_obstack or the current function_obstack.  */
        !            99: 
        !           100: struct obstack *current_obstack;
        !           101: 
        !           102: /* This points at either permanent_obstack or the current function_obstack
        !           103:    or momentary_obstack.  */
        !           104: 
        !           105: struct obstack *expression_obstack;
        !           106: 
        !           107: /* Stack of obstack selections for push_obstacks and pop_obstacks.  */
        !           108: 
        !           109: struct obstack_stack
        !           110: {
        !           111:   struct obstack_stack *next;
        !           112:   struct obstack *current;
        !           113:   struct obstack *saveable;
        !           114:   struct obstack *expression;
        !           115:   struct obstack *rtl;
        !           116: };
        !           117: 
        !           118: struct obstack_stack *obstack_stack;
        !           119: 
        !           120: /* Obstack for allocating struct obstack_stack entries.  */
        !           121: 
        !           122: static struct obstack obstack_stack_obstack;
        !           123: 
        !           124: /* Addresses of first objects in some obstacks.
        !           125:    This is for freeing their entire contents.  */
        !           126: char *maybepermanent_firstobj;
        !           127: char *temporary_firstobj;
        !           128: char *momentary_firstobj;
        !           129: char *temp_decl_firstobj;
        !           130: 
        !           131: /* Nonzero means all ..._TYPE nodes should be allocated permanently.  */
        !           132: 
        !           133: int all_types_permanent;
        !           134: 
        !           135: /* Stack of places to restore the momentary obstack back to.  */
        !           136:    
        !           137: struct momentary_level
        !           138: {
        !           139:   /* Pointer back to previous such level.  */
        !           140:   struct momentary_level *prev;
        !           141:   /* First object allocated within this level.  */
        !           142:   char *base;
        !           143:   /* Value of expression_obstack saved at entry to this level.  */
        !           144:   struct obstack *obstack;
        !           145: };
        !           146: 
        !           147: struct momentary_level *momentary_stack;
        !           148: 
        !           149: /* Table indexed by tree code giving a string containing a character
        !           150:    classifying the tree code.  Possibilities are
        !           151:    t, d, s, c, r, <, 1, 2 and e.  See tree.def for details.  */
        !           152: 
        !           153: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
        !           154: 
        !           155: char *standard_tree_code_type[] = {
        !           156: #include "tree.def"
        !           157: };
        !           158: #undef DEFTREECODE
        !           159: 
        !           160: /* Table indexed by tree code giving number of expression
        !           161:    operands beyond the fixed part of the node structure.
        !           162:    Not used for types or decls.  */
        !           163: 
        !           164: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
        !           165: 
        !           166: int standard_tree_code_length[] = {
        !           167: #include "tree.def"
        !           168: };
        !           169: #undef DEFTREECODE
        !           170: 
        !           171: /* Names of tree components.
        !           172:    Used for printing out the tree and error messages.  */
        !           173: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
        !           174: 
        !           175: char *standard_tree_code_name[] = {
        !           176: #include "tree.def"
        !           177: };
        !           178: #undef DEFTREECODE
        !           179: 
        !           180: /* Table indexed by tree code giving a string containing a character
        !           181:    classifying the tree code.  Possibilities are
        !           182:    t, d, s, c, r, e, <, 1 and 2.  See tree.def for details.  */
        !           183: 
        !           184: char **tree_code_type;
        !           185: 
        !           186: /* Table indexed by tree code giving number of expression
        !           187:    operands beyond the fixed part of the node structure.
        !           188:    Not used for types or decls.  */
        !           189: 
        !           190: int *tree_code_length;
        !           191: 
        !           192: /* Table indexed by tree code giving name of tree code, as a string.  */
        !           193: 
        !           194: char **tree_code_name;
        !           195: 
        !           196: /* Statistics-gathering stuff.  */
        !           197: typedef enum
        !           198: {
        !           199:   d_kind,
        !           200:   t_kind,
        !           201:   b_kind,
        !           202:   s_kind,
        !           203:   r_kind,
        !           204:   e_kind,
        !           205:   c_kind,
        !           206:   id_kind,
        !           207:   op_id_kind,
        !           208:   perm_list_kind,
        !           209:   temp_list_kind,
        !           210:   vec_kind,
        !           211:   x_kind,
        !           212:   lang_decl,
        !           213:   lang_type,
        !           214:   all_kinds
        !           215: } tree_node_kind;
        !           216: 
        !           217: int tree_node_counts[(int)all_kinds];
        !           218: int tree_node_sizes[(int)all_kinds];
        !           219: int id_string_size = 0;
        !           220: 
        !           221: char *tree_node_kind_names[] = {
        !           222:   "decls",
        !           223:   "types",
        !           224:   "blocks",
        !           225:   "stmts",
        !           226:   "refs",
        !           227:   "exprs",
        !           228:   "constants",
        !           229:   "identifiers",
        !           230:   "op_identifiers",
        !           231:   "perm_tree_lists",
        !           232:   "temp_tree_lists",
        !           233:   "vecs",
        !           234:   "random kinds",
        !           235:   "lang_decl kinds",
        !           236:   "lang_type kinds"
        !           237: };
        !           238: 
        !           239: /* Hash table for uniquizing IDENTIFIER_NODEs by name.  */
        !           240: 
        !           241: #define MAX_HASH_TABLE 1009
        !           242: static tree hash_table[MAX_HASH_TABLE];        /* id hash buckets */
        !           243: 
        !           244: /* 0 while creating built-in identifiers.  */
        !           245: static int do_identifier_warnings;
        !           246: 
        !           247: /* Unique id for next decl created.  */
        !           248: static int next_decl_uid;
        !           249: /* Unique id for next type created.  */
        !           250: static int next_type_uid = 1;
        !           251: 
        !           252: extern char *mode_name[];
        !           253: 
        !           254: #ifdef NEXT_SEMANTICS
        !           255: extern short *reg_renumber;
        !           256: #endif
        !           257: 
        !           258: void gcc_obstack_init ();
        !           259: static tree stabilize_reference_1 ();
        !           260: 
        !           261: /* Init the principal obstacks.  */
        !           262: 
        !           263: void
        !           264: init_obstacks ()
        !           265: {
        !           266:   gcc_obstack_init (&obstack_stack_obstack);
        !           267:   gcc_obstack_init (&permanent_obstack);
        !           268: 
        !           269:   gcc_obstack_init (&temporary_obstack);
        !           270:   temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
        !           271:   gcc_obstack_init (&momentary_obstack);
        !           272:   momentary_firstobj = (char *) obstack_alloc (&momentary_obstack, 0);
        !           273:   gcc_obstack_init (&maybepermanent_obstack);
        !           274:   maybepermanent_firstobj
        !           275:     = (char *) obstack_alloc (&maybepermanent_obstack, 0);
        !           276:   gcc_obstack_init (&temp_decl_obstack);
        !           277:   temp_decl_firstobj = (char *) obstack_alloc (&temp_decl_obstack, 0);
        !           278: 
        !           279:   function_obstack = &temporary_obstack;
        !           280:   function_maybepermanent_obstack = &maybepermanent_obstack;
        !           281:   current_obstack = &permanent_obstack;
        !           282:   expression_obstack = &permanent_obstack;
        !           283:   rtl_obstack = saveable_obstack = &permanent_obstack;
        !           284: 
        !           285:   /* Init the hash table of identifiers.  */
        !           286:   bzero (hash_table, sizeof hash_table);
        !           287: }
        !           288: 
        !           289: void
        !           290: gcc_obstack_init (obstack)
        !           291:      struct obstack *obstack;
        !           292: {
        !           293:   /* Let particular systems override the size of a chunk.  */
        !           294: #ifndef OBSTACK_CHUNK_SIZE
        !           295: #define OBSTACK_CHUNK_SIZE 0
        !           296: #endif
        !           297:   /* Let them override the alloc and free routines too.  */
        !           298: #ifndef OBSTACK_CHUNK_ALLOC
        !           299: #define OBSTACK_CHUNK_ALLOC xmalloc
        !           300: #endif
        !           301: #ifndef OBSTACK_CHUNK_FREE
        !           302: #define OBSTACK_CHUNK_FREE free
        !           303: #endif
        !           304:   _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,
        !           305:                  (void *(*) ()) OBSTACK_CHUNK_ALLOC,
        !           306:                  (void (*) ()) OBSTACK_CHUNK_FREE);
        !           307: }
        !           308: 
        !           309: /* Save all variables describing the current status into the structure *P.
        !           310:    This is used before starting a nested function.  */
        !           311: 
        !           312: void
        !           313: save_tree_status (p)
        !           314:      struct function *p;
        !           315: {
        !           316:   p->all_types_permanent = all_types_permanent;
        !           317:   p->momentary_stack = momentary_stack;
        !           318:   p->maybepermanent_firstobj = maybepermanent_firstobj;
        !           319:   p->momentary_firstobj = momentary_firstobj;
        !           320:   p->function_obstack = function_obstack;
        !           321:   p->function_maybepermanent_obstack = function_maybepermanent_obstack;
        !           322:   p->current_obstack = current_obstack;
        !           323:   p->expression_obstack = expression_obstack;
        !           324:   p->saveable_obstack = saveable_obstack;
        !           325:   p->rtl_obstack = rtl_obstack;
        !           326: 
        !           327:   /* Objects that need to be saved in this function can be in the nonsaved
        !           328:      obstack of the enclosing function since they can't possibly be needed
        !           329:      once it has returned.  */
        !           330:   function_maybepermanent_obstack = function_obstack;
        !           331: 
        !           332:   function_obstack = (struct obstack *) xmalloc (sizeof (struct obstack));
        !           333:   gcc_obstack_init (function_obstack);
        !           334: 
        !           335:   current_obstack = &permanent_obstack;
        !           336:   expression_obstack = &permanent_obstack;
        !           337:   rtl_obstack = saveable_obstack = &permanent_obstack;
        !           338: 
        !           339:   momentary_firstobj = (char *) obstack_finish (&momentary_obstack);
        !           340:   maybepermanent_firstobj
        !           341:     = (char *) obstack_finish (function_maybepermanent_obstack);
        !           342: }
        !           343: 
        !           344: /* Restore all variables describing the current status from the structure *P.
        !           345:    This is used after a nested function.  */
        !           346: 
        !           347: void
        !           348: restore_tree_status (p)
        !           349:      struct function *p;
        !           350: {
        !           351:   all_types_permanent = p->all_types_permanent;
        !           352:   momentary_stack = p->momentary_stack;
        !           353: 
        !           354:   obstack_free (&momentary_obstack, momentary_firstobj);
        !           355: 
        !           356:   /* Free saveable storage used by the function just compiled and not
        !           357:      saved.
        !           358: 
        !           359:      CAUTION: This is in function_obstack of the containing function.  So
        !           360:      we must be sure that we never allocate from that obstack during
        !           361:      the compilation of a nested function if we expect it to survive past the
        !           362:      nested function's end.  */
        !           363:   obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj);
        !           364: 
        !           365:   obstack_free (function_obstack, 0);
        !           366:   free (function_obstack);
        !           367: 
        !           368:   momentary_firstobj = p->momentary_firstobj;
        !           369:   maybepermanent_firstobj = p->maybepermanent_firstobj;
        !           370:   function_obstack = p->function_obstack;
        !           371:   function_maybepermanent_obstack = p->function_maybepermanent_obstack;
        !           372:   current_obstack = p->current_obstack;
        !           373:   expression_obstack = p->expression_obstack;
        !           374:   saveable_obstack = p->saveable_obstack;
        !           375:   rtl_obstack = p->rtl_obstack;
        !           376: }
        !           377: 
        !           378: /* Start allocating on the temporary (per function) obstack.
        !           379:    This is done in start_function before parsing the function body,
        !           380:    and before each initialization at top level, and to go back
        !           381:    to temporary allocation after doing permanent_allocation.  */
        !           382: 
        !           383: void
        !           384: temporary_allocation ()
        !           385: {
        !           386:   /* Note that function_obstack at top level points to temporary_obstack.
        !           387:      But within a nested function context, it is a separate obstack.  */
        !           388:   current_obstack = function_obstack;
        !           389:   expression_obstack = function_obstack;
        !           390:   rtl_obstack = saveable_obstack = function_maybepermanent_obstack;
        !           391:   momentary_stack = 0;
        !           392: }
        !           393: 
        !           394: /* Start allocating on the permanent obstack but don't
        !           395:    free the temporary data.  After calling this, call
        !           396:    `permanent_allocation' to fully resume permanent allocation status.  */
        !           397: 
        !           398: void
        !           399: end_temporary_allocation ()
        !           400: {
        !           401:   current_obstack = &permanent_obstack;
        !           402:   expression_obstack = &permanent_obstack;
        !           403:   rtl_obstack = saveable_obstack = &permanent_obstack;
        !           404: }
        !           405: 
        !           406: /* Resume allocating on the temporary obstack, undoing
        !           407:    effects of `end_temporary_allocation'.  */
        !           408: 
        !           409: void
        !           410: resume_temporary_allocation ()
        !           411: {
        !           412:   current_obstack = function_obstack;
        !           413:   expression_obstack = function_obstack;
        !           414:   rtl_obstack = saveable_obstack = function_maybepermanent_obstack;
        !           415: }
        !           416: 
        !           417: /* While doing temporary allocation, switch to allocating in such a
        !           418:    way as to save all nodes if the function is inlined.  Call
        !           419:    resume_temporary_allocation to go back to ordinary temporary
        !           420:    allocation.  */
        !           421: 
        !           422: void
        !           423: saveable_allocation ()
        !           424: {
        !           425:   /* Note that function_obstack at top level points to temporary_obstack.
        !           426:      But within a nested function context, it is a separate obstack.  */
        !           427:   expression_obstack = current_obstack = saveable_obstack;
        !           428: }
        !           429: 
        !           430: /* Switch to current obstack CURRENT and maybepermanent obstack SAVEABLE,
        !           431:    recording the previously current obstacks on a stack.
        !           432:    This does not free any storage in any obstack.  */
        !           433: 
        !           434: void
        !           435: push_obstacks (current, saveable)
        !           436:      struct obstack *current, *saveable;
        !           437: {
        !           438:   struct obstack_stack *p
        !           439:     = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
        !           440:                                              (sizeof (struct obstack_stack)));
        !           441: 
        !           442:   p->current = current_obstack;
        !           443:   p->saveable = saveable_obstack;
        !           444:   p->expression = expression_obstack;
        !           445:   p->rtl = rtl_obstack;
        !           446:   p->next = obstack_stack;
        !           447:   obstack_stack = p;
        !           448: 
        !           449:   current_obstack = current;
        !           450:   expression_obstack = current;
        !           451:   rtl_obstack = saveable_obstack = saveable;
        !           452: }
        !           453: 
        !           454: /* Save the current set of obstacks, but don't change them.  */
        !           455: 
        !           456: void
        !           457: push_obstacks_nochange ()
        !           458: {
        !           459:   struct obstack_stack *p
        !           460:     = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
        !           461:                                              (sizeof (struct obstack_stack)));
        !           462: 
        !           463:   p->current = current_obstack;
        !           464:   p->saveable = saveable_obstack;
        !           465:   p->expression = expression_obstack;
        !           466:   p->rtl = rtl_obstack;
        !           467:   p->next = obstack_stack;
        !           468:   obstack_stack = p;
        !           469: }
        !           470: 
        !           471: /* Pop the obstack selection stack.  */
        !           472: 
        !           473: void
        !           474: pop_obstacks ()
        !           475: {
        !           476:   struct obstack_stack *p = obstack_stack;
        !           477:   obstack_stack = p->next;
        !           478: 
        !           479:   current_obstack = p->current;
        !           480:   saveable_obstack = p->saveable;
        !           481:   expression_obstack = p->expression;
        !           482:   rtl_obstack = p->rtl;
        !           483: 
        !           484:   obstack_free (&obstack_stack_obstack, p);
        !           485: }
        !           486: 
        !           487: /* Nonzero if temporary allocation is currently in effect.
        !           488:    Zero if currently doing permanent allocation.  */
        !           489: 
        !           490: int
        !           491: allocation_temporary_p ()
        !           492: {
        !           493:   return current_obstack != &permanent_obstack;
        !           494: }
        !           495: 
        !           496: /* Go back to allocating on the permanent obstack
        !           497:    and free everything in the temporary obstack.
        !           498:    This is done in finish_function after fully compiling a function.  */
        !           499: 
        !           500: void
        !           501: permanent_allocation ()
        !           502: {
        !           503:   /* Free up previous temporary obstack data */
        !           504:   obstack_free (&temporary_obstack, temporary_firstobj);
        !           505:   obstack_free (&momentary_obstack, momentary_firstobj);
        !           506:   obstack_free (&maybepermanent_obstack, maybepermanent_firstobj);
        !           507:   obstack_free (&temp_decl_obstack, temp_decl_firstobj);
        !           508: 
        !           509:   current_obstack = &permanent_obstack;
        !           510:   expression_obstack = &permanent_obstack;
        !           511:   rtl_obstack = saveable_obstack = &permanent_obstack;
        !           512: #ifdef NEXT_SEMANTICS
        !           513:   reg_renumber = 0;
        !           514: #endif
        !           515: }
        !           516: 
        !           517: /* Save permanently everything on the maybepermanent_obstack.  */
        !           518: 
        !           519: void
        !           520: preserve_data ()
        !           521: {
        !           522:   maybepermanent_firstobj
        !           523:     = (char *) obstack_alloc (function_maybepermanent_obstack, 0);
        !           524: }
        !           525: 
        !           526: void
        !           527: preserve_initializer ()
        !           528: {
        !           529:   temporary_firstobj
        !           530:     = (char *) obstack_alloc (&temporary_obstack, 0);
        !           531:   momentary_firstobj
        !           532:     = (char *) obstack_alloc (&momentary_obstack, 0);
        !           533:   maybepermanent_firstobj
        !           534:     = (char *) obstack_alloc (function_maybepermanent_obstack, 0);
        !           535: }
        !           536: 
        !           537: /* Start allocating new rtl in current_obstack.
        !           538:    Use resume_temporary_allocation
        !           539:    to go back to allocating rtl in saveable_obstack.  */
        !           540: 
        !           541: void
        !           542: rtl_in_current_obstack ()
        !           543: {
        !           544:   rtl_obstack = current_obstack;
        !           545: }
        !           546: 
        !           547: /* Start allocating rtl from saveable_obstack.  Intended to be used after
        !           548:    a call to push_obstacks_nochange.  */
        !           549: 
        !           550: void
        !           551: rtl_in_saveable_obstack ()
        !           552: {
        !           553:   rtl_obstack = saveable_obstack;
        !           554: }
        !           555: 
        !           556: /* Allocate SIZE bytes in the current obstack
        !           557:    and return a pointer to them.
        !           558:    In practice the current obstack is always the temporary one.  */
        !           559: 
        !           560: char *
        !           561: oballoc (size)
        !           562:      int size;
        !           563: {
        !           564:   return (char *) obstack_alloc (current_obstack, size);
        !           565: }
        !           566: 
        !           567: /* Free the object PTR in the current obstack
        !           568:    as well as everything allocated since PTR.
        !           569:    In practice the current obstack is always the temporary one.  */
        !           570: 
        !           571: void
        !           572: obfree (ptr)
        !           573:      char *ptr;
        !           574: {
        !           575:   obstack_free (current_obstack, ptr);
        !           576: }
        !           577: 
        !           578: /* Allocate SIZE bytes in the permanent obstack
        !           579:    and return a pointer to them.  */
        !           580: 
        !           581: char *
        !           582: permalloc (size)
        !           583:      int size;
        !           584: {
        !           585:   return (char *) obstack_alloc (&permanent_obstack, size);
        !           586: }
        !           587: 
        !           588: /* Allocate NELEM items of SIZE bytes in the permanent obstack
        !           589:    and return a pointer to them.  The storage is cleared before
        !           590:    returning the value.  */
        !           591: 
        !           592: char *
        !           593: perm_calloc (nelem, size)
        !           594:      int nelem;
        !           595:      long size;
        !           596: {
        !           597:   char *rval = (char *) obstack_alloc (&permanent_obstack, nelem * size);
        !           598:   bzero (rval, nelem * size);
        !           599:   return rval;
        !           600: }
        !           601: 
        !           602: /* Allocate SIZE bytes in the saveable obstack
        !           603:    and return a pointer to them.  */
        !           604: 
        !           605: char *
        !           606: savealloc (size)
        !           607:      int size;
        !           608: {
        !           609:   return (char *) obstack_alloc (saveable_obstack, size);
        !           610: }
        !           611: 
        !           612: /* Print out which obstack an object is in.  */
        !           613: 
        !           614: void
        !           615: print_obstack_name (object, file, prefix)
        !           616:      char *object;
        !           617:      FILE *file;
        !           618:      char *prefix;
        !           619: {
        !           620:   struct obstack *obstack = NULL;
        !           621:   char *obstack_name = NULL;
        !           622:   struct function *p;
        !           623: 
        !           624:   for (p = outer_function_chain; p; p = p->next)
        !           625:     {
        !           626:       if (_obstack_allocated_p (p->function_obstack, object))
        !           627:        {
        !           628:          obstack = p->function_obstack;
        !           629:          obstack_name = "containing function obstack";
        !           630:        }
        !           631:       if (_obstack_allocated_p (p->function_maybepermanent_obstack, object))
        !           632:        {
        !           633:          obstack = p->function_maybepermanent_obstack;
        !           634:          obstack_name = "containing function maybepermanent obstack";
        !           635:        }
        !           636:     }
        !           637: 
        !           638:   if (_obstack_allocated_p (&obstack_stack_obstack, object))
        !           639:     {
        !           640:       obstack = &obstack_stack_obstack;
        !           641:       obstack_name = "obstack_stack_obstack";
        !           642:     }
        !           643:   else if (_obstack_allocated_p (function_obstack, object))
        !           644:     {
        !           645:       obstack = function_obstack;
        !           646:       obstack_name = "function obstack";
        !           647:     }
        !           648:   else if (_obstack_allocated_p (&permanent_obstack, object))
        !           649:     {
        !           650:       obstack = &permanent_obstack;
        !           651:       obstack_name = "permanent_obstack";
        !           652:     }
        !           653:   else if (_obstack_allocated_p (&momentary_obstack, object))
        !           654:     {
        !           655:       obstack = &momentary_obstack;
        !           656:       obstack_name = "momentary_obstack";
        !           657:     }
        !           658:   else if (_obstack_allocated_p (function_maybepermanent_obstack, object))
        !           659:     {
        !           660:       obstack = function_maybepermanent_obstack;
        !           661:       obstack_name = "function maybepermanent obstack";
        !           662:     }
        !           663:   else if (_obstack_allocated_p (&temp_decl_obstack, object))
        !           664:     {
        !           665:       obstack = &temp_decl_obstack;
        !           666:       obstack_name = "temp_decl_obstack";
        !           667:     }
        !           668: 
        !           669:   /* Check to see if the object is in the free area of the obstack. */
        !           670:   if (obstack != NULL)
        !           671:     {
        !           672:       if (object >= obstack->next_free
        !           673:          && object < obstack->chunk_limit)
        !           674:        fprintf (file, "%s in free portion of obstack %s",
        !           675:                 prefix, obstack_name);
        !           676:       else
        !           677:        fprintf (file, "%s allocated from %s", prefix, obstack_name);
        !           678:     }
        !           679:   else
        !           680:     fprintf (file, "%s not allocated from any obstack", prefix);
        !           681: }
        !           682: 
        !           683: void
        !           684: debug_obstack (object)
        !           685:      char *object;
        !           686: {
        !           687:   print_obstack_name (object, stderr, "object");
        !           688:   fprintf (stderr, ".\n");
        !           689: }
        !           690: 
        !           691: /* Return 1 if OBJ is in the permanent obstack.
        !           692:    This is slow, and should be used only for debugging.
        !           693:    Use TREE_PERMANENT for other purposes.  */
        !           694: 
        !           695: int
        !           696: object_permanent_p (obj)
        !           697:      tree obj;
        !           698: {
        !           699:   return _obstack_allocated_p (&permanent_obstack, obj);
        !           700: }
        !           701: 
        !           702: /* Start a level of momentary allocation.
        !           703:    In C, each compound statement has its own level
        !           704:    and that level is freed at the end of each statement.
        !           705:    All expression nodes are allocated in the momentary allocation level.  */
        !           706: 
        !           707: void
        !           708: push_momentary ()
        !           709: {
        !           710:   struct momentary_level *tem
        !           711:     = (struct momentary_level *) obstack_alloc (&momentary_obstack,
        !           712:                                                sizeof (struct momentary_level));
        !           713:   tem->prev = momentary_stack;
        !           714:   tem->base = (char *) obstack_base (&momentary_obstack);
        !           715:   tem->obstack = expression_obstack;
        !           716:   momentary_stack = tem;
        !           717:   expression_obstack = &momentary_obstack;
        !           718: }
        !           719: 
        !           720: /* Free all the storage in the current momentary-allocation level.
        !           721:    In C, this happens at the end of each statement.  */
        !           722: 
        !           723: void
        !           724: clear_momentary ()
        !           725: {
        !           726:   obstack_free (&momentary_obstack, momentary_stack->base);
        !           727: }
        !           728: 
        !           729: /* Discard a level of momentary allocation.
        !           730:    In C, this happens at the end of each compound statement.
        !           731:    Restore the status of expression node allocation
        !           732:    that was in effect before this level was created.  */
        !           733: 
        !           734: void
        !           735: pop_momentary ()
        !           736: {
        !           737:   struct momentary_level *tem = momentary_stack;
        !           738:   momentary_stack = tem->prev;
        !           739:   expression_obstack = tem->obstack;
        !           740:   obstack_free (&momentary_obstack, tem);
        !           741: }
        !           742: 
        !           743: /* Pop back to the previous level of momentary allocation,
        !           744:    but don't free any momentary data just yet.  */
        !           745: 
        !           746: void
        !           747: pop_momentary_nofree ()
        !           748: {
        !           749:   struct momentary_level *tem = momentary_stack;
        !           750:   momentary_stack = tem->prev;
        !           751:   expression_obstack = tem->obstack;
        !           752: }
        !           753: 
        !           754: /* Call when starting to parse a declaration:
        !           755:    make expressions in the declaration last the length of the function.
        !           756:    Returns an argument that should be passed to resume_momentary later.  */
        !           757: 
        !           758: int
        !           759: suspend_momentary ()
        !           760: {
        !           761:   register int tem = expression_obstack == &momentary_obstack;
        !           762:   expression_obstack = saveable_obstack;
        !           763:   return tem;
        !           764: }
        !           765: 
        !           766: /* Call when finished parsing a declaration:
        !           767:    restore the treatment of node-allocation that was
        !           768:    in effect before the suspension.
        !           769:    YES should be the value previously returned by suspend_momentary.  */
        !           770: 
        !           771: void
        !           772: resume_momentary (yes)
        !           773:      int yes;
        !           774: {
        !           775:   if (yes)
        !           776:     expression_obstack = &momentary_obstack;
        !           777: }
        !           778: 
        !           779: /* Init the tables indexed by tree code.
        !           780:    Note that languages can add to these tables to define their own codes.  */
        !           781: 
        !           782: void
        !           783: init_tree_codes ()
        !           784: {
        !           785:   tree_code_type = (char **) xmalloc (sizeof (standard_tree_code_type));
        !           786:   tree_code_length = (int *) xmalloc (sizeof (standard_tree_code_length));
        !           787:   tree_code_name = (char **) xmalloc (sizeof (standard_tree_code_name));
        !           788:   bcopy (standard_tree_code_type, tree_code_type,
        !           789:         sizeof (standard_tree_code_type));
        !           790:   bcopy (standard_tree_code_length, tree_code_length,
        !           791:         sizeof (standard_tree_code_length));
        !           792:   bcopy (standard_tree_code_name, tree_code_name,
        !           793:         sizeof (standard_tree_code_name));
        !           794: }
        !           795: 
        !           796: /* Return a newly allocated node of code CODE.
        !           797:    Initialize the node's unique id and its TREE_PERMANENT flag.
        !           798:    For decl and type nodes, some other fields are initialized.
        !           799:    The rest of the node is initialized to zero.
        !           800: 
        !           801:    Achoo!  I got a code in the node.  */
        !           802: 
        !           803: tree
        !           804: make_node (code)
        !           805:      enum tree_code code;
        !           806: {
        !           807:   register tree t;
        !           808:   register int type = TREE_CODE_CLASS (code);
        !           809:   register int length;
        !           810:   register struct obstack *obstack = current_obstack;
        !           811:   register int i;
        !           812:   register tree_node_kind kind;
        !           813: 
        !           814:   switch (type)
        !           815:     {
        !           816:     case 'd':  /* A decl node */
        !           817: #ifdef GATHER_STATISTICS
        !           818:       kind = d_kind;
        !           819: #endif
        !           820:       length = sizeof (struct tree_decl);
        !           821:       /* All decls in an inline function need to be saved.  */
        !           822:       if (obstack != &permanent_obstack)
        !           823:        obstack = saveable_obstack;
        !           824: 
        !           825:       /* PARM_DECLs go on the context of the parent. If this is a nested
        !           826:         function, then we must allocate the PARM_DECL on the parent's
        !           827:         obstack, so that they will live to the end of the parent's
        !           828:         closing brace.  This is neccesary in case we try to inline the
        !           829:         function into its parent.
        !           830: 
        !           831:         PARM_DECLs of top-level functions do not have this problem.  However,
        !           832:         we allocate them where we put the FUNCTION_DECL for languauges such as
        !           833:         Ada that need to consult some flags in the PARM_DECLs of the function
        !           834:         when calling it. 
        !           835: 
        !           836:         See comment in restore_tree_status for why we can't put this
        !           837:         in function_obstack.  */
        !           838:       if (code == PARM_DECL && obstack != &permanent_obstack)
        !           839:        {
        !           840:          tree context = 0;
        !           841:          if (current_function_decl)
        !           842:            context = decl_function_context (current_function_decl);
        !           843: 
        !           844:          if (context)
        !           845:            obstack
        !           846:              = find_function_data (context)->function_maybepermanent_obstack;
        !           847:        }
        !           848:       break;
        !           849: 
        !           850:     case 't':  /* a type node */
        !           851: #ifdef GATHER_STATISTICS
        !           852:       kind = t_kind;
        !           853: #endif
        !           854:       length = sizeof (struct tree_type);
        !           855:       /* All data types are put where we can preserve them if nec.  */
        !           856:       if (obstack != &permanent_obstack)
        !           857:        obstack = all_types_permanent ? &permanent_obstack : saveable_obstack;
        !           858:       break;
        !           859: 
        !           860:     case 'b':  /* a lexical block */
        !           861: #ifdef GATHER_STATISTICS
        !           862:       kind = b_kind;
        !           863: #endif
        !           864:       length = sizeof (struct tree_block);
        !           865:       /* All BLOCK nodes are put where we can preserve them if nec.  */
        !           866:       if (obstack != &permanent_obstack)
        !           867:        obstack = saveable_obstack;
        !           868:       break;
        !           869: 
        !           870:     case 's':  /* an expression with side effects */
        !           871: #ifdef GATHER_STATISTICS
        !           872:       kind = s_kind;
        !           873:       goto usual_kind;
        !           874: #endif
        !           875:     case 'r':  /* a reference */
        !           876: #ifdef GATHER_STATISTICS
        !           877:       kind = r_kind;
        !           878:       goto usual_kind;
        !           879: #endif
        !           880:     case 'e':  /* an expression */
        !           881:     case '<':  /* a comparison expression */
        !           882:     case '1':  /* a unary arithmetic expression */
        !           883:     case '2':  /* a binary arithmetic expression */
        !           884: #ifdef GATHER_STATISTICS
        !           885:       kind = e_kind;
        !           886:     usual_kind:
        !           887: #endif
        !           888:       obstack = expression_obstack;
        !           889:       /* All BIND_EXPR nodes are put where we can preserve them if nec.  */
        !           890:       if (code == BIND_EXPR && obstack != &permanent_obstack)
        !           891:        obstack = saveable_obstack;
        !           892:       length = sizeof (struct tree_exp)
        !           893:        + (tree_code_length[(int) code] - 1) * sizeof (char *);
        !           894:       break;
        !           895: 
        !           896:     case 'c':  /* a constant */
        !           897: #ifdef GATHER_STATISTICS
        !           898:       kind = c_kind;
        !           899: #endif
        !           900:       obstack = expression_obstack;
        !           901: 
        !           902:       /* We can't use tree_code_length for INTEGER_CST, since the number of
        !           903:         words is machine-dependent due to varying length of HOST_WIDE_INT,
        !           904:         which might be wider than a pointer (e.g., long long).  Similarly
        !           905:         for REAL_CST, since the number of words is machine-dependent due
        !           906:         to varying size and alignment of `double'.  */
        !           907: 
        !           908:       if (code == INTEGER_CST)
        !           909:        length = sizeof (struct tree_int_cst);
        !           910:       else if (code == REAL_CST)
        !           911:        length = sizeof (struct tree_real_cst);
        !           912:       else
        !           913:        length = sizeof (struct tree_common)
        !           914:          + tree_code_length[(int) code] * sizeof (char *);
        !           915:       break;
        !           916: 
        !           917:     case 'x':  /* something random, like an identifier.  */
        !           918: #ifdef GATHER_STATISTICS
        !           919:       if (code == IDENTIFIER_NODE)
        !           920:        kind = id_kind;
        !           921:       else if (code == OP_IDENTIFIER)
        !           922:        kind = op_id_kind;
        !           923:       else if (code == TREE_VEC)
        !           924:        kind = vec_kind;
        !           925:       else
        !           926:        kind = x_kind;
        !           927: #endif
        !           928:       length = sizeof (struct tree_common)
        !           929:        + tree_code_length[(int) code] * sizeof (char *);
        !           930:       /* Identifier nodes are always permanent since they are
        !           931:         unique in a compiler run.  */
        !           932:       if (code == IDENTIFIER_NODE) obstack = &permanent_obstack;
        !           933:     }
        !           934: 
        !           935:   t = (tree) obstack_alloc (obstack, length);
        !           936: 
        !           937: #ifdef GATHER_STATISTICS
        !           938:   tree_node_counts[(int)kind]++;
        !           939:   tree_node_sizes[(int)kind] += length;
        !           940: #endif
        !           941: 
        !           942:   /* Clear a word at a time.  */
        !           943:   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
        !           944:     ((int *) t)[i] = 0;
        !           945:   /* Clear any extra bytes.  */
        !           946:   for (i = length / sizeof (int) * sizeof (int); i < length; i++)
        !           947:     ((char *) t)[i] = 0;
        !           948: 
        !           949:   TREE_SET_CODE (t, code);
        !           950:   if (obstack == &permanent_obstack)
        !           951:     TREE_PERMANENT (t) = 1;
        !           952: 
        !           953:   switch (type)
        !           954:     {
        !           955:     case 's':
        !           956:       TREE_SIDE_EFFECTS (t) = 1;
        !           957:       TREE_TYPE (t) = void_type_node;
        !           958:       break;
        !           959: 
        !           960:     case 'd':
        !           961:       if (code != FUNCTION_DECL)
        !           962:        DECL_ALIGN (t) = 1;
        !           963:       DECL_IN_SYSTEM_HEADER (t)
        !           964:        = in_system_header && (obstack == &permanent_obstack);
        !           965:       DECL_SOURCE_LINE (t) = lineno;
        !           966:       DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
        !           967:       DECL_UID (t) = next_decl_uid++;
        !           968:       break;
        !           969: 
        !           970:     case 't':
        !           971:       TYPE_UID (t) = next_type_uid++;
        !           972:       TYPE_ALIGN (t) = 1;
        !           973:       TYPE_MAIN_VARIANT (t) = t;
        !           974:       TYPE_OBSTACK (t) = obstack;
        !           975:       break;
        !           976: 
        !           977:     case 'c':
        !           978:       TREE_CONSTANT (t) = 1;
        !           979:       break;
        !           980:     }
        !           981: 
        !           982:   return t;
        !           983: }
        !           984: 
        !           985: /* Return a new node with the same contents as NODE
        !           986:    except that its TREE_CHAIN is zero and it has a fresh uid.  */
        !           987: 
        !           988: tree
        !           989: copy_node (node)
        !           990:      tree node;
        !           991: {
        !           992:   register tree t;
        !           993:   register enum tree_code code = TREE_CODE (node);
        !           994:   register int length;
        !           995:   register int i;
        !           996: 
        !           997:   switch (TREE_CODE_CLASS (code))
        !           998:     {
        !           999:     case 'd':  /* A decl node */
        !          1000:       length = sizeof (struct tree_decl);
        !          1001:       break;
        !          1002: 
        !          1003:     case 't':  /* a type node */
        !          1004:       length = sizeof (struct tree_type);
        !          1005:       break;
        !          1006: 
        !          1007:     case 'b':  /* a lexical block node */
        !          1008:       length = sizeof (struct tree_block);
        !          1009:       break;
        !          1010: 
        !          1011:     case 'r':  /* a reference */
        !          1012:     case 'e':  /* an expression */
        !          1013:     case 's':  /* an expression with side effects */
        !          1014:     case '<':  /* a comparison expression */
        !          1015:     case '1':  /* a unary arithmetic expression */
        !          1016:     case '2':  /* a binary arithmetic expression */
        !          1017:       length = sizeof (struct tree_exp)
        !          1018:        + (tree_code_length[(int) code] - 1) * sizeof (char *);
        !          1019:       break;
        !          1020: 
        !          1021:     case 'c':  /* a constant */
        !          1022:       /* We can't use tree_code_length for this, since the number of words
        !          1023:         is machine-dependent due to varying alignment of `double'.  */
        !          1024:       if (code == REAL_CST)
        !          1025:        {
        !          1026:          length = sizeof (struct tree_real_cst);
        !          1027:          break;
        !          1028:        }
        !          1029: 
        !          1030:     case 'x':  /* something random, like an identifier.  */
        !          1031:       length = sizeof (struct tree_common)
        !          1032:        + tree_code_length[(int) code] * sizeof (char *);
        !          1033:       if (code == TREE_VEC)
        !          1034:        length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);
        !          1035:     }
        !          1036: 
        !          1037:   t = (tree) obstack_alloc (current_obstack, length);
        !          1038: 
        !          1039:   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
        !          1040:     ((int *) t)[i] = ((int *) node)[i];
        !          1041:   /* Clear any extra bytes.  */
        !          1042:   for (i = length / sizeof (int) * sizeof (int); i < length; i++)
        !          1043:     ((char *) t)[i] = ((char *) node)[i];
        !          1044: 
        !          1045:   TREE_CHAIN (t) = 0;
        !          1046: 
        !          1047:   if (TREE_CODE_CLASS (code) == 'd')
        !          1048:     DECL_UID (t) = next_decl_uid++;
        !          1049:   else if (TREE_CODE_CLASS (code) == 't')
        !          1050:     {
        !          1051:       TYPE_UID (t) = next_type_uid++;
        !          1052:       TYPE_OBSTACK (t) = current_obstack;
        !          1053:     }
        !          1054: 
        !          1055:   TREE_PERMANENT (t) = (current_obstack == &permanent_obstack);
        !          1056: 
        !          1057:   return t;
        !          1058: }
        !          1059: 
        !          1060: /* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
        !          1061:    For example, this can copy a list made of TREE_LIST nodes.  */
        !          1062: 
        !          1063: tree
        !          1064: copy_list (list)
        !          1065:      tree list;
        !          1066: {
        !          1067:   tree head;
        !          1068:   register tree prev, next;
        !          1069: 
        !          1070:   if (list == 0)
        !          1071:     return 0;
        !          1072: 
        !          1073:   head = prev = copy_node (list);
        !          1074:   next = TREE_CHAIN (list);
        !          1075:   while (next)
        !          1076:     {
        !          1077:       TREE_CHAIN (prev) = copy_node (next);
        !          1078:       prev = TREE_CHAIN (prev);
        !          1079:       next = TREE_CHAIN (next);
        !          1080:     }
        !          1081:   return head;
        !          1082: }
        !          1083: 
        !          1084: #define HASHBITS 30
        !          1085: 
        !          1086: /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
        !          1087:    If an identifier with that name has previously been referred to,
        !          1088:    the same node is returned this time.  */
        !          1089: 
        !          1090: tree
        !          1091: get_identifier (text)
        !          1092:      register char *text;
        !          1093: {
        !          1094:   register int hi;
        !          1095:   register int i;
        !          1096:   register tree idp;
        !          1097:   register int len, hash_len;
        !          1098: 
        !          1099:   /* Compute length of text in len.  */
        !          1100:   for (len = 0; text[len]; len++);
        !          1101: 
        !          1102:   /* Decide how much of that length to hash on */
        !          1103:   hash_len = len;
        !          1104:   if (warn_id_clash && len > id_clash_len)
        !          1105:     hash_len = id_clash_len;
        !          1106: 
        !          1107:   /* Compute hash code */
        !          1108:   hi = hash_len * 613 + (unsigned)text[0];
        !          1109:   for (i = 1; i < hash_len; i += 2)
        !          1110:     hi = ((hi * 613) + (unsigned)(text[i]));
        !          1111: 
        !          1112:   hi &= (1 << HASHBITS) - 1;
        !          1113:   hi %= MAX_HASH_TABLE;
        !          1114:   
        !          1115:   /* Search table for identifier */
        !          1116:   for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
        !          1117:     if (IDENTIFIER_LENGTH (idp) == len
        !          1118:        && IDENTIFIER_POINTER (idp)[0] == text[0]
        !          1119:        && !bcmp (IDENTIFIER_POINTER (idp), text, len))
        !          1120:       return idp;              /* <-- return if found */
        !          1121: 
        !          1122:   /* Not found; optionally warn about a similar identifier */
        !          1123:   if (warn_id_clash && do_identifier_warnings && len >= id_clash_len)
        !          1124:     for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
        !          1125:       if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len))
        !          1126:        {
        !          1127:          warning ("`%s' and `%s' identical in first %d characters",
        !          1128:                   IDENTIFIER_POINTER (idp), text, id_clash_len);
        !          1129:          break;
        !          1130:        }
        !          1131: 
        !          1132:   if (tree_code_length[(int) IDENTIFIER_NODE] < 0)
        !          1133:     abort ();                  /* set_identifier_size hasn't been called.  */
        !          1134: 
        !          1135:   /* Not found, create one, add to chain */
        !          1136:   idp = make_node (IDENTIFIER_NODE);
        !          1137:   IDENTIFIER_LENGTH (idp) = len;
        !          1138: #ifdef GATHER_STATISTICS
        !          1139:   id_string_size += len;
        !          1140: #endif
        !          1141: 
        !          1142:   IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len);
        !          1143: 
        !          1144:   TREE_CHAIN (idp) = hash_table[hi];
        !          1145:   hash_table[hi] = idp;
        !          1146:   return idp;                  /* <-- return if created */
        !          1147: }
        !          1148: 
        !          1149: /* Enable warnings on similar identifiers (if requested).
        !          1150:    Done after the built-in identifiers are created.  */
        !          1151: 
        !          1152: void
        !          1153: start_identifier_warnings ()
        !          1154: {
        !          1155:   do_identifier_warnings = 1;
        !          1156: }
        !          1157: 
        !          1158: /* Record the size of an identifier node for the language in use.
        !          1159:    SIZE is the total size in bytes.
        !          1160:    This is called by the language-specific files.  This must be
        !          1161:    called before allocating any identifiers.  */
        !          1162: 
        !          1163: void
        !          1164: set_identifier_size (size)
        !          1165:      int size;
        !          1166: {
        !          1167:   tree_code_length[(int) IDENTIFIER_NODE]
        !          1168:     = (size - sizeof (struct tree_common)) / sizeof (tree);
        !          1169: }
        !          1170: 
        !          1171: /* Return a newly constructed INTEGER_CST node whose constant value
        !          1172:    is specified by the two ints LOW and HI.
        !          1173:    The TREE_TYPE is set to `int'. 
        !          1174: 
        !          1175:    This function should be used via the `build_int_2' macro.  */
        !          1176: 
        !          1177: tree
        !          1178: build_int_2_wide (low, hi)
        !          1179:      HOST_WIDE_INT low, hi;
        !          1180: {
        !          1181:   register tree t = make_node (INTEGER_CST);
        !          1182:   TREE_INT_CST_LOW (t) = low;
        !          1183:   TREE_INT_CST_HIGH (t) = hi;
        !          1184:   TREE_TYPE (t) = integer_type_node;
        !          1185:   return t;
        !          1186: }
        !          1187: 
        !          1188: /* Return a new REAL_CST node whose type is TYPE and value is D.  */
        !          1189: 
        !          1190: tree
        !          1191: build_real (type, d)
        !          1192:      tree type;
        !          1193:      REAL_VALUE_TYPE d;
        !          1194: {
        !          1195:   tree v;
        !          1196: 
        !          1197:   /* Check for valid float value for this type on this target machine;
        !          1198:      if not, can print error message and store a valid value in D.  */
        !          1199: #ifdef CHECK_FLOAT_VALUE
        !          1200:   CHECK_FLOAT_VALUE (TYPE_MODE (type), d);
        !          1201: #endif
        !          1202: 
        !          1203:   v = make_node (REAL_CST);
        !          1204:   TREE_TYPE (v) = type;
        !          1205:   TREE_REAL_CST (v) = d;
        !          1206:   return v;
        !          1207: }
        !          1208: 
        !          1209: /* Return a new REAL_CST node whose type is TYPE
        !          1210:    and whose value is the integer value of the INTEGER_CST node I.  */
        !          1211: 
        !          1212: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          1213: 
        !          1214: REAL_VALUE_TYPE
        !          1215: real_value_from_int_cst (i)
        !          1216:      tree i;
        !          1217: {
        !          1218:   REAL_VALUE_TYPE d;
        !          1219:   REAL_VALUE_TYPE e;
        !          1220:   /* Some 386 compilers mishandle unsigned int to float conversions,
        !          1221:      so introduce a temporary variable E to avoid those bugs.  */
        !          1222: 
        !          1223: #ifdef REAL_ARITHMETIC
        !          1224:   if (! TREE_UNSIGNED (TREE_TYPE (i)))
        !          1225:     REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
        !          1226:   else
        !          1227:     REAL_VALUE_FROM_UNSIGNED_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
        !          1228: #else /* not REAL_ARITHMETIC */
        !          1229:   if (TREE_INT_CST_HIGH (i) < 0 && ! TREE_UNSIGNED (TREE_TYPE (i)))
        !          1230:     {
        !          1231:       d = (double) (~ TREE_INT_CST_HIGH (i));
        !          1232:       e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
        !          1233:            * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
        !          1234:       d *= e;
        !          1235:       e = (double) (unsigned HOST_WIDE_INT) (~ TREE_INT_CST_LOW (i));
        !          1236:       d += e;
        !          1237:       d = (- d - 1.0);
        !          1238:     }
        !          1239:   else
        !          1240:     {
        !          1241:       d = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (i);
        !          1242:       e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
        !          1243:            * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
        !          1244:       d *= e;
        !          1245:       e = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (i);
        !          1246:       d += e;
        !          1247:     }
        !          1248: #endif /* not REAL_ARITHMETIC */
        !          1249:   return d;
        !          1250: }
        !          1251: 
        !          1252: /* This function can't be implemented if we can't do arithmetic
        !          1253:    on the float representation.  */
        !          1254: 
        !          1255: tree
        !          1256: build_real_from_int_cst (type, i)
        !          1257:      tree type;
        !          1258:      tree i;
        !          1259: {
        !          1260:   tree v;
        !          1261:   REAL_VALUE_TYPE d;
        !          1262: 
        !          1263:   v = make_node (REAL_CST);
        !          1264:   TREE_TYPE (v) = type;
        !          1265: 
        !          1266:   d = REAL_VALUE_TRUNCATE (TYPE_MODE (type), real_value_from_int_cst (i));
        !          1267:   /* Check for valid float value for this type on this target machine;
        !          1268:      if not, can print error message and store a valid value in D.  */
        !          1269: #ifdef CHECK_FLOAT_VALUE
        !          1270:   CHECK_FLOAT_VALUE (TYPE_MODE (type), d);
        !          1271: #endif
        !          1272: 
        !          1273:   TREE_REAL_CST (v) = d;
        !          1274:   return v;
        !          1275: }
        !          1276: 
        !          1277: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          1278: 
        !          1279: /* Return a newly constructed STRING_CST node whose value is
        !          1280:    the LEN characters at STR.
        !          1281:    The TREE_TYPE is not initialized.  */
        !          1282: 
        !          1283: tree
        !          1284: build_string (len, str)
        !          1285:      int len;
        !          1286:      char *str;
        !          1287: {
        !          1288:   /* Put the string in saveable_obstack since it will be placed in the RTL
        !          1289:      for an "asm" statement and will also be kept around a while if
        !          1290:      deferring constant output in varasm.c.  */
        !          1291: 
        !          1292:   register tree s = make_node (STRING_CST);
        !          1293:   TREE_STRING_LENGTH (s) = len;
        !          1294:   TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
        !          1295:   return s;
        !          1296: }
        !          1297: 
        !          1298: /* Return a newly constructed COMPLEX_CST node whose value is
        !          1299:    specified by the real and imaginary parts REAL and IMAG.
        !          1300:    Both REAL and IMAG should be constant nodes.
        !          1301:    The TREE_TYPE is not initialized.  */
        !          1302: 
        !          1303: tree
        !          1304: build_complex (real, imag)
        !          1305:      tree real, imag;
        !          1306: {
        !          1307:   register tree t = make_node (COMPLEX_CST);
        !          1308:   TREE_REALPART (t) = real;
        !          1309:   TREE_IMAGPART (t) = imag;
        !          1310:   TREE_TYPE (t) = build_complex_type (TREE_TYPE (real));
        !          1311:   return t;
        !          1312: }
        !          1313: 
        !          1314: /* Build a newly constructed TREE_VEC node of length LEN.  */
        !          1315: tree
        !          1316: make_tree_vec (len)
        !          1317:      int len;
        !          1318: {
        !          1319:   register tree t;
        !          1320:   register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
        !          1321:   register struct obstack *obstack = current_obstack;
        !          1322:   register int i;
        !          1323: 
        !          1324: #ifdef GATHER_STATISTICS
        !          1325:   tree_node_counts[(int)vec_kind]++;
        !          1326:   tree_node_sizes[(int)vec_kind] += length;
        !          1327: #endif
        !          1328: 
        !          1329:   t = (tree) obstack_alloc (obstack, length);
        !          1330: 
        !          1331:   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
        !          1332:     ((int *) t)[i] = 0;
        !          1333: 
        !          1334:   TREE_SET_CODE (t, TREE_VEC);
        !          1335:   TREE_VEC_LENGTH (t) = len;
        !          1336:   if (obstack == &permanent_obstack)
        !          1337:     TREE_PERMANENT (t) = 1;
        !          1338: 
        !          1339:   return t;
        !          1340: }
        !          1341: 
        !          1342: /* Return 1 if EXPR is the integer constant zero.  */
        !          1343: 
        !          1344: int
        !          1345: integer_zerop (expr)
        !          1346:      tree expr;
        !          1347: {
        !          1348:   STRIP_NOPS (expr);
        !          1349: 
        !          1350:   return (TREE_CODE (expr) == INTEGER_CST
        !          1351:          && TREE_INT_CST_LOW (expr) == 0
        !          1352:          && TREE_INT_CST_HIGH (expr) == 0);
        !          1353: }
        !          1354: 
        !          1355: /* Return 1 if EXPR is the integer constant one.  */
        !          1356: 
        !          1357: int
        !          1358: integer_onep (expr)
        !          1359:      tree expr;
        !          1360: {
        !          1361:   STRIP_NOPS (expr);
        !          1362: 
        !          1363:   return (TREE_CODE (expr) == INTEGER_CST
        !          1364:          && TREE_INT_CST_LOW (expr) == 1
        !          1365:          && TREE_INT_CST_HIGH (expr) == 0);
        !          1366: }
        !          1367: 
        !          1368: /* Return 1 if EXPR is an integer containing all 1's
        !          1369:    in as much precision as it contains.  */
        !          1370: 
        !          1371: int
        !          1372: integer_all_onesp (expr)
        !          1373:      tree expr;
        !          1374: {
        !          1375:   register int prec;
        !          1376:   register int uns;
        !          1377: 
        !          1378:   STRIP_NOPS (expr);
        !          1379: 
        !          1380:   if (TREE_CODE (expr) != INTEGER_CST)
        !          1381:     return 0;
        !          1382: 
        !          1383:   uns = TREE_UNSIGNED (TREE_TYPE (expr));
        !          1384:   if (!uns)
        !          1385:     return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == -1;
        !          1386: 
        !          1387:   prec = TYPE_PRECISION (TREE_TYPE (expr));
        !          1388:   if (prec >= HOST_BITS_PER_WIDE_INT)
        !          1389:     {
        !          1390:       int high_value, shift_amount;
        !          1391: 
        !          1392:       shift_amount = prec - HOST_BITS_PER_WIDE_INT;
        !          1393: 
        !          1394:       if (shift_amount > HOST_BITS_PER_WIDE_INT)
        !          1395:        /* Can not handle precisions greater than twice the host int size.  */
        !          1396:        abort ();
        !          1397:       else if (shift_amount == HOST_BITS_PER_WIDE_INT)
        !          1398:        /* Shifting by the host word size is undefined according to the ANSI
        !          1399:           standard, so we must handle this as a special case.  */
        !          1400:        high_value = -1;
        !          1401:       else
        !          1402:        high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
        !          1403: 
        !          1404:       return TREE_INT_CST_LOW (expr) == -1
        !          1405:        && TREE_INT_CST_HIGH (expr) == high_value;
        !          1406:     }
        !          1407:   else
        !          1408:     return TREE_INT_CST_LOW (expr) == ((HOST_WIDE_INT) 1 << prec) - 1;
        !          1409: }
        !          1410: 
        !          1411: /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
        !          1412:    one bit on).  */
        !          1413: 
        !          1414: int
        !          1415: integer_pow2p (expr)
        !          1416:      tree expr;
        !          1417: {
        !          1418:   HOST_WIDE_INT high, low;
        !          1419: 
        !          1420:   STRIP_NOPS (expr);
        !          1421: 
        !          1422:   if (TREE_CODE (expr) != INTEGER_CST)
        !          1423:     return 0;
        !          1424: 
        !          1425:   high = TREE_INT_CST_HIGH (expr);
        !          1426:   low = TREE_INT_CST_LOW (expr);
        !          1427: 
        !          1428:   if (high == 0 && low == 0)
        !          1429:     return 0;
        !          1430: 
        !          1431:   return ((high == 0 && (low & (low - 1)) == 0)
        !          1432:          || (low == 0 && (high & (high - 1)) == 0));
        !          1433: }
        !          1434: 
        !          1435: /* Return 1 if EXPR is the real constant zero.  */
        !          1436: 
        !          1437: int
        !          1438: real_zerop (expr)
        !          1439:      tree expr;
        !          1440: {
        !          1441:   STRIP_NOPS (expr);
        !          1442: 
        !          1443:   return (TREE_CODE (expr) == REAL_CST
        !          1444:          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0));
        !          1445: }
        !          1446: 
        !          1447: /* Return 1 if EXPR is the real constant one.  */
        !          1448: 
        !          1449: int
        !          1450: real_onep (expr)
        !          1451:      tree expr;
        !          1452: {
        !          1453:   STRIP_NOPS (expr);
        !          1454: 
        !          1455:   return (TREE_CODE (expr) == REAL_CST
        !          1456:          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1));
        !          1457: }
        !          1458: 
        !          1459: /* Return 1 if EXPR is the real constant two.  */
        !          1460: 
        !          1461: int
        !          1462: real_twop (expr)
        !          1463:      tree expr;
        !          1464: {
        !          1465:   STRIP_NOPS (expr);
        !          1466: 
        !          1467:   return (TREE_CODE (expr) == REAL_CST
        !          1468:          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2));
        !          1469: }
        !          1470: 
        !          1471: /* Nonzero if EXP is a constant or a cast of a constant.  */
        !          1472:  
        !          1473: int
        !          1474: really_constant_p (exp)
        !          1475:      tree exp;
        !          1476: {
        !          1477:   /* This is not quite the same as STRIP_NOPS.  It does more.  */
        !          1478:   while (TREE_CODE (exp) == NOP_EXPR
        !          1479:         || TREE_CODE (exp) == CONVERT_EXPR
        !          1480:         || TREE_CODE (exp) == NON_LVALUE_EXPR)
        !          1481:     exp = TREE_OPERAND (exp, 0);
        !          1482:   return TREE_CONSTANT (exp);
        !          1483: }
        !          1484: 
        !          1485: /* Return first list element whose TREE_VALUE is ELEM.
        !          1486:    Return 0 if ELEM is not it LIST.  */
        !          1487: 
        !          1488: tree
        !          1489: value_member (elem, list)
        !          1490:      tree elem, list;
        !          1491: {
        !          1492:   while (list)
        !          1493:     {
        !          1494:       if (elem == TREE_VALUE (list))
        !          1495:        return list;
        !          1496:       list = TREE_CHAIN (list);
        !          1497:     }
        !          1498:   return NULL_TREE;
        !          1499: }
        !          1500: 
        !          1501: /* Return first list element whose TREE_PURPOSE is ELEM.
        !          1502:    Return 0 if ELEM is not it LIST.  */
        !          1503: 
        !          1504: tree
        !          1505: purpose_member (elem, list)
        !          1506:      tree elem, list;
        !          1507: {
        !          1508:   while (list)
        !          1509:     {
        !          1510:       if (elem == TREE_PURPOSE (list))
        !          1511:        return list;
        !          1512:       list = TREE_CHAIN (list);
        !          1513:     }
        !          1514:   return NULL_TREE;
        !          1515: }
        !          1516: 
        !          1517: /* Return first list element whose BINFO_TYPE is ELEM.
        !          1518:    Return 0 if ELEM is not it LIST.  */
        !          1519: 
        !          1520: tree
        !          1521: binfo_member (elem, list)
        !          1522:      tree elem, list;
        !          1523: {
        !          1524:   while (list)
        !          1525:     {
        !          1526:       if (elem == BINFO_TYPE (list))
        !          1527:        return list;
        !          1528:       list = TREE_CHAIN (list);
        !          1529:     }
        !          1530:   return NULL_TREE;
        !          1531: }
        !          1532: 
        !          1533: /* Return nonzero if ELEM is part of the chain CHAIN.  */
        !          1534: 
        !          1535: int
        !          1536: chain_member (elem, chain)
        !          1537:      tree elem, chain;
        !          1538: {
        !          1539:   while (chain)
        !          1540:     {
        !          1541:       if (elem == chain)
        !          1542:        return 1;
        !          1543:       chain = TREE_CHAIN (chain);
        !          1544:     }
        !          1545: 
        !          1546:   return 0;
        !          1547: }
        !          1548: 
        !          1549: /* Return the length of a chain of nodes chained through TREE_CHAIN.
        !          1550:    We expect a null pointer to mark the end of the chain.
        !          1551:    This is the Lisp primitive `length'.  */
        !          1552: 
        !          1553: int
        !          1554: list_length (t)
        !          1555:      tree t;
        !          1556: {
        !          1557:   register tree tail;
        !          1558:   register int len = 0;
        !          1559: 
        !          1560:   for (tail = t; tail; tail = TREE_CHAIN (tail))
        !          1561:     len++;
        !          1562: 
        !          1563:   return len;
        !          1564: }
        !          1565: 
        !          1566: /* Concatenate two chains of nodes (chained through TREE_CHAIN)
        !          1567:    by modifying the last node in chain 1 to point to chain 2.
        !          1568:    This is the Lisp primitive `nconc'.  */
        !          1569: 
        !          1570: tree
        !          1571: chainon (op1, op2)
        !          1572:      tree op1, op2;
        !          1573: {
        !          1574:   tree t;
        !          1575: 
        !          1576:   if (op1)
        !          1577:     {
        !          1578:       for (t = op1; TREE_CHAIN (t); t = TREE_CHAIN (t))
        !          1579:        if (t == op2) abort (); /* Circularity being created */
        !          1580:       if (t == op2) abort ();  /* Circularity being created */
        !          1581:       TREE_CHAIN (t) = op2;
        !          1582:       return op1;
        !          1583:     }
        !          1584:   else return op2;
        !          1585: }
        !          1586: 
        !          1587: /* Return the last node in a chain of nodes (chained through TREE_CHAIN).  */
        !          1588: 
        !          1589: tree
        !          1590: tree_last (chain)
        !          1591:      register tree chain;
        !          1592: {
        !          1593:   register tree next;
        !          1594:   if (chain)
        !          1595:     while (next = TREE_CHAIN (chain))
        !          1596:       chain = next;
        !          1597:   return chain;
        !          1598: }
        !          1599: 
        !          1600: /* Reverse the order of elements in the chain T,
        !          1601:    and return the new head of the chain (old last element).  */
        !          1602: 
        !          1603: tree
        !          1604: nreverse (t)
        !          1605:      tree t;
        !          1606: {
        !          1607:   register tree prev = 0, decl, next;
        !          1608:   for (decl = t; decl; decl = next)
        !          1609:     {
        !          1610:       next = TREE_CHAIN (decl);
        !          1611:       TREE_CHAIN (decl) = prev;
        !          1612:       prev = decl;
        !          1613:     }
        !          1614:   return prev;
        !          1615: }
        !          1616: 
        !          1617: /* Given a chain CHAIN of tree nodes,
        !          1618:    construct and return a list of those nodes.  */
        !          1619: 
        !          1620: tree
        !          1621: listify (chain)
        !          1622:      tree chain;
        !          1623: {
        !          1624:   tree result = NULL_TREE;
        !          1625:   tree in_tail = chain;
        !          1626:   tree out_tail = NULL_TREE;
        !          1627: 
        !          1628:   while (in_tail)
        !          1629:     {
        !          1630:       tree next = tree_cons (NULL_TREE, in_tail, NULL_TREE);
        !          1631:       if (out_tail)
        !          1632:        TREE_CHAIN (out_tail) = next;
        !          1633:       else
        !          1634:        result = next;
        !          1635:       out_tail = next;
        !          1636:       in_tail = TREE_CHAIN (in_tail);
        !          1637:     }
        !          1638: 
        !          1639:   return result;
        !          1640: }
        !          1641: 
        !          1642: /* Return a newly created TREE_LIST node whose
        !          1643:    purpose and value fields are PARM and VALUE.  */
        !          1644: 
        !          1645: tree
        !          1646: build_tree_list (parm, value)
        !          1647:      tree parm, value;
        !          1648: {
        !          1649:   register tree t = make_node (TREE_LIST);
        !          1650:   TREE_PURPOSE (t) = parm;
        !          1651:   TREE_VALUE (t) = value;
        !          1652:   return t;
        !          1653: }
        !          1654: 
        !          1655: /* Similar, but build on the temp_decl_obstack.  */
        !          1656: 
        !          1657: tree
        !          1658: build_decl_list (parm, value)
        !          1659:      tree parm, value;
        !          1660: {
        !          1661:   register tree node;
        !          1662:   register struct obstack *ambient_obstack = current_obstack;
        !          1663:   current_obstack = &temp_decl_obstack;
        !          1664:   node = build_tree_list (parm, value);
        !          1665:   current_obstack = ambient_obstack;
        !          1666:   return node;
        !          1667: }
        !          1668: 
        !          1669: /* Return a newly created TREE_LIST node whose
        !          1670:    purpose and value fields are PARM and VALUE
        !          1671:    and whose TREE_CHAIN is CHAIN.  */
        !          1672: 
        !          1673: tree
        !          1674: tree_cons (purpose, value, chain)
        !          1675:      tree purpose, value, chain;
        !          1676: {
        !          1677: #if 0
        !          1678:   register tree node = make_node (TREE_LIST);
        !          1679: #else
        !          1680:   register int i;
        !          1681:   register tree node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
        !          1682: #ifdef GATHER_STATISTICS
        !          1683:   tree_node_counts[(int)x_kind]++;
        !          1684:   tree_node_sizes[(int)x_kind] += sizeof (struct tree_list);
        !          1685: #endif
        !          1686: 
        !          1687:   for (i = (sizeof (struct tree_common) / sizeof (int)) - 1; i >= 0; i--)
        !          1688:     ((int *) node)[i] = 0;
        !          1689: 
        !          1690:   TREE_SET_CODE (node, TREE_LIST);
        !          1691:   if (current_obstack == &permanent_obstack)
        !          1692:     TREE_PERMANENT (node) = 1;
        !          1693: #endif
        !          1694: 
        !          1695:   TREE_CHAIN (node) = chain;
        !          1696:   TREE_PURPOSE (node) = purpose;
        !          1697:   TREE_VALUE (node) = value;
        !          1698:   return node;
        !          1699: }
        !          1700: 
        !          1701: /* Similar, but build on the temp_decl_obstack.  */
        !          1702: 
        !          1703: tree
        !          1704: decl_tree_cons (purpose, value, chain)
        !          1705:      tree purpose, value, chain;
        !          1706: {
        !          1707:   register tree node;
        !          1708:   register struct obstack *ambient_obstack = current_obstack;
        !          1709:   current_obstack = &temp_decl_obstack;
        !          1710:   node = tree_cons (purpose, value, chain);
        !          1711:   current_obstack = ambient_obstack;
        !          1712:   return node;
        !          1713: }
        !          1714: 
        !          1715: /* Same as `tree_cons' but make a permanent object.  */
        !          1716: 
        !          1717: tree
        !          1718: perm_tree_cons (purpose, value, chain)
        !          1719:      tree purpose, value, chain;
        !          1720: {
        !          1721:   register tree node;
        !          1722:   register struct obstack *ambient_obstack = current_obstack;
        !          1723:   current_obstack = &permanent_obstack;
        !          1724: 
        !          1725:   node = tree_cons (purpose, value, chain);
        !          1726:   current_obstack = ambient_obstack;
        !          1727:   return node;
        !          1728: }
        !          1729: 
        !          1730: /* Same as `tree_cons', but make this node temporary, regardless.  */
        !          1731: 
        !          1732: tree
        !          1733: temp_tree_cons (purpose, value, chain)
        !          1734:      tree purpose, value, chain;
        !          1735: {
        !          1736:   register tree node;
        !          1737:   register struct obstack *ambient_obstack = current_obstack;
        !          1738:   current_obstack = &temporary_obstack;
        !          1739: 
        !          1740:   node = tree_cons (purpose, value, chain);
        !          1741:   current_obstack = ambient_obstack;
        !          1742:   return node;
        !          1743: }
        !          1744: 
        !          1745: /* Same as `tree_cons', but save this node if the function's RTL is saved.  */
        !          1746: 
        !          1747: tree
        !          1748: saveable_tree_cons (purpose, value, chain)
        !          1749:      tree purpose, value, chain;
        !          1750: {
        !          1751:   register tree node;
        !          1752:   register struct obstack *ambient_obstack = current_obstack;
        !          1753:   current_obstack = saveable_obstack;
        !          1754: 
        !          1755:   node = tree_cons (purpose, value, chain);
        !          1756:   current_obstack = ambient_obstack;
        !          1757:   return node;
        !          1758: }
        !          1759: 
        !          1760: /* Return the size nominally occupied by an object of type TYPE
        !          1761:    when it resides in memory.  The value is measured in units of bytes,
        !          1762:    and its data type is that normally used for type sizes
        !          1763:    (which is the first type created by make_signed_type or
        !          1764:    make_unsigned_type).  */
        !          1765: 
        !          1766: tree
        !          1767: size_in_bytes (type)
        !          1768:      tree type;
        !          1769: {
        !          1770:   tree t;
        !          1771: 
        !          1772:   if (type == error_mark_node)
        !          1773:     return integer_zero_node;
        !          1774:   type = TYPE_MAIN_VARIANT (type);
        !          1775:   if (TYPE_SIZE (type) == 0)
        !          1776:     {
        !          1777:       incomplete_type_error (NULL_TREE, type);
        !          1778:       return integer_zero_node;
        !          1779:     }
        !          1780:   t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
        !          1781:                  size_int (BITS_PER_UNIT));
        !          1782:   if (TREE_CODE (t) == INTEGER_CST)
        !          1783:     force_fit_type (t, 0);
        !          1784:   return t;
        !          1785: }
        !          1786: 
        !          1787: /* Return the size of TYPE (in bytes) as an integer,
        !          1788:    or return -1 if the size can vary.  */
        !          1789: 
        !          1790: int
        !          1791: int_size_in_bytes (type)
        !          1792:      tree type;
        !          1793: {
        !          1794:   unsigned int size;
        !          1795:   if (type == error_mark_node)
        !          1796:     return 0;
        !          1797:   type = TYPE_MAIN_VARIANT (type);
        !          1798:   if (TYPE_SIZE (type) == 0)
        !          1799:     return -1;
        !          1800:   if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
        !          1801:     return -1;
        !          1802:   if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0)
        !          1803:     {
        !          1804:       tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
        !          1805:                           size_int (BITS_PER_UNIT));
        !          1806:       return TREE_INT_CST_LOW (t);
        !          1807:     }
        !          1808:   size = TREE_INT_CST_LOW (TYPE_SIZE (type));
        !          1809:   return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
        !          1810: }
        !          1811: 
        !          1812: /* Return, as a tree node, the number of elements for TYPE (which is an
        !          1813:    ARRAY_TYPE) minus one. This counts only elements of the top array.  */
        !          1814: 
        !          1815: tree
        !          1816: array_type_nelts (type)
        !          1817:      tree type;
        !          1818: {
        !          1819:   tree index_type = TYPE_DOMAIN (type);
        !          1820: 
        !          1821:   return (integer_zerop (TYPE_MIN_VALUE (index_type))
        !          1822:          ? TYPE_MAX_VALUE (index_type)
        !          1823:          : fold (build (MINUS_EXPR, TREE_TYPE (TYPE_MAX_VALUE (index_type)),
        !          1824:                         TYPE_MAX_VALUE (index_type),
        !          1825:                         TYPE_MIN_VALUE (index_type))));
        !          1826: }
        !          1827: 
        !          1828: /* Return nonzero if arg is static -- a reference to an object in
        !          1829:    static storage.  This is not the same as the C meaning of `static'.  */
        !          1830: 
        !          1831: int
        !          1832: staticp (arg)
        !          1833:      tree arg;
        !          1834: {
        !          1835:   switch (TREE_CODE (arg))
        !          1836:     {
        !          1837:     case VAR_DECL:
        !          1838:     case FUNCTION_DECL:
        !          1839:       return TREE_STATIC (arg) || DECL_EXTERNAL (arg);
        !          1840: 
        !          1841:     case CONSTRUCTOR:
        !          1842:       return TREE_STATIC (arg);
        !          1843: 
        !          1844:     case STRING_CST:
        !          1845:       return 1;
        !          1846: 
        !          1847:     case COMPONENT_REF:
        !          1848:     case BIT_FIELD_REF:
        !          1849:       return staticp (TREE_OPERAND (arg, 0));
        !          1850: 
        !          1851:     case INDIRECT_REF:
        !          1852:       return TREE_CONSTANT (TREE_OPERAND (arg, 0));
        !          1853: 
        !          1854:     case ARRAY_REF:
        !          1855:       if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
        !          1856:          && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
        !          1857:        return staticp (TREE_OPERAND (arg, 0));
        !          1858:     }
        !          1859: 
        !          1860:   return 0;
        !          1861: }
        !          1862: 
        !          1863: /* Wrap a SAVE_EXPR around EXPR, if appropriate.
        !          1864:    Do this to any expression which may be used in more than one place,
        !          1865:    but must be evaluated only once.
        !          1866: 
        !          1867:    Normally, expand_expr would reevaluate the expression each time.
        !          1868:    Calling save_expr produces something that is evaluated and recorded
        !          1869:    the first time expand_expr is called on it.  Subsequent calls to
        !          1870:    expand_expr just reuse the recorded value.
        !          1871: 
        !          1872:    The call to expand_expr that generates code that actually computes
        !          1873:    the value is the first call *at compile time*.  Subsequent calls
        !          1874:    *at compile time* generate code to use the saved value.
        !          1875:    This produces correct result provided that *at run time* control
        !          1876:    always flows through the insns made by the first expand_expr
        !          1877:    before reaching the other places where the save_expr was evaluated.
        !          1878:    You, the caller of save_expr, must make sure this is so.
        !          1879: 
        !          1880:    Constants, and certain read-only nodes, are returned with no
        !          1881:    SAVE_EXPR because that is safe.  Expressions containing placeholders
        !          1882:    are not touched; see tree.def for an explanation of what these
        !          1883:    are used for.  */
        !          1884: 
        !          1885: tree
        !          1886: save_expr (expr)
        !          1887:      tree expr;
        !          1888: {
        !          1889:   register tree t = fold (expr);
        !          1890: 
        !          1891:   /* We don't care about whether this can be used as an lvalue in this
        !          1892:      context.  */
        !          1893:   while (TREE_CODE (t) == NON_LVALUE_EXPR)
        !          1894:     t = TREE_OPERAND (t, 0);
        !          1895: 
        !          1896:   /* If the tree evaluates to a constant, then we don't want to hide that
        !          1897:      fact (i.e. this allows further folding, and direct checks for constants).
        !          1898:      However, a read-only object that has side effects cannot be bypassed.
        !          1899:      Since it is no problem to reevaluate literals, we just return the 
        !          1900:      literal node. */
        !          1901: 
        !          1902:   if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
        !          1903:       || TREE_CODE (t) == SAVE_EXPR)
        !          1904:     return t;
        !          1905: 
        !          1906:   /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
        !          1907:      it means that the size or offset of some field of an object depends on
        !          1908:      the value within another field.
        !          1909: 
        !          1910:      Note that it must not be the case that T contains both a PLACEHOLDER_EXPR
        !          1911:      and some variable since it would then need to be both evaluated once and
        !          1912:      evaluated more than once.  Front-ends must assure this case cannot
        !          1913:      happen by surrounding any such subexpressions in their own SAVE_EXPR
        !          1914:      and forcing evaluation at the proper time.  */
        !          1915:   if (contains_placeholder_p (t))
        !          1916:     return t;
        !          1917: 
        !          1918:   t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);
        !          1919: 
        !          1920:   /* This expression might be placed ahead of a jump to ensure that the
        !          1921:      value was computed on both sides of the jump.  So make sure it isn't
        !          1922:      eliminated as dead.  */
        !          1923:   TREE_SIDE_EFFECTS (t) = 1;
        !          1924:   return t;
        !          1925: }
        !          1926: 
        !          1927: /* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
        !          1928:    or offset that depends on a field within a record.
        !          1929: 
        !          1930:    Note that we only allow such expressions within simple arithmetic
        !          1931:    or a COND_EXPR.  */
        !          1932: 
        !          1933: int
        !          1934: contains_placeholder_p (exp)
        !          1935:      tree exp;
        !          1936: {
        !          1937:   register enum tree_code code = TREE_CODE (exp);
        !          1938:   tree inner;
        !          1939: 
        !          1940:   /* If we have a WITH_RECORD_EXPR, it "cancels" any PLACEHOLDER_EXPR
        !          1941:      in it since it is supplying a value for it.  */
        !          1942:   if (code == WITH_RECORD_EXPR || code == ERROR_MARK)
        !          1943:     return 0;
        !          1944: 
        !          1945:   switch (TREE_CODE_CLASS (code))
        !          1946:     {
        !          1947:     case 'r':
        !          1948:       for (inner = TREE_OPERAND (exp, 0);
        !          1949:           TREE_CODE_CLASS (TREE_CODE (inner)) == 'r';
        !          1950:           inner = TREE_OPERAND (inner, 0))
        !          1951:        ;
        !          1952:       return TREE_CODE (inner) == PLACEHOLDER_EXPR;
        !          1953: 
        !          1954:     case '1':
        !          1955:     case '2':  case '<':
        !          1956:     case 'e':
        !          1957:       switch (tree_code_length[(int) code])
        !          1958:        {
        !          1959:        case 1:
        !          1960:          return contains_placeholder_p (TREE_OPERAND (exp, 0));
        !          1961:        case 2:
        !          1962:          return (code != RTL_EXPR
        !          1963:                  && code != CONSTRUCTOR
        !          1964:                  && ! (code == SAVE_EXPR && SAVE_EXPR_RTL (exp) != 0)
        !          1965:                  && code != WITH_RECORD_EXPR
        !          1966:                  && (contains_placeholder_p (TREE_OPERAND (exp, 0))
        !          1967:                      || contains_placeholder_p (TREE_OPERAND (exp, 1))));
        !          1968:        case 3:
        !          1969:          return (code == COND_EXPR
        !          1970:                  && (contains_placeholder_p (TREE_OPERAND (exp, 0))
        !          1971:                      || contains_placeholder_p (TREE_OPERAND (exp, 1))
        !          1972:                      || contains_placeholder_p (TREE_OPERAND (exp, 2))));
        !          1973:        }
        !          1974:     }
        !          1975: 
        !          1976:   return 0;
        !          1977: }
        !          1978: 
        !          1979: /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
        !          1980:    return a tree with all occurrences of references to F in a
        !          1981:    PLACEHOLDER_EXPR replaced by R.   Note that we assume here that EXP
        !          1982:    contains only arithmetic expressions.  */
        !          1983: 
        !          1984: tree
        !          1985: substitute_in_expr (exp, f, r)
        !          1986:      tree exp;
        !          1987:      tree f;
        !          1988:      tree r;
        !          1989: {
        !          1990:   enum tree_code code = TREE_CODE (exp);
        !          1991:   tree inner;
        !          1992: 
        !          1993:   switch (TREE_CODE_CLASS (code))
        !          1994:     {
        !          1995:     case 'c':
        !          1996:     case 'd':
        !          1997:       return exp;
        !          1998: 
        !          1999:     case 'x':
        !          2000:       if (code == PLACEHOLDER_EXPR)
        !          2001:        return exp;
        !          2002:       break;
        !          2003: 
        !          2004:     case '1':
        !          2005:     case '2':
        !          2006:     case '<':
        !          2007:     case 'e':
        !          2008:       switch (tree_code_length[(int) code])
        !          2009:        {
        !          2010:        case 1:
        !          2011:          return fold (build1 (code, TREE_TYPE (exp),
        !          2012:                               substitute_in_expr (TREE_OPERAND (exp, 0),
        !          2013:                                                   f, r)));
        !          2014: 
        !          2015:        case 2:
        !          2016:          if (code == RTL_EXPR || code == CONSTRUCTOR)
        !          2017:            abort ();
        !          2018: 
        !          2019:          return fold (build (code, TREE_TYPE (exp),
        !          2020:                              substitute_in_expr (TREE_OPERAND (exp, 0), f, r),
        !          2021:                              substitute_in_expr (TREE_OPERAND (exp, 1),
        !          2022:                                                  f, r)));
        !          2023: 
        !          2024:        case 3:
        !          2025:          if (code != COND_EXPR)
        !          2026:            abort ();
        !          2027: 
        !          2028:          return fold (build (code, TREE_TYPE (exp),
        !          2029:                              substitute_in_expr (TREE_OPERAND (exp, 0), f, r),
        !          2030:                              substitute_in_expr (TREE_OPERAND (exp, 1), f, r),
        !          2031:                              substitute_in_expr (TREE_OPERAND (exp, 2),
        !          2032:                                                  f, r)));
        !          2033:        }
        !          2034: 
        !          2035:       break;
        !          2036: 
        !          2037:     case 'r':
        !          2038:       switch (code)
        !          2039:        {
        !          2040:        case COMPONENT_REF:
        !          2041:          /* If this expression is getting a value from a PLACEHOLDER_EXPR
        !          2042:             and it is the right field, replace it with R.  */
        !          2043:          for (inner = TREE_OPERAND (exp, 0);
        !          2044:               TREE_CODE_CLASS (TREE_CODE (inner)) == 'r';
        !          2045:               inner = TREE_OPERAND (inner, 0))
        !          2046:            ;
        !          2047:          if (TREE_CODE (inner) == PLACEHOLDER_EXPR
        !          2048:              && TREE_OPERAND (exp, 1) == f)
        !          2049:            return r;
        !          2050: 
        !          2051:          return fold (build (code, TREE_TYPE (exp),
        !          2052:                              substitute_in_expr (TREE_OPERAND (exp, 0), f, r),
        !          2053:                              TREE_OPERAND (exp, 1)));
        !          2054:        case BIT_FIELD_REF:
        !          2055:          return fold (build (code, TREE_TYPE (exp),
        !          2056:                              substitute_in_expr (TREE_OPERAND (exp, 0), f, r),
        !          2057:                              substitute_in_expr (TREE_OPERAND (exp, 1), f, r),
        !          2058:                              substitute_in_expr (TREE_OPERAND (exp, 2), f, r)));
        !          2059:        case INDIRECT_REF:
        !          2060:        case BUFFER_REF:
        !          2061:          return fold (build1 (code, TREE_TYPE (exp),
        !          2062:                               substitute_in_expr (TREE_OPERAND (exp, 0),
        !          2063:                                                 f, r)));
        !          2064:        case OFFSET_REF:
        !          2065:          return fold (build (code, TREE_TYPE (exp),
        !          2066:                              substitute_in_expr (TREE_OPERAND (exp, 0), f, r),
        !          2067:                              substitute_in_expr (TREE_OPERAND (exp, 1), f, r)));
        !          2068:        }
        !          2069:     }
        !          2070: 
        !          2071:   /* If it wasn't one of the cases we handle, give up.  */
        !          2072: 
        !          2073:   abort ();
        !          2074: }
        !          2075: 
        !          2076: /* Given a type T, a FIELD_DECL F, and a replacement value R,
        !          2077:    return a new type with all size expressions that contain F
        !          2078:    updated by replacing F with R.  */
        !          2079: 
        !          2080: tree
        !          2081: substitute_in_type (t, f, r)
        !          2082:      tree t, f, r;
        !          2083: {
        !          2084:   switch (TREE_CODE (t))
        !          2085:     {
        !          2086:     case POINTER_TYPE:
        !          2087:     case VOID_TYPE:
        !          2088:       return t;
        !          2089:     case INTEGER_TYPE:
        !          2090:     case ENUMERAL_TYPE:
        !          2091:     case BOOLEAN_TYPE:
        !          2092:     case CHAR_TYPE:
        !          2093:       if ((TREE_CODE (TYPE_MIN_VALUE (t)) != INTEGER_CST
        !          2094:           && contains_placeholder_p (TYPE_MIN_VALUE (t)))
        !          2095:          || (TREE_CODE (TYPE_MAX_VALUE (t)) != INTEGER_CST
        !          2096:              && contains_placeholder_p (TYPE_MAX_VALUE (t))))
        !          2097:        return build_range_type (t,
        !          2098:                                 substitute_in_expr (TYPE_MIN_VALUE (t), f, r),
        !          2099:                                 substitute_in_expr (TYPE_MAX_VALUE (t), f, r));
        !          2100:       return t;
        !          2101: 
        !          2102:     case REAL_TYPE:
        !          2103:       if ((TREE_CODE (TYPE_MIN_VALUE (t)) != INTEGER_CST
        !          2104:           && contains_placeholder_p (TYPE_MIN_VALUE (t)))
        !          2105:          || (TREE_CODE (TYPE_MAX_VALUE (t)) != INTEGER_CST
        !          2106:              && contains_placeholder_p (TYPE_MAX_VALUE (t))))
        !          2107:        {
        !          2108:          t = build_type_copy (t);
        !          2109:          TYPE_MIN_VALUE (t) = substitute_in_expr (TYPE_MIN_VALUE (t), f, r);
        !          2110:          TYPE_MAX_VALUE (t) = substitute_in_expr (TYPE_MAX_VALUE (t), f, r);
        !          2111:        }
        !          2112:       return t;
        !          2113: 
        !          2114:     case COMPLEX_TYPE:
        !          2115:       return build_complex_type (substitute_in_type (TREE_TYPE (t), f, r));
        !          2116: 
        !          2117:     case OFFSET_TYPE:
        !          2118:     case METHOD_TYPE:
        !          2119:     case REFERENCE_TYPE:
        !          2120:     case FILE_TYPE:
        !          2121:     case SET_TYPE:
        !          2122:     case STRING_TYPE:
        !          2123:     case FUNCTION_TYPE:
        !          2124:     case LANG_TYPE:
        !          2125:       /* Don't know how to do these yet.  */
        !          2126:       abort ();
        !          2127: 
        !          2128:     case ARRAY_TYPE:
        !          2129:       t = build_array_type (substitute_in_type (TREE_TYPE (t), f, r),
        !          2130:                            substitute_in_type (TYPE_DOMAIN (t), f, r));
        !          2131:       TYPE_SIZE (t) = 0;
        !          2132:       layout_type (t);
        !          2133:       return t;
        !          2134: 
        !          2135:     case RECORD_TYPE:
        !          2136:     case UNION_TYPE:
        !          2137:     case QUAL_UNION_TYPE:
        !          2138:       {
        !          2139:        tree new = copy_node (t);
        !          2140:        tree field;
        !          2141:        tree last_field = 0;
        !          2142: 
        !          2143:        /* Start out with no fields, make new fields, and chain them
        !          2144:           in.  */
        !          2145: 
        !          2146:        TYPE_FIELDS (new) = 0;
        !          2147:        TYPE_SIZE (new) = 0;
        !          2148: 
        !          2149:        for (field = TYPE_FIELDS (t); field;
        !          2150:             field = TREE_CHAIN (field))
        !          2151:          {
        !          2152:            tree new_field = copy_node (field);
        !          2153: 
        !          2154:            TREE_TYPE (new_field)
        !          2155:              = substitute_in_type (TREE_TYPE (new_field), f, r);
        !          2156: 
        !          2157:            /* If this is an anonymous field and the type of this field is
        !          2158:               a UNION_TYPE or RECORD_TYPE with no elements, ignore it.  If
        !          2159:               the type just has one element, treat that as the field. 
        !          2160:               But don't do this if we are processing a QUAL_UNION_TYPE.  */
        !          2161:            if (TREE_CODE (t) != QUAL_UNION_TYPE && DECL_NAME (new_field) == 0
        !          2162:                && (TREE_CODE (TREE_TYPE (new_field)) == UNION_TYPE
        !          2163:                    || TREE_CODE (TREE_TYPE (new_field)) == RECORD_TYPE))
        !          2164:              {
        !          2165:                if (TYPE_FIELDS (TREE_TYPE (new_field)) == 0)
        !          2166:                  continue;
        !          2167: 
        !          2168:                if (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (new_field))) == 0)
        !          2169:                  new_field = TYPE_FIELDS (TREE_TYPE (new_field));
        !          2170:              }
        !          2171: 
        !          2172:            DECL_CONTEXT (new_field) = new;
        !          2173:            DECL_SIZE (new_field) = 0;
        !          2174: 
        !          2175:            if (TREE_CODE (t) == QUAL_UNION_TYPE)
        !          2176:              {
        !          2177:                /* Do the substitution inside the qualifier and if we find
        !          2178:                   that this field will not be present, omit it.  */
        !          2179:                DECL_QUALIFIER (new_field)
        !          2180:                  = substitute_in_expr (DECL_QUALIFIER (field), f, r);
        !          2181:                if (integer_zerop (DECL_QUALIFIER (new_field)))
        !          2182:                  continue;
        !          2183:              }
        !          2184: 
        !          2185:            if (last_field == 0)
        !          2186:              TYPE_FIELDS (new) = new_field;
        !          2187:            else
        !          2188:              TREE_CHAIN (last_field) = new_field;
        !          2189: 
        !          2190:            last_field = new_field;
        !          2191: 
        !          2192:            /* If this is a qualified type and this field will always be
        !          2193:               present, we are done.  */
        !          2194:            if (TREE_CODE (t) == QUAL_UNION_TYPE
        !          2195:                && integer_onep (DECL_QUALIFIER (new_field)))
        !          2196:              break;
        !          2197:          }
        !          2198: 
        !          2199:        /* If this used to be a qualified union type, but we now know what
        !          2200:           field will be present, make this a normal union.  */
        !          2201:        if (TREE_CODE (new) == QUAL_UNION_TYPE
        !          2202:            && (TYPE_FIELDS (new) == 0
        !          2203:                || integer_onep (DECL_QUALIFIER (TYPE_FIELDS (new)))))
        !          2204:          TREE_SET_CODE (new, UNION_TYPE);
        !          2205: 
        !          2206:        layout_type (new);
        !          2207:        return new;
        !          2208:       }
        !          2209:     }
        !          2210: }
        !          2211: 
        !          2212: /* Stabilize a reference so that we can use it any number of times
        !          2213:    without causing its operands to be evaluated more than once.
        !          2214:    Returns the stabilized reference.  This works by means of save_expr,
        !          2215:    so see the caveats in the comments about save_expr.
        !          2216: 
        !          2217:    Also allows conversion expressions whose operands are references.
        !          2218:    Any other kind of expression is returned unchanged.  */
        !          2219: 
        !          2220: tree
        !          2221: stabilize_reference (ref)
        !          2222:      tree ref;
        !          2223: {
        !          2224:   register tree result;
        !          2225:   register enum tree_code code = TREE_CODE (ref);
        !          2226: 
        !          2227:   switch (code)
        !          2228:     {
        !          2229:     case VAR_DECL:
        !          2230:     case PARM_DECL:
        !          2231:     case RESULT_DECL:
        !          2232:       /* No action is needed in this case.  */
        !          2233:       return ref;
        !          2234: 
        !          2235:     case NOP_EXPR:
        !          2236:     case CONVERT_EXPR:
        !          2237:     case FLOAT_EXPR:
        !          2238:     case FIX_TRUNC_EXPR:
        !          2239:     case FIX_FLOOR_EXPR:
        !          2240:     case FIX_ROUND_EXPR:
        !          2241:     case FIX_CEIL_EXPR:
        !          2242:       result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
        !          2243:       break;
        !          2244: 
        !          2245:     case INDIRECT_REF:
        !          2246:       result = build_nt (INDIRECT_REF,
        !          2247:                         stabilize_reference_1 (TREE_OPERAND (ref, 0)));
        !          2248:       break;
        !          2249: 
        !          2250:     case COMPONENT_REF:
        !          2251:       result = build_nt (COMPONENT_REF,
        !          2252:                         stabilize_reference (TREE_OPERAND (ref, 0)),
        !          2253:                         TREE_OPERAND (ref, 1));
        !          2254:       break;
        !          2255: 
        !          2256:     case BIT_FIELD_REF:
        !          2257:       result = build_nt (BIT_FIELD_REF,
        !          2258:                         stabilize_reference (TREE_OPERAND (ref, 0)),
        !          2259:                         stabilize_reference_1 (TREE_OPERAND (ref, 1)),
        !          2260:                         stabilize_reference_1 (TREE_OPERAND (ref, 2)));
        !          2261:       break;
        !          2262: 
        !          2263:     case ARRAY_REF:
        !          2264:       result = build_nt (ARRAY_REF,
        !          2265:                         stabilize_reference (TREE_OPERAND (ref, 0)),
        !          2266:                         stabilize_reference_1 (TREE_OPERAND (ref, 1)));
        !          2267:       break;
        !          2268: 
        !          2269:       /* If arg isn't a kind of lvalue we recognize, make no change.
        !          2270:         Caller should recognize the error for an invalid lvalue.  */
        !          2271:     default:
        !          2272:       return ref;
        !          2273: 
        !          2274:     case ERROR_MARK:
        !          2275:       return error_mark_node;
        !          2276:     }
        !          2277: 
        !          2278:   TREE_TYPE (result) = TREE_TYPE (ref);
        !          2279:   TREE_READONLY (result) = TREE_READONLY (ref);
        !          2280:   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
        !          2281:   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
        !          2282:   TREE_RAISES (result) = TREE_RAISES (ref);
        !          2283: 
        !          2284:   return result;
        !          2285: }
        !          2286: 
        !          2287: /* Subroutine of stabilize_reference; this is called for subtrees of
        !          2288:    references.  Any expression with side-effects must be put in a SAVE_EXPR
        !          2289:    to ensure that it is only evaluated once.
        !          2290: 
        !          2291:    We don't put SAVE_EXPR nodes around everything, because assigning very
        !          2292:    simple expressions to temporaries causes us to miss good opportunities
        !          2293:    for optimizations.  Among other things, the opportunity to fold in the
        !          2294:    addition of a constant into an addressing mode often gets lost, e.g.
        !          2295:    "y[i+1] += x;".  In general, we take the approach that we should not make
        !          2296:    an assignment unless we are forced into it - i.e., that any non-side effect
        !          2297:    operator should be allowed, and that cse should take care of coalescing
        !          2298:    multiple utterances of the same expression should that prove fruitful.  */
        !          2299: 
        !          2300: static tree
        !          2301: stabilize_reference_1 (e)
        !          2302:      tree e;
        !          2303: {
        !          2304:   register tree result;
        !          2305:   register int length;
        !          2306:   register enum tree_code code = TREE_CODE (e);
        !          2307: 
        !          2308:   /* We cannot ignore const expressions because it might be a reference
        !          2309:      to a const array but whose index contains side-effects.  But we can
        !          2310:      ignore things that are actual constant or that already have been
        !          2311:      handled by this function.  */
        !          2312: 
        !          2313:   if (TREE_CONSTANT (e) || code == SAVE_EXPR)
        !          2314:     return e;
        !          2315: 
        !          2316:   switch (TREE_CODE_CLASS (code))
        !          2317:     {
        !          2318:     case 'x':
        !          2319:     case 't':
        !          2320:     case 'd':
        !          2321:     case 'b':
        !          2322:     case '<':
        !          2323:     case 's':
        !          2324:     case 'e':
        !          2325:     case 'r':
        !          2326:       /* If the expression has side-effects, then encase it in a SAVE_EXPR
        !          2327:         so that it will only be evaluated once.  */
        !          2328:       /* The reference (r) and comparison (<) classes could be handled as
        !          2329:         below, but it is generally faster to only evaluate them once.  */
        !          2330:       if (TREE_SIDE_EFFECTS (e))
        !          2331:        return save_expr (e);
        !          2332:       return e;
        !          2333: 
        !          2334:     case 'c':
        !          2335:       /* Constants need no processing.  In fact, we should never reach
        !          2336:         here.  */
        !          2337:       return e;
        !          2338:       
        !          2339:     case '2':
        !          2340:       /* Division is slow and tends to be compiled with jumps,
        !          2341:         especially the division by powers of 2 that is often
        !          2342:         found inside of an array reference.  So do it just once.  */
        !          2343:       if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
        !          2344:          || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
        !          2345:          || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
        !          2346:          || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
        !          2347:        return save_expr (e);
        !          2348:       /* Recursively stabilize each operand.  */
        !          2349:       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
        !          2350:                         stabilize_reference_1 (TREE_OPERAND (e, 1)));
        !          2351:       break;
        !          2352: 
        !          2353:     case '1':
        !          2354:       /* Recursively stabilize each operand.  */
        !          2355:       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)));
        !          2356:       break;
        !          2357:     }
        !          2358:   
        !          2359:   TREE_TYPE (result) = TREE_TYPE (e);
        !          2360:   TREE_READONLY (result) = TREE_READONLY (e);
        !          2361:   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
        !          2362:   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
        !          2363:   TREE_RAISES (result) = TREE_RAISES (e);
        !          2364: 
        !          2365:   return result;
        !          2366: }
        !          2367: 
        !          2368: /* Low-level constructors for expressions.  */
        !          2369: 
        !          2370: /* Build an expression of code CODE, data type TYPE,
        !          2371:    and operands as specified by the arguments ARG1 and following arguments.
        !          2372:    Expressions and reference nodes can be created this way.
        !          2373:    Constants, decls, types and misc nodes cannot be.  */
        !          2374: 
        !          2375: tree
        !          2376: build (va_alist)
        !          2377:      va_dcl
        !          2378: {
        !          2379:   va_list p;
        !          2380:   enum tree_code code;
        !          2381:   register tree t;
        !          2382:   register int length;
        !          2383:   register int i;
        !          2384: 
        !          2385:   va_start (p);
        !          2386: 
        !          2387:   code = va_arg (p, enum tree_code);
        !          2388:   t = make_node (code);
        !          2389:   length = tree_code_length[(int) code];
        !          2390:   TREE_TYPE (t) = va_arg (p, tree);
        !          2391: 
        !          2392:   if (length == 2)
        !          2393:     {
        !          2394:       /* This is equivalent to the loop below, but faster.  */
        !          2395:       register tree arg0 = va_arg (p, tree);
        !          2396:       register tree arg1 = va_arg (p, tree);
        !          2397:       TREE_OPERAND (t, 0) = arg0;
        !          2398:       TREE_OPERAND (t, 1) = arg1;
        !          2399:       if ((arg0 && TREE_SIDE_EFFECTS (arg0))
        !          2400:          || (arg1 && TREE_SIDE_EFFECTS (arg1)))
        !          2401:        TREE_SIDE_EFFECTS (t) = 1;
        !          2402:       TREE_RAISES (t)
        !          2403:        = (arg0 && TREE_RAISES (arg0)) || (arg1 && TREE_RAISES (arg1));
        !          2404:     }
        !          2405:   else if (length == 1)
        !          2406:     {
        !          2407:       register tree arg0 = va_arg (p, tree);
        !          2408: 
        !          2409:       /* Call build1 for this!  */
        !          2410:       if (TREE_CODE_CLASS (code) != 's')
        !          2411:        abort ();
        !          2412:       TREE_OPERAND (t, 0) = arg0;
        !          2413:       if (arg0 && TREE_SIDE_EFFECTS (arg0))
        !          2414:        TREE_SIDE_EFFECTS (t) = 1;
        !          2415:       TREE_RAISES (t) = (arg0 && TREE_RAISES (arg0));
        !          2416:     }
        !          2417:   else
        !          2418:     {
        !          2419:       for (i = 0; i < length; i++)
        !          2420:        {
        !          2421:          register tree operand = va_arg (p, tree);
        !          2422:          TREE_OPERAND (t, i) = operand;
        !          2423:          if (operand)
        !          2424:            {
        !          2425:              if (TREE_SIDE_EFFECTS (operand))
        !          2426:                TREE_SIDE_EFFECTS (t) = 1;
        !          2427:              if (TREE_RAISES (operand))
        !          2428:                TREE_RAISES (t) = 1;
        !          2429:            }
        !          2430:        }
        !          2431:     }
        !          2432:   va_end (p);
        !          2433:   return t;
        !          2434: }
        !          2435: 
        !          2436: /* Same as above, but only builds for unary operators.
        !          2437:    Saves lions share of calls to `build'; cuts down use
        !          2438:    of varargs, which is expensive for RISC machines.  */
        !          2439: tree
        !          2440: build1 (code, type, node)
        !          2441:      enum tree_code code;
        !          2442:      tree type;
        !          2443:      tree node;
        !          2444: {
        !          2445:   register struct obstack *obstack = current_obstack;
        !          2446:   register int i, length;
        !          2447:   register tree_node_kind kind;
        !          2448:   register tree t;
        !          2449: 
        !          2450: #ifdef GATHER_STATISTICS
        !          2451:   if (TREE_CODE_CLASS (code) == 'r')
        !          2452:     kind = r_kind;
        !          2453:   else
        !          2454:     kind = e_kind;
        !          2455: #endif
        !          2456: 
        !          2457:   obstack = expression_obstack;
        !          2458:   length = sizeof (struct tree_exp);
        !          2459: 
        !          2460:   t = (tree) obstack_alloc (obstack, length);
        !          2461: 
        !          2462: #ifdef GATHER_STATISTICS
        !          2463:   tree_node_counts[(int)kind]++;
        !          2464:   tree_node_sizes[(int)kind] += length;
        !          2465: #endif
        !          2466: 
        !          2467:   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
        !          2468:     ((int *) t)[i] = 0;
        !          2469: 
        !          2470:   TREE_TYPE (t) = type;
        !          2471:   TREE_SET_CODE (t, code);
        !          2472: 
        !          2473:   if (obstack == &permanent_obstack)
        !          2474:     TREE_PERMANENT (t) = 1;
        !          2475: 
        !          2476:   TREE_OPERAND (t, 0) = node;
        !          2477:   if (node)
        !          2478:     {
        !          2479:       if (TREE_SIDE_EFFECTS (node))
        !          2480:        TREE_SIDE_EFFECTS (t) = 1;
        !          2481:       if (TREE_RAISES (node))
        !          2482:        TREE_RAISES (t) = 1;
        !          2483:     }
        !          2484: 
        !          2485:   return t;
        !          2486: }
        !          2487: 
        !          2488: /* Similar except don't specify the TREE_TYPE
        !          2489:    and leave the TREE_SIDE_EFFECTS as 0.
        !          2490:    It is permissible for arguments to be null,
        !          2491:    or even garbage if their values do not matter.  */
        !          2492: 
        !          2493: tree
        !          2494: build_nt (va_alist)
        !          2495:      va_dcl
        !          2496: {
        !          2497:   va_list p;
        !          2498:   register enum tree_code code;
        !          2499:   register tree t;
        !          2500:   register int length;
        !          2501:   register int i;
        !          2502: 
        !          2503:   va_start (p);
        !          2504: 
        !          2505:   code = va_arg (p, enum tree_code);
        !          2506:   t = make_node (code);
        !          2507:   length = tree_code_length[(int) code];
        !          2508: 
        !          2509:   for (i = 0; i < length; i++)
        !          2510:     TREE_OPERAND (t, i) = va_arg (p, tree);
        !          2511: 
        !          2512:   va_end (p);
        !          2513:   return t;
        !          2514: }
        !          2515: 
        !          2516: /* Similar to `build_nt', except we build
        !          2517:    on the temp_decl_obstack, regardless.  */
        !          2518: 
        !          2519: tree
        !          2520: build_parse_node (va_alist)
        !          2521:      va_dcl
        !          2522: {
        !          2523:   register struct obstack *ambient_obstack = expression_obstack;
        !          2524:   va_list p;
        !          2525:   register enum tree_code code;
        !          2526:   register tree t;
        !          2527:   register int length;
        !          2528:   register int i;
        !          2529: 
        !          2530:   expression_obstack = &temp_decl_obstack;
        !          2531: 
        !          2532:   va_start (p);
        !          2533: 
        !          2534:   code = va_arg (p, enum tree_code);
        !          2535:   t = make_node (code);
        !          2536:   length = tree_code_length[(int) code];
        !          2537: 
        !          2538:   for (i = 0; i < length; i++)
        !          2539:     TREE_OPERAND (t, i) = va_arg (p, tree);
        !          2540: 
        !          2541:   va_end (p);
        !          2542:   expression_obstack = ambient_obstack;
        !          2543:   return t;
        !          2544: }
        !          2545: 
        !          2546: #if 0
        !          2547: /* Commented out because this wants to be done very
        !          2548:    differently.  See cp-lex.c.  */
        !          2549: tree
        !          2550: build_op_identifier (op1, op2)
        !          2551:      tree op1, op2;
        !          2552: {
        !          2553:   register tree t = make_node (OP_IDENTIFIER);
        !          2554:   TREE_PURPOSE (t) = op1;
        !          2555:   TREE_VALUE (t) = op2;
        !          2556:   return t;
        !          2557: }
        !          2558: #endif
        !          2559: 
        !          2560: /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
        !          2561:    We do NOT enter this node in any sort of symbol table.
        !          2562: 
        !          2563:    layout_decl is used to set up the decl's storage layout.
        !          2564:    Other slots are initialized to 0 or null pointers.  */
        !          2565: 
        !          2566: tree
        !          2567: build_decl (code, name, type)
        !          2568:      enum tree_code code;
        !          2569:      tree name, type;
        !          2570: {
        !          2571:   register tree t;
        !          2572: 
        !          2573:   t = make_node (code);
        !          2574: 
        !          2575: /*  if (type == error_mark_node)
        !          2576:     type = integer_type_node; */
        !          2577: /* That is not done, deliberately, so that having error_mark_node
        !          2578:    as the type can suppress useless errors in the use of this variable.  */
        !          2579: 
        !          2580:   DECL_NAME (t) = name;
        !          2581:   DECL_ASSEMBLER_NAME (t) = name;
        !          2582:   TREE_TYPE (t) = type;
        !          2583: 
        !          2584:   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
        !          2585:     layout_decl (t, 0);
        !          2586:   else if (code == FUNCTION_DECL)
        !          2587:     DECL_MODE (t) = FUNCTION_MODE;
        !          2588: 
        !          2589:   return t;
        !          2590: }
        !          2591: 
        !          2592: /* BLOCK nodes are used to represent the structure of binding contours
        !          2593:    and declarations, once those contours have been exited and their contents
        !          2594:    compiled.  This information is used for outputting debugging info.  */
        !          2595: 
        !          2596: tree
        !          2597: build_block (vars, tags, subblocks, supercontext, chain)
        !          2598:      tree vars, tags, subblocks, supercontext, chain;
        !          2599: {
        !          2600:   register tree block = make_node (BLOCK);
        !          2601:   BLOCK_VARS (block) = vars;
        !          2602:   BLOCK_TYPE_TAGS (block) = tags;
        !          2603:   BLOCK_SUBBLOCKS (block) = subblocks;
        !          2604:   BLOCK_SUPERCONTEXT (block) = supercontext;
        !          2605:   BLOCK_CHAIN (block) = chain;
        !          2606:   return block;
        !          2607: }
        !          2608: 
        !          2609: /* Return a type like TYPE except that its TYPE_READONLY is CONSTP
        !          2610:    and its TYPE_VOLATILE is VOLATILEP.
        !          2611: 
        !          2612:    Such variant types already made are recorded so that duplicates
        !          2613:    are not made.
        !          2614: 
        !          2615:    A variant types should never be used as the type of an expression.
        !          2616:    Always copy the variant information into the TREE_READONLY
        !          2617:    and TREE_THIS_VOLATILE of the expression, and then give the expression
        !          2618:    as its type the "main variant", the variant whose TYPE_READONLY
        !          2619:    and TYPE_VOLATILE are zero.  Use TYPE_MAIN_VARIANT to find the
        !          2620:    main variant.  */
        !          2621: 
        !          2622: tree
        !          2623: build_type_variant (type, constp, volatilep)
        !          2624:      tree type;
        !          2625:      int constp, volatilep;
        !          2626: {
        !          2627:   register tree t, m = TYPE_MAIN_VARIANT (type);
        !          2628:   register struct obstack *ambient_obstack = current_obstack;
        !          2629: 
        !          2630:   /* Treat any nonzero argument as 1.  */
        !          2631:   constp = !!constp;
        !          2632:   volatilep = !!volatilep;
        !          2633: 
        !          2634:   /* If not generating auxiliary info, search the chain of variants to see
        !          2635:      if there is already one there just like the one we need to have.  If so,
        !          2636:      use that existing one.
        !          2637: 
        !          2638:      We don't do this in the case where we are generating aux info because
        !          2639:      in that case we want each typedef names to get it's own distinct type
        !          2640:      node, even if the type of this new typedef is the same as some other
        !          2641:      (existing) type.  */
        !          2642: 
        !          2643:   if (!flag_gen_aux_info)
        !          2644:     for (t = m; t; t = TYPE_NEXT_VARIANT (t))
        !          2645:       if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t))
        !          2646:         return t;
        !          2647: 
        !          2648:   /* We need a new one.  */
        !          2649: 
        !          2650:   current_obstack = TYPE_OBSTACK (type);
        !          2651:   t = copy_node (type);
        !          2652:   current_obstack = ambient_obstack;
        !          2653: 
        !          2654:   TYPE_READONLY (t) = constp;
        !          2655:   TYPE_VOLATILE (t) = volatilep;
        !          2656:   TYPE_POINTER_TO (t) = 0;
        !          2657:   TYPE_REFERENCE_TO (t) = 0;
        !          2658: 
        !          2659:   /* Add this type to the chain of variants of TYPE.  */
        !          2660:   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
        !          2661:   TYPE_NEXT_VARIANT (m) = t;
        !          2662: 
        !          2663:   return t;
        !          2664: }
        !          2665: 
        !          2666: /* Give TYPE a new main variant: NEW_MAIN.
        !          2667:    This is the right thing to do only when something else
        !          2668:    about TYPE is modified in place.  */
        !          2669: 
        !          2670: tree
        !          2671: change_main_variant (type, new_main)
        !          2672:      tree type, new_main;
        !          2673: {
        !          2674:   tree t;
        !          2675:   tree omain = TYPE_MAIN_VARIANT (type);
        !          2676: 
        !          2677:   /* Remove TYPE from the TYPE_NEXT_VARIANT chain of its main variant.  */
        !          2678:   if (TYPE_NEXT_VARIANT (omain) == type)
        !          2679:     TYPE_NEXT_VARIANT (omain) = TYPE_NEXT_VARIANT (type);
        !          2680:   else
        !          2681:     for (t = TYPE_NEXT_VARIANT (omain); t && TYPE_NEXT_VARIANT (t);
        !          2682:         t = TYPE_NEXT_VARIANT (t))
        !          2683:       if (TYPE_NEXT_VARIANT (t) == type)
        !          2684:        {
        !          2685:          TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (type);
        !          2686:          break;
        !          2687:        }
        !          2688: 
        !          2689:   TYPE_MAIN_VARIANT (type) = new_main;
        !          2690:   TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (new_main);
        !          2691:   TYPE_NEXT_VARIANT (new_main) = type;
        !          2692: }
        !          2693: 
        !          2694: /* Create a new variant of TYPE, equivalent but distinct.
        !          2695:    This is so the caller can modify it.  */
        !          2696: 
        !          2697: tree
        !          2698: build_type_copy (type)
        !          2699:      tree type;
        !          2700: {
        !          2701:   register tree t, m = TYPE_MAIN_VARIANT (type);
        !          2702:   register struct obstack *ambient_obstack = current_obstack;
        !          2703: 
        !          2704:   current_obstack = TYPE_OBSTACK (type);
        !          2705:   t = copy_node (type);
        !          2706:   current_obstack = ambient_obstack;
        !          2707: 
        !          2708:   TYPE_POINTER_TO (t) = 0;
        !          2709:   TYPE_REFERENCE_TO (t) = 0;
        !          2710: 
        !          2711:   /* Add this type to the chain of variants of TYPE.  */
        !          2712:   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
        !          2713:   TYPE_NEXT_VARIANT (m) = t;
        !          2714: 
        !          2715:   return t;
        !          2716: }
        !          2717: 
        !          2718: /* Hashing of types so that we don't make duplicates.
        !          2719:    The entry point is `type_hash_canon'.  */
        !          2720: 
        !          2721: /* Each hash table slot is a bucket containing a chain
        !          2722:    of these structures.  */
        !          2723: 
        !          2724: struct type_hash
        !          2725: {
        !          2726:   struct type_hash *next;      /* Next structure in the bucket.  */
        !          2727:   int hashcode;                        /* Hash code of this type.  */
        !          2728:   tree type;                   /* The type recorded here.  */
        !          2729: };
        !          2730: 
        !          2731: /* Now here is the hash table.  When recording a type, it is added
        !          2732:    to the slot whose index is the hash code mod the table size.
        !          2733:    Note that the hash table is used for several kinds of types
        !          2734:    (function types, array types and array index range types, for now).
        !          2735:    While all these live in the same table, they are completely independent,
        !          2736:    and the hash code is computed differently for each of these.  */
        !          2737: 
        !          2738: #define TYPE_HASH_SIZE 59
        !          2739: struct type_hash *type_hash_table[TYPE_HASH_SIZE];
        !          2740: 
        !          2741: /* Here is how primitive or already-canonicalized types' hash
        !          2742:    codes are made.  */
        !          2743: #define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
        !          2744: 
        !          2745: /* Compute a hash code for a list of types (chain of TREE_LIST nodes
        !          2746:    with types in the TREE_VALUE slots), by adding the hash codes
        !          2747:    of the individual types.  */
        !          2748: 
        !          2749: int
        !          2750: type_hash_list (list)
        !          2751:      tree list;
        !          2752: {
        !          2753:   register int hashcode;
        !          2754:   register tree tail;
        !          2755:   for (hashcode = 0, tail = list; tail; tail = TREE_CHAIN (tail))
        !          2756:     hashcode += TYPE_HASH (TREE_VALUE (tail));
        !          2757:   return hashcode;
        !          2758: }
        !          2759: 
        !          2760: /* Look in the type hash table for a type isomorphic to TYPE.
        !          2761:    If one is found, return it.  Otherwise return 0.  */
        !          2762: 
        !          2763: tree
        !          2764: type_hash_lookup (hashcode, type)
        !          2765:      int hashcode;
        !          2766:      tree type;
        !          2767: {
        !          2768:   register struct type_hash *h;
        !          2769:   for (h = type_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
        !          2770:     if (h->hashcode == hashcode
        !          2771:        && TREE_CODE (h->type) == TREE_CODE (type)
        !          2772:        && TREE_TYPE (h->type) == TREE_TYPE (type)
        !          2773:        && (TYPE_MAX_VALUE (h->type) == TYPE_MAX_VALUE (type)
        !          2774:            || tree_int_cst_equal (TYPE_MAX_VALUE (h->type),
        !          2775:                                   TYPE_MAX_VALUE (type)))
        !          2776:        && (TYPE_MIN_VALUE (h->type) == TYPE_MIN_VALUE (type)
        !          2777:            || tree_int_cst_equal (TYPE_MIN_VALUE (h->type),
        !          2778:                                   TYPE_MIN_VALUE (type)))
        !          2779:        && (TYPE_DOMAIN (h->type) == TYPE_DOMAIN (type)
        !          2780:            || (TYPE_DOMAIN (h->type)
        !          2781:                && TREE_CODE (TYPE_DOMAIN (h->type)) == TREE_LIST
        !          2782:                && TYPE_DOMAIN (type)
        !          2783:                && TREE_CODE (TYPE_DOMAIN (type)) == TREE_LIST
        !          2784:                && type_list_equal (TYPE_DOMAIN (h->type), TYPE_DOMAIN (type)))))
        !          2785:       return h->type;
        !          2786:   return 0;
        !          2787: }
        !          2788: 
        !          2789: /* Add an entry to the type-hash-table
        !          2790:    for a type TYPE whose hash code is HASHCODE.  */
        !          2791: 
        !          2792: void
        !          2793: type_hash_add (hashcode, type)
        !          2794:      int hashcode;
        !          2795:      tree type;
        !          2796: {
        !          2797:   register struct type_hash *h;
        !          2798: 
        !          2799:   h = (struct type_hash *) oballoc (sizeof (struct type_hash));
        !          2800:   h->hashcode = hashcode;
        !          2801:   h->type = type;
        !          2802:   h->next = type_hash_table[hashcode % TYPE_HASH_SIZE];
        !          2803:   type_hash_table[hashcode % TYPE_HASH_SIZE] = h;
        !          2804: }
        !          2805: 
        !          2806: /* Given TYPE, and HASHCODE its hash code, return the canonical
        !          2807:    object for an identical type if one already exists.
        !          2808:    Otherwise, return TYPE, and record it as the canonical object
        !          2809:    if it is a permanent object.
        !          2810: 
        !          2811:    To use this function, first create a type of the sort you want.
        !          2812:    Then compute its hash code from the fields of the type that
        !          2813:    make it different from other similar types.
        !          2814:    Then call this function and use the value.
        !          2815:    This function frees the type you pass in if it is a duplicate.  */
        !          2816: 
        !          2817: /* Set to 1 to debug without canonicalization.  Never set by program.  */
        !          2818: int debug_no_type_hash = 0;
        !          2819: 
        !          2820: tree
        !          2821: type_hash_canon (hashcode, type)
        !          2822:      int hashcode;
        !          2823:      tree type;
        !          2824: {
        !          2825:   tree t1;
        !          2826: 
        !          2827:   if (debug_no_type_hash)
        !          2828:     return type;
        !          2829: 
        !          2830:   t1 = type_hash_lookup (hashcode, type);
        !          2831:   if (t1 != 0)
        !          2832:     {
        !          2833:       struct obstack *o
        !          2834:        = TREE_PERMANENT (type) ? &permanent_obstack : saveable_obstack;
        !          2835:       obstack_free (o, type);
        !          2836: #ifdef GATHER_STATISTICS
        !          2837:       tree_node_counts[(int)t_kind]--;
        !          2838:       tree_node_sizes[(int)t_kind] -= sizeof (struct tree_type);
        !          2839: #endif
        !          2840:       return t1;
        !          2841:     }
        !          2842: 
        !          2843:   /* If this is a new type, record it for later reuse.  */
        !          2844:   if (current_obstack == &permanent_obstack)
        !          2845:     type_hash_add (hashcode, type);
        !          2846: 
        !          2847:   return type;
        !          2848: }
        !          2849: 
        !          2850: /* Given two lists of types
        !          2851:    (chains of TREE_LIST nodes with types in the TREE_VALUE slots)
        !          2852:    return 1 if the lists contain the same types in the same order.
        !          2853:    Also, the TREE_PURPOSEs must match.  */
        !          2854: 
        !          2855: int
        !          2856: type_list_equal (l1, l2)
        !          2857:      tree l1, l2;
        !          2858: {
        !          2859:   register tree t1, t2;
        !          2860:   for (t1 = l1, t2 = l2; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
        !          2861:     {
        !          2862:       if (TREE_VALUE (t1) != TREE_VALUE (t2))
        !          2863:        return 0;
        !          2864:       if (TREE_PURPOSE (t1) != TREE_PURPOSE (t2))
        !          2865:        {
        !          2866:          int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
        !          2867:          if (cmp < 0)
        !          2868:            abort ();
        !          2869:          if (cmp == 0)
        !          2870:            return 0;
        !          2871:        }
        !          2872:     }
        !          2873: 
        !          2874:   return t1 == t2;
        !          2875: }
        !          2876: 
        !          2877: /* Nonzero if integer constants T1 and T2
        !          2878:    represent the same constant value.  */
        !          2879: 
        !          2880: int
        !          2881: tree_int_cst_equal (t1, t2)
        !          2882:      tree t1, t2;
        !          2883: {
        !          2884:   if (t1 == t2)
        !          2885:     return 1;
        !          2886:   if (t1 == 0 || t2 == 0)
        !          2887:     return 0;
        !          2888:   if (TREE_CODE (t1) == INTEGER_CST
        !          2889:       && TREE_CODE (t2) == INTEGER_CST
        !          2890:       && TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
        !          2891:       && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2))
        !          2892:     return 1;
        !          2893:   return 0;
        !          2894: }
        !          2895: 
        !          2896: /* Nonzero if integer constants T1 and T2 represent values that satisfy <.
        !          2897:    The precise way of comparison depends on their data type.  */
        !          2898: 
        !          2899: int
        !          2900: tree_int_cst_lt (t1, t2)
        !          2901:      tree t1, t2;
        !          2902: {
        !          2903:   if (t1 == t2)
        !          2904:     return 0;
        !          2905: 
        !          2906:   if (!TREE_UNSIGNED (TREE_TYPE (t1)))
        !          2907:     return INT_CST_LT (t1, t2);
        !          2908:   return INT_CST_LT_UNSIGNED (t1, t2);
        !          2909: }
        !          2910: 
        !          2911: /* Compare two constructor-element-type constants.  */
        !          2912: int
        !          2913: simple_cst_list_equal (l1, l2)
        !          2914:      tree l1, l2;
        !          2915: {
        !          2916:   while (l1 != NULL_TREE && l2 != NULL_TREE)
        !          2917:     {
        !          2918:       int cmp = simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2));
        !          2919:       if (cmp < 0)
        !          2920:        abort ();
        !          2921:       if (cmp == 0)
        !          2922:        return 0;
        !          2923:       l1 = TREE_CHAIN (l1);
        !          2924:       l2 = TREE_CHAIN (l2);
        !          2925:     }
        !          2926:   return (l1 == l2);
        !          2927: }
        !          2928: 
        !          2929: /* Return truthvalue of whether T1 is the same tree structure as T2.
        !          2930:    Return 1 if they are the same.
        !          2931:    Return 0 if they are understandably different.
        !          2932:    Return -1 if either contains tree structure not understood by
        !          2933:    this function.  */
        !          2934: 
        !          2935: int
        !          2936: simple_cst_equal (t1, t2)
        !          2937:      tree t1, t2;
        !          2938: {
        !          2939:   register enum tree_code code1, code2;
        !          2940:   int cmp;
        !          2941: 
        !          2942:   if (t1 == t2)
        !          2943:     return 1;
        !          2944:   if (t1 == 0 || t2 == 0)
        !          2945:     return 0;
        !          2946: 
        !          2947:   code1 = TREE_CODE (t1);
        !          2948:   code2 = TREE_CODE (t2);
        !          2949: 
        !          2950:   if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR)
        !          2951:     if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR)
        !          2952:       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          2953:     else
        !          2954:       return simple_cst_equal (TREE_OPERAND (t1, 0), t2);
        !          2955:   else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR
        !          2956:           || code2 == NON_LVALUE_EXPR)
        !          2957:     return simple_cst_equal (t1, TREE_OPERAND (t2, 0));
        !          2958: 
        !          2959:   if (code1 != code2)
        !          2960:     return 0;
        !          2961: 
        !          2962:   switch (code1)
        !          2963:     {
        !          2964:     case INTEGER_CST:
        !          2965:       return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
        !          2966:        && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
        !          2967: 
        !          2968:     case REAL_CST:
        !          2969:       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
        !          2970: 
        !          2971:     case STRING_CST:
        !          2972:       return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
        !          2973:        && !bcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
        !          2974:                  TREE_STRING_LENGTH (t1));
        !          2975: 
        !          2976:     case CONSTRUCTOR:
        !          2977:       abort ();
        !          2978: 
        !          2979:     case SAVE_EXPR:
        !          2980:       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          2981: 
        !          2982:     case CALL_EXPR:
        !          2983:       cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          2984:       if (cmp <= 0)
        !          2985:        return cmp;
        !          2986:       return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
        !          2987: 
        !          2988:     case TARGET_EXPR:
        !          2989:       /* Special case: if either target is an unallocated VAR_DECL,
        !          2990:         it means that it's going to be unified with whatever the
        !          2991:         TARGET_EXPR is really supposed to initialize, so treat it
        !          2992:         as being equivalent to anything.  */
        !          2993:       if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
        !          2994:           && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
        !          2995:           && DECL_RTL (TREE_OPERAND (t1, 0)) == 0)
        !          2996:          || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
        !          2997:              && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
        !          2998:              && DECL_RTL (TREE_OPERAND (t2, 0)) == 0))
        !          2999:        cmp = 1;
        !          3000:       else
        !          3001:        cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          3002:       if (cmp <= 0)
        !          3003:        return cmp;
        !          3004:       return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
        !          3005: 
        !          3006:     case WITH_CLEANUP_EXPR:
        !          3007:       cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          3008:       if (cmp <= 0)
        !          3009:        return cmp;
        !          3010:       return simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t1, 2));
        !          3011: 
        !          3012:     case COMPONENT_REF:
        !          3013:       if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
        !          3014:        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
        !          3015:       return 0;
        !          3016: 
        !          3017:     case VAR_DECL:
        !          3018:     case PARM_DECL:
        !          3019:     case CONST_DECL:
        !          3020:     case FUNCTION_DECL:
        !          3021:       return 0;
        !          3022:     }
        !          3023: 
        !          3024:   /* This general rule works for most tree codes.
        !          3025:      All exceptions should be handled above.  */
        !          3026: 
        !          3027:   switch (TREE_CODE_CLASS (code1))
        !          3028:     {
        !          3029:       int i;
        !          3030:     case '1':
        !          3031:     case '2':
        !          3032:     case '<':
        !          3033:     case 'e':
        !          3034:     case 'r':
        !          3035:     case 's':
        !          3036:       cmp = 1;
        !          3037:       for (i=0; i<tree_code_length[(int) code1]; ++i)
        !          3038:        {
        !          3039:          cmp = simple_cst_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
        !          3040:          if (cmp <= 0)
        !          3041:            return cmp;
        !          3042:        }
        !          3043:       return cmp;
        !          3044:     }
        !          3045: 
        !          3046:   return -1;
        !          3047: }
        !          3048: 
        !          3049: /* Constructors for pointer, array and function types.
        !          3050:    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
        !          3051:    constructed by language-dependent code, not here.)  */
        !          3052: 
        !          3053: /* Construct, lay out and return the type of pointers to TO_TYPE.
        !          3054:    If such a type has already been constructed, reuse it.  */
        !          3055: 
        !          3056: tree
        !          3057: build_pointer_type (to_type)
        !          3058:      tree to_type;
        !          3059: {
        !          3060:   register tree t = TYPE_POINTER_TO (to_type);
        !          3061: 
        !          3062:   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
        !          3063: 
        !          3064:   if (t)
        !          3065:     return t;
        !          3066: 
        !          3067:   /* We need a new one.  Put this in the same obstack as TO_TYPE.   */
        !          3068:   push_obstacks (TYPE_OBSTACK (to_type), TYPE_OBSTACK (to_type));
        !          3069:   t = make_node (POINTER_TYPE);
        !          3070:   pop_obstacks ();
        !          3071: 
        !          3072:   TREE_TYPE (t) = to_type;
        !          3073: 
        !          3074:   /* Record this type as the pointer to TO_TYPE.  */
        !          3075:   TYPE_POINTER_TO (to_type) = t;
        !          3076: 
        !          3077:   /* Lay out the type.  This function has many callers that are concerned
        !          3078:      with expression-construction, and this simplifies them all.
        !          3079:      Also, it guarantees the TYPE_SIZE is in the same obstack as the type.  */
        !          3080:   layout_type (t);
        !          3081: 
        !          3082:   return t;
        !          3083: }
        !          3084: 
        !          3085: /* Create a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE.
        !          3086:    MAXVAL should be the maximum value in the domain
        !          3087:    (one less than the length of the array).  */
        !          3088: 
        !          3089: tree
        !          3090: build_index_type (maxval)
        !          3091:      tree maxval;
        !          3092: {
        !          3093:   register tree itype = make_node (INTEGER_TYPE);
        !          3094:   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
        !          3095:   TYPE_MIN_VALUE (itype) = build_int_2 (0, 0);
        !          3096:   TREE_TYPE (TYPE_MIN_VALUE (itype)) = sizetype;
        !          3097:   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
        !          3098:   TYPE_MODE (itype) = TYPE_MODE (sizetype);
        !          3099:   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
        !          3100:   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
        !          3101:   if (TREE_CODE (maxval) == INTEGER_CST)
        !          3102:     {
        !          3103:       int maxint = (int) TREE_INT_CST_LOW (maxval);
        !          3104:       /* If the domain should be empty, make sure the maxval
        !          3105:         remains -1 and is not spoiled by truncation.  */
        !          3106:       if (INT_CST_LT (maxval, integer_zero_node))
        !          3107:        {
        !          3108:          TYPE_MAX_VALUE (itype) = build_int_2 (-1, -1);
        !          3109:          TREE_TYPE (TYPE_MAX_VALUE (itype)) = sizetype;
        !          3110:        }
        !          3111:       return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
        !          3112:     }
        !          3113:   else
        !          3114:     return itype;
        !          3115: }
        !          3116: 
        !          3117: /* Create a range of some discrete type TYPE (an INTEGER_TYPE,
        !          3118:    ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with
        !          3119:    low bound LOWVAL and high bound HIGHVAL.
        !          3120:    if TYPE==NULL_TREE, sizetype is used. */
        !          3121: 
        !          3122: tree
        !          3123: build_range_type (type, lowval, highval)
        !          3124:      tree type, lowval, highval;
        !          3125: {
        !          3126:   register tree itype = make_node (INTEGER_TYPE);
        !          3127:   TREE_TYPE (itype) = type;
        !          3128:   if (type == NULL_TREE)
        !          3129:     type = sizetype;
        !          3130:   TYPE_PRECISION (itype) = TYPE_PRECISION (type);
        !          3131:   TYPE_MIN_VALUE (itype) = convert (type, lowval);
        !          3132:   TYPE_MAX_VALUE (itype) = convert (type, highval);
        !          3133:   TYPE_MODE (itype) = TYPE_MODE (type);
        !          3134:   TYPE_SIZE (itype) = TYPE_SIZE (type);
        !          3135:   TYPE_ALIGN (itype) = TYPE_ALIGN (type);
        !          3136:   if ((TREE_CODE (lowval) == INTEGER_CST)
        !          3137:       && (TREE_CODE (highval) == INTEGER_CST))
        !          3138:     {
        !          3139:       HOST_WIDE_INT highint = TREE_INT_CST_LOW (highval);
        !          3140:       HOST_WIDE_INT lowint = TREE_INT_CST_LOW (lowval);
        !          3141:       int maxint = (int) (highint - lowint);
        !          3142:       return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
        !          3143:     }
        !          3144:   else
        !          3145:     return itype;
        !          3146: }
        !          3147: 
        !          3148: /* Just like build_index_type, but takes lowval and highval instead
        !          3149:    of just highval (maxval). */
        !          3150: 
        !          3151: tree
        !          3152: build_index_2_type (lowval,highval)
        !          3153:      tree lowval, highval;
        !          3154: {
        !          3155:   return build_range_type (NULL_TREE, lowval, highval);
        !          3156: }
        !          3157: 
        !          3158: /* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense).
        !          3159:    Needed because when index types are not hashed, equal index types
        !          3160:    built at different times appear distinct, even though structurally,
        !          3161:    they are not.  */
        !          3162: 
        !          3163: int
        !          3164: index_type_equal (itype1, itype2)
        !          3165:      tree itype1, itype2;
        !          3166: {
        !          3167:   if (TREE_CODE (itype1) != TREE_CODE (itype2))
        !          3168:     return 0;
        !          3169:   if (TREE_CODE (itype1) == INTEGER_TYPE)
        !          3170:     {
        !          3171:       if (TYPE_PRECISION (itype1) != TYPE_PRECISION (itype2)
        !          3172:          || TYPE_MODE (itype1) != TYPE_MODE (itype2)
        !          3173:          || ! simple_cst_equal (TYPE_SIZE (itype1), TYPE_SIZE (itype2))
        !          3174:          || TYPE_ALIGN (itype1) != TYPE_ALIGN (itype2))
        !          3175:        return 0;
        !          3176:       if (simple_cst_equal (TYPE_MIN_VALUE (itype1), TYPE_MIN_VALUE (itype2))
        !          3177:          && simple_cst_equal (TYPE_MAX_VALUE (itype1), TYPE_MAX_VALUE (itype2)))
        !          3178:        return 1;
        !          3179:     }
        !          3180:   return 0;
        !          3181: }
        !          3182: 
        !          3183: /* Construct, lay out and return the type of arrays of elements with ELT_TYPE
        !          3184:    and number of elements specified by the range of values of INDEX_TYPE.
        !          3185:    If such a type has already been constructed, reuse it.  */
        !          3186: 
        !          3187: tree
        !          3188: build_array_type (elt_type, index_type)
        !          3189:      tree elt_type, index_type;
        !          3190: {
        !          3191:   register tree t;
        !          3192:   int hashcode;
        !          3193: 
        !          3194:   if (TREE_CODE (elt_type) == FUNCTION_TYPE)
        !          3195:     {
        !          3196:       error ("arrays of functions are not meaningful");
        !          3197:       elt_type = integer_type_node;
        !          3198:     }
        !          3199: 
        !          3200:   /* Make sure TYPE_POINTER_TO (elt_type) is filled in.  */
        !          3201:   build_pointer_type (elt_type);
        !          3202: 
        !          3203:   /* Allocate the array after the pointer type,
        !          3204:      in case we free it in type_hash_canon.  */
        !          3205:   t = make_node (ARRAY_TYPE);
        !          3206:   TREE_TYPE (t) = elt_type;
        !          3207:   TYPE_DOMAIN (t) = index_type;
        !          3208: 
        !          3209:   if (index_type == 0)
        !          3210:     {
        !          3211:       return t;
        !          3212:     }
        !          3213: 
        !          3214:   hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
        !          3215:   t = type_hash_canon (hashcode, t);
        !          3216: 
        !          3217: #if 0 /* This led to crashes, because it could put a temporary node
        !          3218:         on the TYPE_NEXT_VARIANT chain of a permanent one.  */
        !          3219:   /* The main variant of an array type should always
        !          3220:      be an array whose element type is the main variant.  */
        !          3221:   if (elt_type != TYPE_MAIN_VARIANT (elt_type))
        !          3222:     change_main_variant (t, build_array_type (TYPE_MAIN_VARIANT (elt_type),
        !          3223:                                              index_type));
        !          3224: #endif
        !          3225: 
        !          3226:   if (TYPE_SIZE (t) == 0)
        !          3227:     layout_type (t);
        !          3228:   return t;
        !          3229: }
        !          3230: 
        !          3231: /* Construct, lay out and return
        !          3232:    the type of functions returning type VALUE_TYPE
        !          3233:    given arguments of types ARG_TYPES.
        !          3234:    ARG_TYPES is a chain of TREE_LIST nodes whose TREE_VALUEs
        !          3235:    are data type nodes for the arguments of the function.
        !          3236:    If such a type has already been constructed, reuse it.  */
        !          3237: 
        !          3238: tree
        !          3239: build_function_type (value_type, arg_types)
        !          3240:      tree value_type, arg_types;
        !          3241: {
        !          3242:   register tree t;
        !          3243:   int hashcode;
        !          3244: 
        !          3245:   if (TREE_CODE (value_type) == FUNCTION_TYPE)
        !          3246:     {
        !          3247:       error ("function return type cannot be function");
        !          3248:       value_type = integer_type_node;
        !          3249:     }
        !          3250: 
        !          3251:   /* Make a node of the sort we want.  */
        !          3252:   t = make_node (FUNCTION_TYPE);
        !          3253:   TREE_TYPE (t) = value_type;
        !          3254:   TYPE_ARG_TYPES (t) = arg_types;
        !          3255: 
        !          3256:   /* If we already have such a type, use the old one and free this one.  */
        !          3257:   hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types);
        !          3258:   t = type_hash_canon (hashcode, t);
        !          3259: 
        !          3260:   if (TYPE_SIZE (t) == 0)
        !          3261:     layout_type (t);
        !          3262:   return t;
        !          3263: }
        !          3264: 
        !          3265: /* Build the node for the type of references-to-TO_TYPE.  */
        !          3266: 
        !          3267: tree
        !          3268: build_reference_type (to_type)
        !          3269:      tree to_type;
        !          3270: {
        !          3271:   register tree t = TYPE_REFERENCE_TO (to_type);
        !          3272:   register struct obstack *ambient_obstack = current_obstack;
        !          3273:   register struct obstack *ambient_saveable_obstack = saveable_obstack;
        !          3274: 
        !          3275:   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
        !          3276: 
        !          3277:   if (t)
        !          3278:     return t;
        !          3279: 
        !          3280:   /* We need a new one.  If TO_TYPE is permanent, make this permanent too.  */
        !          3281:   if (TREE_PERMANENT (to_type))
        !          3282:     {
        !          3283:       current_obstack = &permanent_obstack;
        !          3284:       saveable_obstack = &permanent_obstack;
        !          3285:     }
        !          3286: 
        !          3287:   t = make_node (REFERENCE_TYPE);
        !          3288:   TREE_TYPE (t) = to_type;
        !          3289: 
        !          3290:   /* Record this type as the pointer to TO_TYPE.  */
        !          3291:   TYPE_REFERENCE_TO (to_type) = t;
        !          3292: 
        !          3293:   layout_type (t);
        !          3294: 
        !          3295:   current_obstack = ambient_obstack;
        !          3296:   saveable_obstack = ambient_saveable_obstack;
        !          3297:   return t;
        !          3298: }
        !          3299: 
        !          3300: /* Construct, lay out and return the type of methods belonging to class
        !          3301:    BASETYPE and whose arguments and values are described by TYPE.
        !          3302:    If that type exists already, reuse it.
        !          3303:    TYPE must be a FUNCTION_TYPE node.  */
        !          3304: 
        !          3305: tree
        !          3306: build_method_type (basetype, type)
        !          3307:      tree basetype, type;
        !          3308: {
        !          3309:   register tree t;
        !          3310:   int hashcode;
        !          3311: 
        !          3312:   /* Make a node of the sort we want.  */
        !          3313:   t = make_node (METHOD_TYPE);
        !          3314: 
        !          3315:   if (TREE_CODE (type) != FUNCTION_TYPE)
        !          3316:     abort ();
        !          3317: 
        !          3318:   TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
        !          3319:   TREE_TYPE (t) = TREE_TYPE (type);
        !          3320: 
        !          3321:   /* The actual arglist for this function includes a "hidden" argument
        !          3322:      which is "this".  Put it into the list of argument types.  */
        !          3323: 
        !          3324:   TYPE_ARG_TYPES (t)
        !          3325:     = tree_cons (NULL_TREE,
        !          3326:                 build_pointer_type (basetype), TYPE_ARG_TYPES (type));
        !          3327: 
        !          3328:   /* If we already have such a type, use the old one and free this one.  */
        !          3329:   hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
        !          3330:   t = type_hash_canon (hashcode, t);
        !          3331: 
        !          3332:   if (TYPE_SIZE (t) == 0)
        !          3333:     layout_type (t);
        !          3334: 
        !          3335:   return t;
        !          3336: }
        !          3337: 
        !          3338: /* Construct, lay out and return the type of offsets to a value
        !          3339:    of type TYPE, within an object of type BASETYPE.
        !          3340:    If a suitable offset type exists already, reuse it.  */
        !          3341: 
        !          3342: tree
        !          3343: build_offset_type (basetype, type)
        !          3344:      tree basetype, type;
        !          3345: {
        !          3346:   register tree t;
        !          3347:   int hashcode;
        !          3348: 
        !          3349:   /* Make a node of the sort we want.  */
        !          3350:   t = make_node (OFFSET_TYPE);
        !          3351: 
        !          3352:   TYPE_OFFSET_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
        !          3353:   TREE_TYPE (t) = type;
        !          3354: 
        !          3355:   /* If we already have such a type, use the old one and free this one.  */
        !          3356:   hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
        !          3357:   t = type_hash_canon (hashcode, t);
        !          3358: 
        !          3359:   if (TYPE_SIZE (t) == 0)
        !          3360:     layout_type (t);
        !          3361: 
        !          3362:   return t;
        !          3363: }
        !          3364: 
        !          3365: /* Create a complex type whose components are COMPONENT_TYPE.  */
        !          3366: 
        !          3367: tree
        !          3368: build_complex_type (component_type)
        !          3369:      tree component_type;
        !          3370: {
        !          3371:   register tree t;
        !          3372:   int hashcode;
        !          3373: 
        !          3374:   /* Make a node of the sort we want.  */
        !          3375:   t = make_node (COMPLEX_TYPE);
        !          3376: 
        !          3377:   TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
        !          3378:   TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type);
        !          3379:   TYPE_READONLY (t) = TYPE_READONLY (component_type);
        !          3380: 
        !          3381:   /* If we already have such a type, use the old one and free this one.  */
        !          3382:   hashcode = TYPE_HASH (component_type);
        !          3383:   t = type_hash_canon (hashcode, t);
        !          3384: 
        !          3385:   if (TYPE_SIZE (t) == 0)
        !          3386:     layout_type (t);
        !          3387: 
        !          3388:   return t;
        !          3389: }
        !          3390: 
        !          3391: /* Return OP, stripped of any conversions to wider types as much as is safe.
        !          3392:    Converting the value back to OP's type makes a value equivalent to OP.
        !          3393: 
        !          3394:    If FOR_TYPE is nonzero, we return a value which, if converted to
        !          3395:    type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE.
        !          3396: 
        !          3397:    If FOR_TYPE is nonzero, unaligned bit-field references may be changed to the
        !          3398:    narrowest type that can hold the value, even if they don't exactly fit.
        !          3399:    Otherwise, bit-field references are changed to a narrower type
        !          3400:    only if they can be fetched directly from memory in that type.
        !          3401: 
        !          3402:    OP must have integer, real or enumeral type.  Pointers are not allowed!
        !          3403: 
        !          3404:    There are some cases where the obvious value we could return
        !          3405:    would regenerate to OP if converted to OP's type, 
        !          3406:    but would not extend like OP to wider types.
        !          3407:    If FOR_TYPE indicates such extension is contemplated, we eschew such values.
        !          3408:    For example, if OP is (unsigned short)(signed char)-1,
        !          3409:    we avoid returning (signed char)-1 if FOR_TYPE is int,
        !          3410:    even though extending that to an unsigned short would regenerate OP,
        !          3411:    since the result of extending (signed char)-1 to (int)
        !          3412:    is different from (int) OP.  */
        !          3413: 
        !          3414: tree
        !          3415: get_unwidened (op, for_type)
        !          3416:      register tree op;
        !          3417:      tree for_type;
        !          3418: {
        !          3419:   /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension.  */
        !          3420:   /* TYPE_PRECISION is safe in place of type_precision since
        !          3421:      pointer types are not allowed.  */
        !          3422:   register tree type = TREE_TYPE (op);
        !          3423:   register unsigned final_prec
        !          3424:     = TYPE_PRECISION (for_type != 0 ? for_type : type);
        !          3425:   register int uns
        !          3426:     = (for_type != 0 && for_type != type
        !          3427:        && final_prec > TYPE_PRECISION (type)
        !          3428:        && TREE_UNSIGNED (type));
        !          3429:   register tree win = op;
        !          3430: 
        !          3431:   while (TREE_CODE (op) == NOP_EXPR)
        !          3432:     {
        !          3433:       register int bitschange
        !          3434:        = TYPE_PRECISION (TREE_TYPE (op))
        !          3435:          - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
        !          3436: 
        !          3437:       /* Truncations are many-one so cannot be removed.
        !          3438:         Unless we are later going to truncate down even farther.  */
        !          3439:       if (bitschange < 0
        !          3440:          && final_prec > TYPE_PRECISION (TREE_TYPE (op)))
        !          3441:        break;
        !          3442: 
        !          3443:       /* See what's inside this conversion.  If we decide to strip it,
        !          3444:         we will set WIN.  */
        !          3445:       op = TREE_OPERAND (op, 0);
        !          3446: 
        !          3447:       /* If we have not stripped any zero-extensions (uns is 0),
        !          3448:         we can strip any kind of extension.
        !          3449:         If we have previously stripped a zero-extension,
        !          3450:         only zero-extensions can safely be stripped.
        !          3451:         Any extension can be stripped if the bits it would produce
        !          3452:         are all going to be discarded later by truncating to FOR_TYPE.  */
        !          3453: 
        !          3454:       if (bitschange > 0)
        !          3455:        {
        !          3456:          if (! uns || final_prec <= TYPE_PRECISION (TREE_TYPE (op)))
        !          3457:            win = op;
        !          3458:          /* TREE_UNSIGNED says whether this is a zero-extension.
        !          3459:             Let's avoid computing it if it does not affect WIN
        !          3460:             and if UNS will not be needed again.  */
        !          3461:          if ((uns || TREE_CODE (op) == NOP_EXPR)
        !          3462:              && TREE_UNSIGNED (TREE_TYPE (op)))
        !          3463:            {
        !          3464:              uns = 1;
        !          3465:              win = op;
        !          3466:            }
        !          3467:        }
        !          3468:     }
        !          3469: 
        !          3470:   if (TREE_CODE (op) == COMPONENT_REF
        !          3471:       /* Since type_for_size always gives an integer type.  */
        !          3472:       && TREE_CODE (type) != REAL_TYPE)
        !          3473:     {
        !          3474:       unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1)));
        !          3475:       type = type_for_size (innerprec, TREE_UNSIGNED (TREE_OPERAND (op, 1)));
        !          3476: 
        !          3477:       /* We can get this structure field in the narrowest type it fits in.
        !          3478:         If FOR_TYPE is 0, do this only for a field that matches the
        !          3479:         narrower type exactly and is aligned for it
        !          3480:         The resulting extension to its nominal type (a fullword type)
        !          3481:         must fit the same conditions as for other extensions.  */
        !          3482: 
        !          3483:       if (innerprec < TYPE_PRECISION (TREE_TYPE (op))
        !          3484:          && (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
        !          3485:          && (! uns || final_prec <= innerprec
        !          3486:              || TREE_UNSIGNED (TREE_OPERAND (op, 1)))
        !          3487:          && type != 0)
        !          3488:        {
        !          3489:          win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0),
        !          3490:                       TREE_OPERAND (op, 1));
        !          3491:          TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
        !          3492:          TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
        !          3493:          TREE_RAISES (win) = TREE_RAISES (op);
        !          3494:        }
        !          3495:     }
        !          3496:   return win;
        !          3497: }
        !          3498: 
        !          3499: /* Return OP or a simpler expression for a narrower value
        !          3500:    which can be sign-extended or zero-extended to give back OP.
        !          3501:    Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended
        !          3502:    or 0 if the value should be sign-extended.  */
        !          3503: 
        !          3504: tree
        !          3505: get_narrower (op, unsignedp_ptr)
        !          3506:      register tree op;
        !          3507:      int *unsignedp_ptr;
        !          3508: {
        !          3509:   register int uns = 0;
        !          3510:   int first = 1;
        !          3511:   register tree win = op;
        !          3512: 
        !          3513:   while (TREE_CODE (op) == NOP_EXPR)
        !          3514:     {
        !          3515:       register int bitschange
        !          3516:        = TYPE_PRECISION (TREE_TYPE (op))
        !          3517:          - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
        !          3518: 
        !          3519:       /* Truncations are many-one so cannot be removed.  */
        !          3520:       if (bitschange < 0)
        !          3521:        break;
        !          3522: 
        !          3523:       /* See what's inside this conversion.  If we decide to strip it,
        !          3524:         we will set WIN.  */
        !          3525:       op = TREE_OPERAND (op, 0);
        !          3526: 
        !          3527:       if (bitschange > 0)
        !          3528:        {
        !          3529:          /* An extension: the outermost one can be stripped,
        !          3530:             but remember whether it is zero or sign extension.  */
        !          3531:          if (first)
        !          3532:            uns = TREE_UNSIGNED (TREE_TYPE (op));
        !          3533:          /* Otherwise, if a sign extension has been stripped,
        !          3534:             only sign extensions can now be stripped;
        !          3535:             if a zero extension has been stripped, only zero-extensions.  */
        !          3536:          else if (uns != TREE_UNSIGNED (TREE_TYPE (op)))
        !          3537:            break;
        !          3538:          first = 0;
        !          3539:        }
        !          3540:       else /* bitschange == 0 */
        !          3541:        {
        !          3542:          /* A change in nominal type can always be stripped, but we must
        !          3543:             preserve the unsignedness.  */
        !          3544:          if (first)
        !          3545:            uns = TREE_UNSIGNED (TREE_TYPE (op));
        !          3546:          first = 0;
        !          3547:        }
        !          3548: 
        !          3549:       win = op;
        !          3550:     }
        !          3551: 
        !          3552:   if (TREE_CODE (op) == COMPONENT_REF
        !          3553:       /* Since type_for_size always gives an integer type.  */
        !          3554:       && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE)
        !          3555:     {
        !          3556:       unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1)));
        !          3557:       tree type = type_for_size (innerprec, TREE_UNSIGNED (op));
        !          3558: 
        !          3559:       /* We can get this structure field in a narrower type that fits it,
        !          3560:         but the resulting extension to its nominal type (a fullword type)
        !          3561:         must satisfy the same conditions as for other extensions.
        !          3562: 
        !          3563:         Do this only for fields that are aligned (not bit-fields),
        !          3564:         because when bit-field insns will be used there is no
        !          3565:         advantage in doing this.  */
        !          3566: 
        !          3567:       if (innerprec < TYPE_PRECISION (TREE_TYPE (op))
        !          3568:          && ! DECL_BIT_FIELD (TREE_OPERAND (op, 1))
        !          3569:          && (first || uns == TREE_UNSIGNED (TREE_OPERAND (op, 1)))
        !          3570:          && type != 0)
        !          3571:        {
        !          3572:          if (first)
        !          3573:            uns = TREE_UNSIGNED (TREE_OPERAND (op, 1));
        !          3574:          win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0),
        !          3575:                       TREE_OPERAND (op, 1));
        !          3576:          TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
        !          3577:          TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
        !          3578:          TREE_RAISES (win) = TREE_RAISES (op);
        !          3579:        }
        !          3580:     }
        !          3581:   *unsignedp_ptr = uns;
        !          3582:   return win;
        !          3583: }
        !          3584: 
        !          3585: /* Return the precision of a type, for arithmetic purposes.
        !          3586:    Supports all types on which arithmetic is possible
        !          3587:    (including pointer types).
        !          3588:    It's not clear yet what will be right for complex types.  */
        !          3589: 
        !          3590: int
        !          3591: type_precision (type)
        !          3592:      register tree type;
        !          3593: {
        !          3594:   return ((TREE_CODE (type) == INTEGER_TYPE
        !          3595:           || TREE_CODE (type) == ENUMERAL_TYPE
        !          3596:           || TREE_CODE (type) == REAL_TYPE)
        !          3597:          ? TYPE_PRECISION (type) : POINTER_SIZE);
        !          3598: }
        !          3599: 
        !          3600: /* Nonzero if integer constant C has a value that is permissible
        !          3601:    for type TYPE (an INTEGER_TYPE).  */
        !          3602: 
        !          3603: int
        !          3604: int_fits_type_p (c, type)
        !          3605:      tree c, type;
        !          3606: {
        !          3607:   if (TREE_UNSIGNED (type))
        !          3608:     return (!INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c)
        !          3609:            && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))
        !          3610:            && (TREE_INT_CST_HIGH (c) >= 0 || TREE_UNSIGNED (TREE_TYPE (c))));
        !          3611:   else
        !          3612:     return (!INT_CST_LT (TYPE_MAX_VALUE (type), c)
        !          3613:            && !INT_CST_LT (c, TYPE_MIN_VALUE (type))
        !          3614:            && (TREE_INT_CST_HIGH (c) >= 0 || !TREE_UNSIGNED (TREE_TYPE (c))));
        !          3615: }
        !          3616: 
        !          3617: /* Return the innermost context enclosing DECL that is
        !          3618:    a FUNCTION_DECL, or zero if none.  */
        !          3619: 
        !          3620: tree
        !          3621: decl_function_context (decl)
        !          3622:      tree decl;
        !          3623: {
        !          3624:   tree context;
        !          3625: 
        !          3626:   if (TREE_CODE (decl) == ERROR_MARK)
        !          3627:     return 0;
        !          3628: 
        !          3629: #ifdef METHOD_SEL_NAME
        !          3630:   if (TREE_CODE (decl) == INSTANCE_METHOD_DECL
        !          3631:       || TREE_CODE (decl) == CLASS_METHOD_DECL)
        !          3632:     return 0;
        !          3633: #endif
        !          3634: 
        !          3635:   if (TREE_CODE (decl) == SAVE_EXPR)
        !          3636:     context = SAVE_EXPR_CONTEXT (decl);
        !          3637:   else
        !          3638:     context = DECL_CONTEXT (decl);
        !          3639: 
        !          3640:   while (context && TREE_CODE (context) != FUNCTION_DECL)
        !          3641:     {
        !          3642:       if (TREE_CODE (context) == RECORD_TYPE
        !          3643:          || TREE_CODE (context) == UNION_TYPE)
        !          3644:        context = TYPE_CONTEXT (context);
        !          3645:       else if (TREE_CODE (context) == TYPE_DECL)
        !          3646:        context = DECL_CONTEXT (context);
        !          3647:       else if (TREE_CODE (context) == BLOCK)
        !          3648:        context = BLOCK_SUPERCONTEXT (context);
        !          3649:       else
        !          3650:        /* Unhandled CONTEXT !?  */
        !          3651:        abort ();
        !          3652:     }
        !          3653: 
        !          3654:   return context;
        !          3655: }
        !          3656: 
        !          3657: /* Return the innermost context enclosing DECL that is
        !          3658:    a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, or zero if none.
        !          3659:    TYPE_DECLs and FUNCTION_DECLs are transparent to this function.  */
        !          3660: 
        !          3661: tree
        !          3662: decl_type_context (decl)
        !          3663:      tree decl;
        !          3664: {
        !          3665:   tree context = DECL_CONTEXT (decl);
        !          3666: 
        !          3667:   while (context)
        !          3668:     {
        !          3669:       if (TREE_CODE (context) == RECORD_TYPE
        !          3670:          || TREE_CODE (context) == UNION_TYPE
        !          3671:          || TREE_CODE (context) == QUAL_UNION_TYPE)
        !          3672:        return context;
        !          3673:       if (TREE_CODE (context) == TYPE_DECL
        !          3674:          || TREE_CODE (context) == FUNCTION_DECL)
        !          3675:        context = DECL_CONTEXT (context);
        !          3676:       else if (TREE_CODE (context) == BLOCK)
        !          3677:        context = BLOCK_SUPERCONTEXT (context);
        !          3678:       else
        !          3679:        /* Unhandled CONTEXT!?  */
        !          3680:        abort ();
        !          3681:     }
        !          3682:   return NULL_TREE;
        !          3683: }
        !          3684: 
        !          3685: void
        !          3686: print_obstack_statistics (str, o)
        !          3687:      char *str;
        !          3688:      struct obstack *o;
        !          3689: {
        !          3690:   struct _obstack_chunk *chunk = o->chunk;
        !          3691:   int n_chunks = 0;
        !          3692:   int n_alloc = 0;
        !          3693: 
        !          3694:   while (chunk)
        !          3695:     {
        !          3696:       n_chunks += 1;
        !          3697:       n_alloc += chunk->limit - &chunk->contents[0];
        !          3698:       chunk = chunk->prev;
        !          3699:     }
        !          3700:   fprintf (stderr, "obstack %s: %d bytes, %d chunks\n",
        !          3701:           str, n_alloc, n_chunks);
        !          3702: }
        !          3703: void
        !          3704: dump_tree_statistics ()
        !          3705: {
        !          3706:   int i;
        !          3707:   int total_nodes, total_bytes;
        !          3708: 
        !          3709:   fprintf (stderr, "\n??? tree nodes created\n\n");
        !          3710: #ifdef GATHER_STATISTICS
        !          3711:   fprintf (stderr, "Kind                  Nodes     Bytes\n");
        !          3712:   fprintf (stderr, "-------------------------------------\n");
        !          3713:   total_nodes = total_bytes = 0;
        !          3714:   for (i = 0; i < (int) all_kinds; i++)
        !          3715:     {
        !          3716:       fprintf (stderr, "%-20s %6d %9d\n", tree_node_kind_names[i],
        !          3717:               tree_node_counts[i], tree_node_sizes[i]);
        !          3718:       total_nodes += tree_node_counts[i];
        !          3719:       total_bytes += tree_node_sizes[i];
        !          3720:     }
        !          3721:   fprintf (stderr, "%-20s        %9d\n", "identifier names", id_string_size);
        !          3722:   fprintf (stderr, "-------------------------------------\n");
        !          3723:   fprintf (stderr, "%-20s %6d %9d\n", "Total", total_nodes, total_bytes);
        !          3724:   fprintf (stderr, "-------------------------------------\n");
        !          3725: #else
        !          3726:   fprintf (stderr, "(No per-node statistics)\n");
        !          3727: #endif
        !          3728:   print_lang_statistics ();
        !          3729: }
        !          3730: 
        !          3731: #define FILE_FUNCTION_PREFIX_LEN 9
        !          3732: 
        !          3733: #ifndef NO_DOLLAR_IN_LABEL
        !          3734: #define FILE_FUNCTION_FORMAT "_GLOBAL_$D$%s"
        !          3735: #else /* NO_DOLLAR_IN_LABEL */
        !          3736: #ifndef NO_DOT_IN_LABEL
        !          3737: #define FILE_FUNCTION_FORMAT "_GLOBAL_.D.%s"
        !          3738: #else /* NO_DOT_IN_LABEL */
        !          3739: #define FILE_FUNCTION_FORMAT "__GLOBAL_D_%s"
        !          3740: #endif /* NO_DOT_IN_LABEL */
        !          3741: #endif /* NO_DOLLAR_IN_LABEL */
        !          3742: 
        !          3743: extern char * first_global_object_name;
        !          3744: 
        !          3745: /* If KIND=='I', return a suitable global initializer (constructor) name.
        !          3746:    If KIND=='D', return a suitable global clean-up (destructor) name. */
        !          3747: 
        !          3748: tree
        !          3749: get_file_function_name (kind)
        !          3750:      int kind;
        !          3751: {
        !          3752:   char *buf;
        !          3753:   register char *p;
        !          3754: 
        !          3755:   if (first_global_object_name)
        !          3756:     p = first_global_object_name;
        !          3757:   else if (main_input_filename)
        !          3758:     p = main_input_filename;
        !          3759:   else
        !          3760:     p = input_filename;
        !          3761: 
        !          3762:   buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p));
        !          3763: 
        !          3764:   /* Set up the name of the file-level functions we may need.  */
        !          3765:   /* Use a global object (which is already required to be unique over
        !          3766:      the program) rather than the file name (which imposes extra
        !          3767:      constraints).  -- [email protected], 10 Jan 1990.  */
        !          3768:   sprintf (buf, FILE_FUNCTION_FORMAT, p);
        !          3769: 
        !          3770:   /* Don't need to pull wierd characters out of global names.  */
        !          3771:   if (p != first_global_object_name)
        !          3772:     {
        !          3773:       for (p = buf+11; *p; p++)
        !          3774:        if (! ((*p >= '0' && *p <= '9')
        !          3775: #if 0 /* we always want labels, which are valid C++ identifiers (+ `$') */
        !          3776: #ifndef ASM_IDENTIFY_GCC       /* this is required if `.' is invalid -- k. raeburn */
        !          3777:               || *p == '.'
        !          3778: #endif
        !          3779: #endif
        !          3780: #ifndef NO_DOLLAR_IN_LABEL     /* this for `$'; unlikely, but... -- kr */
        !          3781:               || *p == '$'
        !          3782: #endif
        !          3783: #ifndef NO_DOT_IN_LABEL                /* this for `.'; unlikely, but... */
        !          3784:               || *p == '.'
        !          3785: #endif
        !          3786:               || (*p >= 'A' && *p <= 'Z')
        !          3787:               || (*p >= 'a' && *p <= 'z')))
        !          3788:          *p = '_';
        !          3789:     }
        !          3790: 
        !          3791:   buf[FILE_FUNCTION_PREFIX_LEN] = kind;
        !          3792: 
        !          3793:   return get_identifier (buf);
        !          3794: }

unix.superglobalmegacorp.com

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