⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Language-independent node constructors for parse phase of GNU compiler.   Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* This file contains the low level primitives for operating on tree nodes,   including allocation, list operations, interning of identifiers,   construction of data type nodes and statement nodes,   and construction of type conversion nodes.  It also contains   tables index by tree code that describe how to take apart   nodes of that code.   It is intended to be language-independent, but occasionally   calls language-dependent routines defined (for C) in typecheck.c.   The low-level allocation routines oballoc and permalloc   are used also for allocating many other kinds of objects   by all passes of the compiler.  */#include <setjmp.h>#include "config.h"#include "flags.h"#include "tree.h"#include "function.h"#include "obstack.h"#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include <stdio.h>#define obstack_chunk_alloc xmalloc#define obstack_chunk_free free/* Tree nodes of permanent duration are allocated in this obstack.   They are the identifier nodes, and everything outside of   the bodies and parameters of function definitions.  */struct obstack permanent_obstack;/* The initial RTL, and all ..._TYPE nodes, in a function   are allocated in this obstack.  Usually they are freed at the   end of the function, but if the function is inline they are saved.   For top-level functions, this is maybepermanent_obstack.   Separate obstacks are made for nested functions.  */struct obstack *function_maybepermanent_obstack;/* This is the function_maybepermanent_obstack for top-level functions.  */struct obstack maybepermanent_obstack;/* This is a list of function_maybepermanent_obstacks for top-level inline   functions that are compiled in the middle of compiling other functions.  */struct simple_obstack_stack *toplev_inline_obstacks;/* This is a list of function_maybepermanent_obstacks for inline functions   nested in the current function that were compiled in the middle of   compiling other functions.  */struct simple_obstack_stack *inline_obstacks;/* The contents of the current function definition are allocated   in this obstack, and all are freed at the end of the function.   For top-level functions, this is temporary_obstack.   Separate obstacks are made for nested functions.  */struct obstack *function_obstack;/* This is used for reading initializers of global variables.  */struct obstack temporary_obstack;/* The tree nodes of an expression are allocated   in this obstack, and all are freed at the end of the expression.  */struct obstack momentary_obstack;/* The tree nodes of a declarator are allocated   in this obstack, and all are freed when the declarator   has been parsed.  */static struct obstack temp_decl_obstack;/* This points at either permanent_obstack   or the current function_maybepermanent_obstack.  */struct obstack *saveable_obstack;/* This is same as saveable_obstack during parse and expansion phase;   it points to the current function's obstack during optimization.   This is the obstack to be used for creating rtl objects.  */struct obstack *rtl_obstack;/* This points at either permanent_obstack or the current function_obstack.  */struct obstack *current_obstack;/* This points at either permanent_obstack or the current function_obstack   or momentary_obstack.  */struct obstack *expression_obstack;/* Stack of obstack selections for push_obstacks and pop_obstacks.  */struct obstack_stack{  struct obstack_stack *next;  struct obstack *current;  struct obstack *saveable;  struct obstack *expression;  struct obstack *rtl;};struct obstack_stack *obstack_stack;/* Obstack for allocating struct obstack_stack entries.  */static struct obstack obstack_stack_obstack;/* Addresses of first objects in some obstacks.   This is for freeing their entire contents.  */char *maybepermanent_firstobj;char *temporary_firstobj;char *momentary_firstobj;char *temp_decl_firstobj;/* This is used to preserve objects (mainly array initializers) that need to   live until the end of the current function, but no further.  */char *momentary_function_firstobj;/* Nonzero means all ..._TYPE nodes should be allocated permanently.  */int all_types_permanent;/* Stack of places to restore the momentary obstack back to.  */   struct momentary_level{  /* Pointer back to previous such level.  */  struct momentary_level *prev;  /* First object allocated within this level.  */  char *base;  /* Value of expression_obstack saved at entry to this level.  */  struct obstack *obstack;};struct momentary_level *momentary_stack;/* Table indexed by tree code giving a string containing a character   classifying the tree code.  Possibilities are   t, d, s, c, r, <, 1, 2 and e.  See tree.def for details.  */#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,char *standard_tree_code_type[] = {#include "tree.def"};#undef DEFTREECODE/* Table indexed by tree code giving number of expression   operands beyond the fixed part of the node structure.   Not used for types or decls.  */#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,int standard_tree_code_length[] = {#include "tree.def"};#undef DEFTREECODE/* Names of tree components.   Used for printing out the tree and error messages.  */#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,char *standard_tree_code_name[] = {#include "tree.def"};#undef DEFTREECODE/* Table indexed by tree code giving a string containing a character   classifying the tree code.  Possibilities are   t, d, s, c, r, e, <, 1 and 2.  See tree.def for details.  */char **tree_code_type;/* Table indexed by tree code giving number of expression   operands beyond the fixed part of the node structure.   Not used for types or decls.  */int *tree_code_length;/* Table indexed by tree code giving name of tree code, as a string.  */char **tree_code_name;/* Statistics-gathering stuff.  */typedef enum{  d_kind,  t_kind,  b_kind,  s_kind,  r_kind,  e_kind,  c_kind,  id_kind,  op_id_kind,  perm_list_kind,  temp_list_kind,  vec_kind,  x_kind,  lang_decl,  lang_type,  all_kinds} tree_node_kind;int tree_node_counts[(int)all_kinds];int tree_node_sizes[(int)all_kinds];int id_string_size = 0;char *tree_node_kind_names[] = {  "decls",  "types",  "blocks",  "stmts",  "refs",  "exprs",  "constants",  "identifiers",  "op_identifiers",  "perm_tree_lists",  "temp_tree_lists",  "vecs",  "random kinds",  "lang_decl kinds",  "lang_type kinds"};/* Hash table for uniquizing IDENTIFIER_NODEs by name.  */#define MAX_HASH_TABLE 1009static tree hash_table[MAX_HASH_TABLE];	/* id hash buckets *//* 0 while creating built-in identifiers.  */static int do_identifier_warnings;/* Unique id for next decl created.  */static int next_decl_uid;/* Unique id for next type created.  */static int next_type_uid = 1;/* Here is how primitive or already-canonicalized types' hash   codes are made.  */#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)extern char *mode_name[];void gcc_obstack_init ();/* Init the principal obstacks.  */voidinit_obstacks (){  gcc_obstack_init (&obstack_stack_obstack);  gcc_obstack_init (&permanent_obstack);  gcc_obstack_init (&temporary_obstack);  temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);  gcc_obstack_init (&momentary_obstack);  momentary_firstobj = (char *) obstack_alloc (&momentary_obstack, 0);  momentary_function_firstobj = momentary_firstobj;  gcc_obstack_init (&maybepermanent_obstack);  maybepermanent_firstobj    = (char *) obstack_alloc (&maybepermanent_obstack, 0);  gcc_obstack_init (&temp_decl_obstack);  temp_decl_firstobj = (char *) obstack_alloc (&temp_decl_obstack, 0);  function_obstack = &temporary_obstack;  function_maybepermanent_obstack = &maybepermanent_obstack;  current_obstack = &permanent_obstack;  expression_obstack = &permanent_obstack;  rtl_obstack = saveable_obstack = &permanent_obstack;  /* Init the hash table of identifiers.  */  bzero ((char *) hash_table, sizeof hash_table);}voidgcc_obstack_init (obstack)     struct obstack *obstack;{  /* Let particular systems override the size of a chunk.  */#ifndef OBSTACK_CHUNK_SIZE#define OBSTACK_CHUNK_SIZE 0#endif  /* Let them override the alloc and free routines too.  */#ifndef OBSTACK_CHUNK_ALLOC#define OBSTACK_CHUNK_ALLOC xmalloc#endif#ifndef OBSTACK_CHUNK_FREE#define OBSTACK_CHUNK_FREE free#endif  _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,		  (void *(*) ()) OBSTACK_CHUNK_ALLOC,		  (void (*) ()) OBSTACK_CHUNK_FREE);}/* Save all variables describing the current status into the structure *P.   This is used before starting a nested function.   CONTEXT is the decl_function_context for the function we're about to   compile; if it isn't current_function_decl, we have to play some games.  */voidsave_tree_status (p, context)     struct function *p;     tree context;{  p->all_types_permanent = all_types_permanent;  p->momentary_stack = momentary_stack;  p->maybepermanent_firstobj = maybepermanent_firstobj;  p->momentary_firstobj = momentary_firstobj;  p->momentary_function_firstobj = momentary_function_firstobj;  p->function_obstack = function_obstack;  p->function_maybepermanent_obstack = function_maybepermanent_obstack;  p->current_obstack = current_obstack;  p->expression_obstack = expression_obstack;  p->saveable_obstack = saveable_obstack;  p->rtl_obstack = rtl_obstack;  p->inline_obstacks = inline_obstacks;  if (context == current_function_decl)    /* Objects that need to be saved in this function can be in the nonsaved       obstack of the enclosing function since they can't possibly be needed       once it has returned.  */    function_maybepermanent_obstack = function_obstack;  else    {      /* We're compiling a function which isn't nested in the current         function.  We need to create a new maybepermanent_obstack for this         function, since it can't go onto any of the existing obstacks.  */      struct simple_obstack_stack **head;      struct simple_obstack_stack *current;      if (context == NULL_TREE)	head = &toplev_inline_obstacks;      else	{	  struct function *f = find_function_data (context);	  head = &f->inline_obstacks;	}      current = ((struct simple_obstack_stack *)		 xmalloc (sizeof (struct simple_obstack_stack)));      current->obstack = (struct obstack *) xmalloc (sizeof (struct obstack));      function_maybepermanent_obstack = current->obstack;      gcc_obstack_init (function_maybepermanent_obstack);      current->next = *head;      *head = current;    }        maybepermanent_firstobj    = (char *) obstack_finish (function_maybepermanent_obstack);  function_obstack = (struct obstack *) xmalloc (sizeof (struct obstack));  gcc_obstack_init (function_obstack);  current_obstack = &permanent_obstack;  expression_obstack = &permanent_obstack;  rtl_obstack = saveable_obstack = &permanent_obstack;  momentary_firstobj = (char *) obstack_finish (&momentary_obstack);  momentary_function_firstobj = momentary_firstobj;}/* Restore all variables describing the current status from the structure *P.   This is used after a nested function.  */voidrestore_tree_status (p)     struct function *p;{  all_types_permanent = p->all_types_permanent;  momentary_stack = p->momentary_stack;  obstack_free (&momentary_obstack, momentary_function_firstobj);  /* Free saveable storage used by the function just compiled and not     saved.     CAUTION: This is in function_obstack of the containing function.     So we must be sure that we never allocate from that obstack during     the compilation of a nested function if we expect it to survive     past the nested function's end.  */  obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj);  obstack_free (function_obstack, 0);  free (function_obstack);  momentary_firstobj = p->momentary_firstobj;  momentary_function_firstobj = p->momentary_function_firstobj;  maybepermanent_firstobj = p->maybepermanent_firstobj;  function_obstack = p->function_obstack;  function_maybepermanent_obstack = p->function_maybepermanent_obstack;  current_obstack = p->current_obstack;  expression_obstack = p->expression_obstack;  saveable_obstack = p->saveable_obstack;  rtl_obstack = p->rtl_obstack;  inline_obstacks = p->inline_obstacks;}/* Start allocating on the temporary (per function) obstack.   This is done in start_function before parsing the function body,   and before each initialization at top level, and to go back   to temporary allocation after doing permanent_allocation.  */voidtemporary_allocation (){  /* Note that function_obstack at top level points to temporary_obstack.     But within a nested function context, it is a separate obstack.  */  current_obstack = function_obstack;  expression_obstack = function_obstack;  rtl_obstack = saveable_obstack = function_maybepermanent_obstack;  momentary_stack = 0;  inline_obstacks = 0;}/* Start allocating on the permanent obstack but don't   free the temporary data.  After calling this, call   `permanent_allocation' to fully resume permanent allocation status.  */voidend_temporary_allocation (){  current_obstack = &permanent_obstack;  expression_obstack = &permanent_obstack;  rtl_obstack = saveable_obstack = &permanent_obstack;}/* Resume allocating on the temporary obstack, undoing   effects of `end_temporary_allocation'.  */voidresume_temporary_allocation (){  current_obstack = function_obstack;  expression_obstack = function_obstack;  rtl_obstack = saveable_obstack = function_maybepermanent_obstack;}/* While doing temporary allocation, switch to allocating in such a   way as to save all nodes if the function is inlined.  Call   resume_temporary_allocation to go back to ordinary temporary   allocation.  */void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -