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

📄 decl.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Process declarations and variables for GNU CHILL compiler.   Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.       This file is part of GNU CC.      GNU CC is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the 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 of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with GNU CC; see the file COPYING.  If not, write to   the Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* Process declarations and symbol lookup for CHILL front end.   Also constructs types; the standard scalar types at initialization,   and structure, union, array and enum types when they are declared.  *//* NOTES on Chill name resolution      Chill allows one to refer to an identifier that is declared later in   the same Group.  Hence, a single pass over the code (as in C) is   insufficient.      This implementation uses two complete passes over the source code,   plus some extra passes over internal data structures.      Loosely, during pass 1, a 'scope' object is created for each Chill   reach.  Each scope object contains a list of 'decl' objects,   one for each 'defining occurrence' in the reach.  (This list   is in the 'remembered_decls' field of each scope.)   The scopes and their decls are replayed in pass 2:  As each reach   is entered, the decls saved from pass 1 are made visible.      There are some exceptions.  Declarations that cannot be referenced   before their declaration (i.e. whose defining occurrence precede   their reach), can be deferred to pass 2.  These include formal   parameter declarations, and names defined in a DO action.      During pass 2, as each scope is entered, we must make visible all   the declarations defined in the scope, before we generate any code.   We must also simplify the declarations from pass 1:  For example   a VAR_DECL may have a array type whose bounds are expressions;   these need to be folded.  But of course the expressions may contain   identifiers that may be defined later in the scope - or even in   a different module.      The "satisfy" process has two main phases:      1: Binding. Each identifier *referenced* in a declaration (i.e. in   a mode or the RHS of a synonum declaration) must be bound to its   defining occurrence.  This may need to be linking via   grants and/or seizes (which are represented by ALIAS_DECLs).   A further complication is handling implied name strings.      2: Layout. Each CONST_DECL or TYPE_DECL *referenced* in a declaration   must than be replaced by its value (or type).  Constants must be   folded.  Types and declarstions must be laid out.  DECL_RTL must be set.   While doing this, we must watch out for circular dependencies.      If a scope contains nested modulions, then the Binding phase must be   done for each nested module (recursively) before the Layout phase   can start for that scope.  As an example of why this is needed, consider:      M1: MODULE     DCL a ARRAY [1:y] int; -- This should have 7 elements.     SYN x = 5;     SEIZE y;   END M1;   M2: MODULE     SYN x = 2;     SYN y = x + 5;     GRANT y;   END M2;   Here, the 'x' in "x + 5" must be Bound to the 'x' in module M2.   This must be done before we can Layout a.   The reason this is an issue is that we do *not* have a lookup   (or hash) table per scope (or module).  Instead we have a single   global table we we keep adding and removing bindings from.   (This is both for speed, and because of gcc history.)   Note that a SEIZE generates a declaration in the current scope,   linked to something in the surrounding scope.  Determining (binding)   the link must be done in pass 2.  On the other hand, a GRANT   generates a declaration in the surrounding scope, linked to   something in the current scope.  This linkage is Bound in pass 1.   The sequence for the above example is:   - Enter the declarations of M1 (i.e. {a, x, y}) into the hash table.   - For each of {a, x, y}, examine dependent expression (the     rhs of x, the bounds of a), and Bind any identifiers to     the current declarations (as found in the hash table).  Specifically,     the 'y' in the array bounds of 'a' is bound to the 'y' declared by     the SEIZE declaration.  Also, 'y' is Bound to the implicit     declaration in the global scope (generated from the GRANT in M2).   - Remove the bindings for M1 (i.e. {a, x, y}) from the hash table.   - Enter the declarations of M2 (i.e. {x, y}) into the hash table.   - For each of {x, y} examine the dependent expressions (the rhs of     x and y), and Bind any identifiers to their current declarartions     (in this case the 'x' in "x + 5" is bound to the 'x' that is 2.   - Remove the bindings for M2 (i.e. {x, y}) from the hash table.   - Perform Layout for M1:  This requires the size of a, which     requires the value of y.  The 'y'  is Bound to the implicit     declaration in the global scope, which is Bound to the declaration     of y in M2.  We now require the value of this 'y', which is "x + 5"     where x is bound to the x in M2 (thanks to our previous Binding     phase).  So we get that the value of y is 7.   - Perform layout of M2.  This implies calculating (constant folding)   the value of y - but we already did that, so we're done.      An example illustating the problem with implied names:   M1: MODULE     SEIZE y;     use(e);  -- e is implied by y.   END M1;   M2: MODULE     GRANT y;     SYNMODE y = x;     SEIZE x;   END M2;   M3: MODULE     GRANT x;     SYNMODE x = SET (e);   END M3;   This implies that determining the implied name e in M1   must be done after Binding of y to x in M2.   Yet another nasty:   M1: MODULE     SEIZE v;     DCL a ARRAY(v:v) int;   END M1;   M2: MODULE     GRANT v;     SEIZE x;     SYN v x = e;   END M2;   M3: MODULE     GRANT x;     SYNMODE x = SET(e);   END M3;   This one implies that determining the implied name e in M2,   must be done before Layout of a in M1.   These two examples togother indicate the determining implieed   names requries yet another phase.   - Bind strong names in M1.   - Bind strong names in M2.   - Bind strong names in M3.   - Determine weak names implied by SEIZEs in M1.   - Bind the weak names in M1.   - Determine weak names implied by SEIZEs in M2.   - Bind the weak names in M2.   - Determine weak names implied by SEIZEs in M3.   - Bind the weak names in M3.   - Layout M1.   - Layout M2.   - Layout M3.   We must bind the strong names in every module before we can determine   weak names in any module (because of seized/granted synmode/newmodes).   We must bind the weak names in every module before we can do Layout   in any module.   Sigh.   *//* ??? not all decl nodes are given the most useful possible   line numbers.  For example, the CONST_DECLs for enum values.  */#include "config.h"#include "system.h"#include "tree.h"#include "flags.h"#include "ch-tree.h"#include "lex.h"#include "obstack.h"#include "input.h"#include "rtl.h"#include "toplev.h"#define IS_UNKNOWN_TYPE(type) (TYPE_SIZE(type)==0)#define BUILTIN_NESTING_LEVEL (-1)/* For backward compatibility, we define Chill INT to be the same   as SHORT (i.e. 16 bits), at least if C INT is the same as LONG.   This is a lose. */#define CHILL_INT_IS_SHORT (INT_TYPE_SIZE==LONG_TYPE_SIZE)extern int  ignore_case;extern tree process_type;extern struct obstack *saveable_obstack;extern tree signal_code;extern int special_UC;static tree get_next_decl             PROTO((void));static tree lookup_name_for_seizing   PROTO((tree));#if 0static tree lookup_name_current_level PROTO((tree));#endifstatic void save_decl                 PROTO((tree));extern struct obstack permanent_obstack;extern int in_pseudo_module;struct module *current_module = NULL;struct module *first_module = NULL;struct module **next_module = &first_module;extern int  in_pseudo_module;int module_number = 0;/* This is only used internally (by signed_type). */tree signed_boolean_type_node;tree global_function_decl = NULL_TREE;/* This is a temportary used by RESULT to store its value.   Note we cannot directly use DECL_RESULT for two reasons:   a) If DECL_RESULT is a register, it may get clobbered by a   subsequent function call; and   b) if the function returns a struct, we might (visibly) modify the   destination before we're supposed to. */tree chill_result_decl;int result_never_set;/* forward declarations */static void pushdecllist                     PROTO((tree, int));static int  init_nonvalue_struct             PROTO((tree));static int  init_nonvalue_array              PROTO((tree));int current_nesting_level = BUILTIN_NESTING_LEVEL;int current_module_nesting_level = 0;/* Lots of declarations copied from c-decl.c. *//* ??? not all decl nodes are given the most useful possible   line numbers.  For example, the CONST_DECLs for enum values.  */#if 0/* In grokdeclarator, distinguish syntactic contexts of declarators.  */enum decl_context{ NORMAL,			/* Ordinary declaration */    FUNCDEF,			/* Function definition */    PARM,			/* Declaration of parm before function body */    FIELD,			/* Declaration inside struct or union */    BITFIELD,			/* Likewise but with specified width */    TYPENAME};			/* Typename (inside cast or sizeof)  */#endif#ifndef CHAR_TYPE_SIZE#define CHAR_TYPE_SIZE BITS_PER_UNIT#endif#ifndef SHORT_TYPE_SIZE#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))#endif#ifndef INT_TYPE_SIZE#define INT_TYPE_SIZE BITS_PER_WORD#endif#ifndef LONG_TYPE_SIZE#define LONG_TYPE_SIZE BITS_PER_WORD#endif#ifndef LONG_LONG_TYPE_SIZE#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)#endif#ifndef WCHAR_UNSIGNED#define WCHAR_UNSIGNED 0#endif#ifndef FLOAT_TYPE_SIZE#define FLOAT_TYPE_SIZE BITS_PER_WORD#endif#ifndef DOUBLE_TYPE_SIZE#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)#endif#ifndef LONG_DOUBLE_TYPE_SIZE#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)#endif/* We let tm.h override the types used here, to handle trivial differences   such as the choice of unsigned int or long unsigned int for size_t.   When machines start needing nontrivial differences in the size type,   it would be best to do something here to figure out automatically   from other information what type to use.  */#ifndef PTRDIFF_TYPE#define PTRDIFF_TYPE "long int"#endif#ifndef WCHAR_TYPE#define WCHAR_TYPE "int"#endif/* a node which has tree code ERROR_MARK, and whose type is itself.   All erroneous expressions are replaced with this node.  All functions   that accept nodes as arguments should avoid generating error messages   if this node is one of the arguments, since it is undesirable to get   multiple error messages from one error in the input.  */tree error_mark_node;/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */tree short_integer_type_node;tree integer_type_node;tree long_integer_type_node;tree long_long_integer_type_node;tree short_unsigned_type_node;tree unsigned_type_node;tree long_unsigned_type_node;tree long_long_unsigned_type_node;tree ptrdiff_type_node;tree unsigned_char_type_node;tree signed_char_type_node;tree char_type_node;tree wchar_type_node;tree signed_wchar_type_node;tree unsigned_wchar_type_node;tree float_type_node;tree double_type_node;tree long_double_type_node;tree complex_integer_type_node;tree complex_float_type_node;tree complex_double_type_node;tree complex_long_double_type_node;tree intQI_type_node;tree intHI_type_node;tree intSI_type_node;tree intDI_type_node;#if HOST_BITS_PER_WIDE_INT >= 64tree intTI_type_node;#endiftree unsigned_intQI_type_node;tree unsigned_intHI_type_node;tree unsigned_intSI_type_node;tree unsigned_intDI_type_node;#if HOST_BITS_PER_WIDE_INT >= 64tree unsigned_intTI_type_node;#endif/* a VOID_TYPE node.  */tree void_type_node;tree void_list_node;/* Nodes for types `void *' and `const void *'.  */tree ptr_type_node, const_ptr_type_node;/* type of initializer structure, which points to   a module's module-level code, and to the next   such structure. */tree initializer_type;/* type of a CHILL predefined value builtin routine */tree chill_predefined_function_type;/* type `int ()' -- used for implicit declaration of functions.  */tree default_function_type;#if 0/* function types `double (double)' and `double (double, double)', etc.  */tree double_ftype_double, double_ftype_double_double;tree int_ftype_int, long_ftype_long;/* Function type `void (void *, void *, int)' and similar ones */tree void_ftype_ptr_ptr_int, int_ftype_ptr_ptr_int, void_ftype_ptr_int_int;/* Function type `char *(char *, char *)' and similar ones */tree string_ftype_ptr_ptr, int_ftype_string_string;/* Function type `int (const void *, const void *, size_t)' */tree int_ftype_cptr_cptr_sizet;#endifchar **boolean_code_name;/* Two expressions that are constants with value zero.   The first is of type `int', the second of type `void *'.  */tree integer_zero_node;tree null_pointer_node;/* A node for the integer constant 1.  */tree integer_one_node;/* A node for the integer constant -1.  */tree integer_minus_one_node;/* Nodes for boolean constants TRUE and FALSE. */tree boolean_true_node, boolean_false_node;tree string_one_type_node;  /* The type of CHARS(1). */tree bitstring_one_type_node;  /* The type of BOOLS(1). */tree bit_zero_node; /* B'0' */tree bit_one_node; /* B'1' *//* Nonzero if we have seen an invalid cross reference   to a struct, union, or enum, but not yet printed the message.  */tree pending_invalid_xref;/* File and line to appear in the eventual error message.  */char *pending_invalid_xref_file;int pending_invalid_xref_line;/* After parsing the declarator that starts a function definition,   `start_function' puts here the list of parameter names or chain of decls.   `store_parm_decls' finds it here.  */static tree current_function_parms;/* Nonzero when store_parm_decls is called indicates a varargs function.   Value not meaningful after store_parm_decls.  */static int c_function_varargs;/* The FUNCTION_DECL for the function currently being compiled,   or 0 if between functions.  */tree current_function_decl;

⌨️ 快捷键说明

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