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

📄 tree.c

📁 使用yacc和lex编写的cmm语言的词法分析和语法分析程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Language-independent node constructors for parse phase of GNU compiler.   Copyright (C) 1987, 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, 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 "config.h"#include <stdio.h>#include "flags.h"#include "function.h"#include "tree.h"#include "obstack.h"#include "gvarargs.h"#define obstack_chunk_alloc xmalloc#define obstack_chunk_free freeextern int xmalloc ();extern void 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;/* 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;/* 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, 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", "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;extern char *mode_name[];void gcc_obstack_init ();static tree stabilize_reference_1 ();/* 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);  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 (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.  */voidsave_tree_status (p)     struct function *p;{  p->all_types_permanent = all_types_permanent;  p->momentary_stack = momentary_stack;  p->maybepermanent_firstobj = maybepermanent_firstobj;  p->momentary_firstobj = momentary_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;  function_obstack = (struct obstack *) xmalloc (sizeof (struct obstack));  gcc_obstack_init (function_obstack);  function_maybepermanent_obstack    = (struct obstack *) xmalloc (sizeof (struct obstack));  gcc_obstack_init (function_maybepermanent_obstack);  current_obstack = &permanent_obstack;  expression_obstack = &permanent_obstack;  rtl_obstack = saveable_obstack = &permanent_obstack;  momentary_firstobj = (char *) obstack_finish (&momentary_obstack);  maybepermanent_firstobj    = (char *) obstack_finish (function_maybepermanent_obstack);}/* 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_firstobj);  obstack_free (function_obstack, 0);  obstack_free (function_maybepermanent_obstack, 0);  free (function_obstack);  momentary_firstobj = p->momentary_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;}/* 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 end_temporary_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;}/* 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.  */voidsaveable_allocation (){  /* Note that function_obstack at top level points to temporary_obstack.     But within a nested function context, it is a separate obstack.  */  expression_obstack = current_obstack = saveable_obstack;}/* Switch to current obstack CURRENT and maybepermanent obstack SAVEABLE,   recording the previously current obstacks on a stack.   This does not free any storage in any obstack.  */voidpush_obstacks (current, saveable)     struct obstack *current, *saveable;{  struct obstack_stack *p    = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,					      (sizeof (struct obstack_stack)));  p->current = current_obstack;  p->saveable = saveable_obstack;  p->expression = expression_obstack;  p->rtl = rtl_obstack;  p->next = obstack_stack;  obstack_stack = p;  current_obstack = current;  expression_obstack = current;  rtl_obstack = saveable_obstack = saveable;}/* Save the current set of obstacks, but don't change them.  */voidpush_obstacks_nochange (){  struct obstack_stack *p    = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,					      (sizeof (struct obstack_stack)));  p->current = current_obstack;  p->saveable = saveable_obstack;  p->expression = expression_obstack;  p->rtl = rtl_obstack;  p->next = obstack_stack;  obstack_stack = p;}/* Pop the obstack selection stack.  */voidpop_obstacks (){  struct obstack_stack *p = obstack_stack;  obstack_stack = p->next;  current_obstack = p->current;  saveable_obstack = p->saveable;  expression_obstack = p->expression;  rtl_obstack = p->rtl;  obstack_free (&obstack_stack_obstack, p);}/* Nonzero if temporary allocation is currently in effect.   Zero if currently doing permanent allocation.  */intallocation_temporary_p (){  return current_obstack != &permanent_obstack;}/* Go back to allocating on the permanent obstack   and free everything in the temporary obstack.   This is done in finish_function after fully compiling a function.  */voidpermanent_allocation (){  /* Free up previous temporary obstack data */  obstack_free (&temporary_obstack, temporary_firstobj);  obstack_free (&momentary_obstack, momentary_firstobj);  obstack_free (&maybepermanent_obstack, maybepermanent_firstobj);  obstack_free (&temp_decl_obstack, temp_decl_firstobj);  current_obstack = &permanent_obstack;  expression_obstack = &permanent_obstack;  rtl_obstack = saveable_obstack = &permanent_obstack;}/* Save permanently everything on the maybepermanent_obstack.  */voidpreserve_data (){  maybepermanent_firstobj    = (char *) obstack_alloc (function_maybepermanent_obstack, 0);}voidpreserve_initializer (){  temporary_firstobj    = (char *) obstack_alloc (&temporary_obstack, 0);  momentary_firstobj    = (char *) obstack_alloc (&momentary_obstack, 0);  maybepermanent_firstobj    = (char *) obstack_alloc (function_maybepermanent_obstack, 0);}/* Start allocating new rtl in current_obstack.   Use resume_temporary_allocation   to go back to allocating rtl in saveable_obstack.  */void

⌨️ 快捷键说明

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