📄 decl.c
字号:
/* Process declarations and variables for the GNU compiler for the Java(TM) language. Copyright (C) 1996, 97-98, 1999 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.Java and all Java-based marks are trademarks or registered trademarksof Sun Microsystems, Inc. in the United States and other countries.The Free Software Foundation is independent of Sun Microsystems, Inc. *//* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */#include "config.h"#include "system.h"#include "tree.h"#include "java-tree.h"#include "jcf.h"#include "toplev.h"#include "except.h"static tree push_jvm_slot PROTO ((int, tree));static tree builtin_function PROTO ((const char *, tree, enum built_in_function, const char *));static tree lookup_name_current_level PROTO ((tree));#ifndef INT_TYPE_SIZE#define INT_TYPE_SIZE BITS_PER_WORD#endif/* The DECL_MAP is a mapping from (index, type) to a decl node. If index < max_locals, it is the index of a local variable. if index >= max_locals, then index-max_locals is a stack slot. The DECL_MAP mapping is represented as a TREE_VEC whose elements are a list of decls (VAR_DECL or PARM_DECL) chained by DECL_LOCAL_SLOT_CHAIN; the index finds the TREE_VEC element, and then we search the chain for a decl with a matching TREE_TYPE. */tree decl_map;/* A list of local variables VAR_DECLs for this method that we have seen debug information, but we have not reached their starting (byte) PC yet. */tree pending_local_decls = NULL_TREE;/* Push a local variable or stack slot into the decl_map, and assign it an rtl. */static treepush_jvm_slot (index, decl) int index; tree decl;{ struct rtx_def *rtl = NULL; tree type = TREE_TYPE (decl); tree tmp; DECL_CONTEXT (decl) = current_function_decl; layout_decl (decl, 0); /* See if we have an appropriate rtl (i.e. same mode) at this index. If so, we must use it. */ tmp = TREE_VEC_ELT (decl_map, index); while (tmp != NULL_TREE) { if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp))) rtl = DECL_RTL (tmp); if (rtl != NULL) break; tmp = DECL_LOCAL_SLOT_CHAIN (tmp); } if (rtl != NULL) DECL_RTL (decl) = rtl; else { if (index >= DECL_MAX_LOCALS (current_function_decl)) DECL_REGISTER (decl) = 1; expand_decl (decl); } /* Now link the decl into the decl_map. */ if (DECL_LANG_SPECIFIC (decl) == NULL) { DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); DECL_LOCAL_START_PC (decl) = 0; DECL_LOCAL_END_PC (decl) = DECL_CODE_LENGTH (current_function_decl); DECL_LOCAL_SLOT_NUMBER (decl) = index; } DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index); TREE_VEC_ELT (decl_map, index) = decl; return decl;}/* Find a VAR_DECL (or PARM_DECL) at local index INDEX that has type TYPE, that is valid at PC (or -1 if any pc). If there is no existing matching decl, allocate one. If we find a decl with matching modes but different types, we re-use the rtl, but create a new decl. */treefind_local_variable (index, type, pc) int index; tree type; int pc;{ tree decl = TREE_VEC_ELT (decl_map, index); tree best = NULL_TREE; while (decl != NULL_TREE) { int in_range; in_range = pc < 0 || (pc >= DECL_LOCAL_START_PC (decl) && pc < DECL_LOCAL_END_PC (decl)); if ((TREE_TYPE (decl) == type || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE && type == ptr_type_node)) && in_range) { if (best == NULL_TREE || (TREE_TYPE (decl) == type && TREE_TYPE (best) != type) || DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best) || DECL_LOCAL_END_PC (decl) < DECL_LOCAL_START_PC (decl)) best = decl; } decl = DECL_LOCAL_SLOT_CHAIN (decl); } if (best != NULL_TREE) return best; return push_jvm_slot (index, build_decl (VAR_DECL, NULL_TREE, type));}/* Same as find_local_index, except that INDEX is a stack index. */treefind_stack_slot (index, type) int index; tree type;{ return find_local_variable (index + DECL_MAX_LOCALS (current_function_decl), type, -1);}struct binding_level { /* A chain of _DECL nodes for all variables, constants, functions, * and typedef types. These are in the reverse of the order supplied. */ tree names; /* For each level, a list of shadowed outer-level local definitions to be restored when this level is popped. Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ tree shadowed; /* For each level (except not the global one), a chain of BLOCK nodes for all the levels that were entered and exited one level down. */ tree blocks; /* The BLOCK node for this level, if one has been preallocated. If 0, the BLOCK is allocated (if needed) when the level is popped. */ tree this_block; /* The binding level which this one is contained in (inherits from). */ struct binding_level *level_chain; /* 1 means make a BLOCK for this level regardless of all else. 2 for temporary binding contours created by the compiler. */ char keep; /* Nonzero means make a BLOCK if this level has any subblocks. */ char keep_if_subblocks; /* Nonzero if this level can safely have additional cleanup-needing variables added to it. */ char more_cleanups_ok; char have_cleanups; /* The bytecode PC that marks the end of this level. */ int end_pc; };#define NULL_BINDING_LEVEL (struct binding_level *) NULL/* The binding level currently in effect. */static struct binding_level *current_binding_level;/* A chain of binding_level structures awaiting reuse. */static struct binding_level *free_binding_level;/* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */static struct binding_level *global_binding_level;/* Binding level structures are initialized by copying this one. */static struct binding_level clear_binding_level = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_BINDING_LEVEL, 0, 0, 0, 0, 1000000000};#if 0/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function that have names. Here so we can clear out their names' definitions at the end of the function. */static tree named_labels;/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */static tree shadowed_labels;#endifint flag_traditional;/* Nonzero means unconditionally make a BLOCK for the next level pushed. */static int keep_next_level_flag;/* Nonzero means make a BLOCK for the next level pushed if it has subblocks. */static int keep_next_if_subblocks; /* The FUNCTION_DECL for the function currently being compiled, or 0 if between functions. */tree current_function_decl;/* The type node for the ordinary character type. */tree char_type_node;tree object_type_node;tree unqualified_object_id_node;tree object_ptr_type_node;tree string_type_node;tree string_ptr_type_node;tree throwable_type_node;tree runtime_exception_type_node;tree error_exception_type_node;tree *predef_filenames;int predef_filenames_size;tree boolean_type_node;tree float_type_node;tree double_type_node;/* a VOID_TYPE node. */tree void_type_node;tree ptr_type_node;tree return_address_type_node;tree integer_type_node;tree byte_type_node;tree short_type_node;tree int_type_node;tree long_type_node;tree promoted_byte_type_node;tree promoted_short_type_node;tree promoted_char_type_node;tree promoted_boolean_type_node;tree unsigned_byte_type_node;tree unsigned_short_type_node;tree unsigned_int_type_node;tree unsigned_long_type_node;/* The type for struct methodtable. */tree methodtable_type;tree methodtable_ptr_type;tree utf8const_type;tree utf8const_ptr_type;tree class_type_node;tree class_ptr_type;tree field_type_node;tree field_ptr_type_node;tree field_info_union_node;tree jexception_type;tree jexception_ptr_type;tree lineNumberEntry_type;tree lineNumbers_type;tree constants_type_node;tree dtable_type;tree dtable_ptr_type;tree method_type_node;tree method_ptr_type_node;tree nativecode_ptr_array_type_node;tree one_elt_array_domain_type;tree access_flags_type_node;tree class_dtable_decl;/* 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;/* Two expressions that are constants with value zero. The first is of type `int', the second of type `void *'. Other of type `long', `float' and `double' follow. */tree integer_zero_node;tree null_pointer_node;tree long_zero_node;tree float_zero_node;tree double_zero_node;tree empty_stmt_node;/* Nodes for boolean constants TRUE and FALSE. */tree boolean_true_node, boolean_false_node;tree TYPE_identifier_node;tree init_identifier_node;tree clinit_identifier_node;tree finit_identifier_node;tree void_signature_node;tree length_identifier_node;tree this_identifier_node;tree super_identifier_node;tree continue_identifier_node;tree end_params_node;/* References to internal libjava functions we use. */tree alloc_object_node;tree soft_instanceof_node;tree soft_checkcast_node;tree soft_initclass_node;tree soft_newarray_node;tree soft_anewarray_node;tree soft_multianewarray_node;tree soft_badarrayindex_node;tree throw_node;tree soft_checkarraystore_node;tree soft_monitorenter_node;tree soft_monitorexit_node;tree soft_lookupinterfacemethod_node;tree soft_fmod_node;tree soft_exceptioninfo_call_node;/* Build (and pushdecl) a "promoted type" for all standard types shorter than int. */static treepush_promoted_type (name, actual_type) char *name; tree actual_type;{ tree type = make_node (TREE_CODE (actual_type));#if 1 tree in_min = TYPE_MIN_VALUE (int_type_node); tree in_max = TYPE_MAX_VALUE (int_type_node);#else tree in_min = TYPE_MIN_VALUE (actual_type); tree in_max = TYPE_MAX_VALUE (actual_type);#endif TYPE_MIN_VALUE (type) = build_int_2 (TREE_INT_CST_LOW (in_min), TREE_INT_CST_HIGH (in_min)); TREE_TYPE (TYPE_MIN_VALUE (type)) = type; TYPE_MAX_VALUE (type) = build_int_2 (TREE_INT_CST_LOW (in_max), TREE_INT_CST_HIGH (in_max)); TREE_TYPE (TYPE_MAX_VALUE (type)) = type; TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node); layout_type (type); pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); return type;}/* Nodes for integer constants. */tree integer_one_node, integer_two_node, integer_four_node;tree integer_negative_one_node;/* Return a definition for a builtin function named NAME and whose data type is TYPE. TYPE should be a function type with argument types. FUNCTION_CODE tells later passes how to compile calls to this function. See tree.h for its possible values. If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, the name to be called if we can't opencode the function. */static treebuiltin_function (name, type, function_code, library_name) const char *name; tree type; enum built_in_function function_code; const char *library_name;{ tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; if (library_name)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -