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

📄 trans-decl.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Backend function setup   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.   Contributed by Paul BrookThis file is part of GCC.GCC is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING.  If not, write to the FreeSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, USA.  *//* trans-decl.c -- Handling of backend function and variable decls, etc */#include "config.h"#include "system.h"#include "coretypes.h"#include "tree.h"#include "tree-dump.h"#include "tree-gimple.h"#include "ggc.h"#include "toplev.h"#include "tm.h"#include "target.h"#include "function.h"#include "flags.h"#include "cgraph.h"#include "gfortran.h"#include "trans.h"#include "trans-types.h"#include "trans-array.h"#include "trans-const.h"/* Only for gfc_trans_code.  Shouldn't need to include this.  */#include "trans-stmt.h"#define MAX_LABEL_VALUE 99999/* Holds the result of the function if no result variable specified.  */static GTY(()) tree current_fake_result_decl;static GTY(()) tree current_function_return_label;/* Holds the variable DECLs for the current function.  */static GTY(()) tree saved_function_decls = NULL_TREE;static GTY(()) tree saved_parent_function_decls = NULL_TREE;/* The namespace of the module we're currently generating.  Only used while   outputting decls for module variables.  Do not rely on this being set.  */static gfc_namespace *module_namespace;/* List of static constructor functions.  */tree gfc_static_ctors;/* Function declarations for builtin library functions.  */tree gfor_fndecl_internal_malloc;tree gfor_fndecl_internal_malloc64;tree gfor_fndecl_internal_realloc;tree gfor_fndecl_internal_realloc64;tree gfor_fndecl_internal_free;tree gfor_fndecl_allocate;tree gfor_fndecl_allocate64;tree gfor_fndecl_deallocate;tree gfor_fndecl_pause_numeric;tree gfor_fndecl_pause_string;tree gfor_fndecl_stop_numeric;tree gfor_fndecl_stop_string;tree gfor_fndecl_select_string;tree gfor_fndecl_runtime_error;tree gfor_fndecl_set_fpe;tree gfor_fndecl_set_std;tree gfor_fndecl_set_convert;tree gfor_fndecl_ctime;tree gfor_fndecl_fdate;tree gfor_fndecl_ttynam;tree gfor_fndecl_in_pack;tree gfor_fndecl_in_unpack;tree gfor_fndecl_associated;/* Math functions.  Many other math functions are handled in   trans-intrinsic.c.  */gfc_powdecl_list gfor_fndecl_math_powi[4][3];tree gfor_fndecl_math_cpowf;tree gfor_fndecl_math_cpow;tree gfor_fndecl_math_cpowl10;tree gfor_fndecl_math_cpowl16;tree gfor_fndecl_math_ishftc4;tree gfor_fndecl_math_ishftc8;tree gfor_fndecl_math_ishftc16;tree gfor_fndecl_math_exponent4;tree gfor_fndecl_math_exponent8;tree gfor_fndecl_math_exponent10;tree gfor_fndecl_math_exponent16;/* String functions.  */tree gfor_fndecl_copy_string;tree gfor_fndecl_compare_string;tree gfor_fndecl_concat_string;tree gfor_fndecl_string_len_trim;tree gfor_fndecl_string_index;tree gfor_fndecl_string_scan;tree gfor_fndecl_string_verify;tree gfor_fndecl_string_trim;tree gfor_fndecl_string_repeat;tree gfor_fndecl_adjustl;tree gfor_fndecl_adjustr;/* Other misc. runtime library functions.  */tree gfor_fndecl_size0;tree gfor_fndecl_size1;tree gfor_fndecl_iargc;/* Intrinsic functions implemented in FORTRAN.  */tree gfor_fndecl_si_kind;tree gfor_fndecl_sr_kind;static voidgfc_add_decl_to_parent_function (tree decl){  gcc_assert (decl);  DECL_CONTEXT (decl) = DECL_CONTEXT (current_function_decl);  DECL_NONLOCAL (decl) = 1;  TREE_CHAIN (decl) = saved_parent_function_decls;  saved_parent_function_decls = decl;}voidgfc_add_decl_to_function (tree decl){  gcc_assert (decl);  TREE_USED (decl) = 1;  DECL_CONTEXT (decl) = current_function_decl;  TREE_CHAIN (decl) = saved_function_decls;  saved_function_decls = decl;}/* Build a  backend label declaration.  Set TREE_USED for named labels.   The context of the label is always the current_function_decl.  All   labels are marked artificial.  */treegfc_build_label_decl (tree label_id){  /* 2^32 temporaries should be enough.  */  static unsigned int tmp_num = 1;  tree label_decl;  char *label_name;  if (label_id == NULL_TREE)    {      /* Build an internal label name.  */      ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++);      label_id = get_identifier (label_name);    }  else    label_name = NULL;  /* Build the LABEL_DECL node. Labels have no type.  */  label_decl = build_decl (LABEL_DECL, label_id, void_type_node);  DECL_CONTEXT (label_decl) = current_function_decl;  DECL_MODE (label_decl) = VOIDmode;  /* We always define the label as used, even if the original source     file never references the label.  We don't want all kinds of     spurious warnings for old-style Fortran code with too many     labels.  */  TREE_USED (label_decl) = 1;  DECL_ARTIFICIAL (label_decl) = 1;  return label_decl;}/* Returns the return label for the current function.  */treegfc_get_return_label (void){  char name[GFC_MAX_SYMBOL_LEN + 10];  if (current_function_return_label)    return current_function_return_label;  sprintf (name, "__return_%s",	   IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));  current_function_return_label =    gfc_build_label_decl (get_identifier (name));  DECL_ARTIFICIAL (current_function_return_label) = 1;  return current_function_return_label;}/* Set the backend source location of a decl.  */voidgfc_set_decl_location (tree decl, locus * loc){#ifdef USE_MAPPED_LOCATION  DECL_SOURCE_LOCATION (decl) = loc->lb->location;#else  DECL_SOURCE_LINE (decl) = loc->lb->linenum;  DECL_SOURCE_FILE (decl) = loc->lb->file->filename;#endif}/* Return the backend label declaration for a given label structure,   or create it if it doesn't exist yet.  */treegfc_get_label_decl (gfc_st_label * lp){  if (lp->backend_decl)    return lp->backend_decl;  else    {      char label_name[GFC_MAX_SYMBOL_LEN + 1];      tree label_decl;      /* Validate the label declaration from the front end.  */      gcc_assert (lp != NULL && lp->value <= MAX_LABEL_VALUE);      /* Build a mangled name for the label.  */      sprintf (label_name, "__label_%.6d", lp->value);      /* Build the LABEL_DECL node.  */      label_decl = gfc_build_label_decl (get_identifier (label_name));      /* Tell the debugger where the label came from.  */      if (lp->value <= MAX_LABEL_VALUE)	/* An internal label.  */	gfc_set_decl_location (label_decl, &lp->where);      else	DECL_ARTIFICIAL (label_decl) = 1;      /* Store the label in the label list and return the LABEL_DECL.  */      lp->backend_decl = label_decl;      return label_decl;    }}/* Convert a gfc_symbol to an identifier of the same name.  */static treegfc_sym_identifier (gfc_symbol * sym){  return (get_identifier (sym->name));}/* Construct mangled name from symbol name.  */static treegfc_sym_mangled_identifier (gfc_symbol * sym){  char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];  if (sym->module == NULL)    return gfc_sym_identifier (sym);  else    {      snprintf (name, sizeof name, "__%s__%s", sym->module, sym->name);      return get_identifier (name);    }}/* Construct mangled function name from symbol name.  */static treegfc_sym_mangled_function_id (gfc_symbol * sym){  int has_underscore;  char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];  if (sym->module == NULL || sym->attr.proc == PROC_EXTERNAL      || (sym->module != NULL && sym->attr.if_source == IFSRC_IFBODY))    {      if (strcmp (sym->name, "MAIN__") == 0	  || sym->attr.proc == PROC_INTRINSIC)	return get_identifier (sym->name);      if (gfc_option.flag_underscoring)	{	  has_underscore = strchr (sym->name, '_') != 0;	  if (gfc_option.flag_second_underscore && has_underscore)	    snprintf (name, sizeof name, "%s__", sym->name);	  else	    snprintf (name, sizeof name, "%s_", sym->name);	  return get_identifier (name);	}      else	return get_identifier (sym->name);    }  else    {      snprintf (name, sizeof name, "__%s__%s", sym->module, sym->name);      return get_identifier (name);    }}/* Returns true if a variable of specified size should go on the stack.  */intgfc_can_put_var_on_stack (tree size){  unsigned HOST_WIDE_INT low;  if (!INTEGER_CST_P (size))    return 0;  if (gfc_option.flag_max_stack_var_size < 0)    return 1;  if (TREE_INT_CST_HIGH (size) != 0)    return 0;  low = TREE_INT_CST_LOW (size);  if (low > (unsigned HOST_WIDE_INT) gfc_option.flag_max_stack_var_size)    return 0;/* TODO: Set a per-function stack size limit.  */  return 1;}/* gfc_finish_cray_pointee sets DECL_VALUE_EXPR for a Cray pointee to   an expression involving its corresponding pointer.  There are   2 cases; one for variable size arrays, and one for everything else,   because variable-sized arrays require one fewer level of   indirection.  */static voidgfc_finish_cray_pointee (tree decl, gfc_symbol *sym){  tree ptr_decl = gfc_get_symbol_decl (sym->cp_pointer);  tree value;  /* Parameters need to be dereferenced.  */  if (sym->cp_pointer->attr.dummy)     ptr_decl = gfc_build_indirect_ref (ptr_decl);  /* Check to see if we're dealing with a variable-sized array.  */  if (sym->attr.dimension      && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)     {        /* These decls will be dereferenced later, so we don't dereference	 them here.  */      value = convert (TREE_TYPE (decl), ptr_decl);    }  else    {      ptr_decl = convert (build_pointer_type (TREE_TYPE (decl)),			  ptr_decl);      value = gfc_build_indirect_ref (ptr_decl);    }  SET_DECL_VALUE_EXPR (decl, value);  DECL_HAS_VALUE_EXPR_P (decl) = 1;  /* This is a fake variable just for debugging purposes.  */  TREE_ASM_WRITTEN (decl) = 1;}/* Finish processing of a declaration and install its initial value.  */static voidgfc_finish_decl (tree decl, tree init){  if (TREE_CODE (decl) == PARM_DECL)    gcc_assert (init == NULL_TREE);  /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se     -- it overlaps DECL_ARG_TYPE.  */  else if (init == NULL_TREE)    gcc_assert (DECL_INITIAL (decl) == NULL_TREE);  else    gcc_assert (DECL_INITIAL (decl) == error_mark_node);  if (init != NULL_TREE)    {      if (TREE_CODE (decl) != TYPE_DECL)	DECL_INITIAL (decl) = init;      else	{	  /* typedef foo = bar; store the type of bar as the type of foo.  */	  TREE_TYPE (decl) = TREE_TYPE (init);	  DECL_INITIAL (decl) = init = 0;	}    }  if (TREE_CODE (decl) == VAR_DECL)    {      if (DECL_SIZE (decl) == NULL_TREE	  && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)	layout_decl (decl, 0);      /* A static variable with an incomplete type is an error if it is         initialized. Also if it is not file scope. Otherwise, let it         through, but if it is not `extern' then it may cause an error         message later.  */      /* An automatic variable with an incomplete type is an error.  */      if (DECL_SIZE (decl) == NULL_TREE          && (TREE_STATIC (decl) ? (DECL_INITIAL (decl) != 0				    || DECL_CONTEXT (decl) != 0)                                 : !DECL_EXTERNAL (decl)))	{	  gfc_fatal_error ("storage size not known");	}      if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))	  && (DECL_SIZE (decl) != 0)	  && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))	{	  gfc_fatal_error ("storage size not constant");	}    }}

⌨️ 快捷键说明

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