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

📄 satisfy.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Name-satisfaction for GNU Chill compiler.   Copyright (C) 1993, 1998 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.  */#include "config.h"#include "system.h"#include "tree.h"#include "flags.h"#include "ch-tree.h"#include "lex.h"#include "toplev.h"#define SATISFY(ARG) ((ARG) = satisfy(ARG, chain))struct decl_chain{  struct decl_chain *prev;  /* DECL can be a decl, or a POINTER_TYPE or a REFERENCE_TYPE. */  tree decl;};/* forward declaration */tree satisfy PROTO((tree, struct decl_chain *));static struct decl_chain dummy_chain;#define LOOKUP_ONLY (chain==&dummy_chain)/* Recursive helper routine to logically reverse the chain. */static voidcycle_error_print (chain, decl)     struct decl_chain *chain;     tree decl;{  if (chain->decl != decl)    {      cycle_error_print (chain->prev, decl);      if (TREE_CODE_CLASS (TREE_CODE (chain->decl)) == 'd')	error_with_decl (chain->decl, "  `%s', which depends on ...");    }}treesafe_satisfy_decl (decl, prev_chain)     tree decl;     struct decl_chain *prev_chain;{  struct decl_chain new_link;  struct decl_chain *link;  struct decl_chain *chain = prev_chain;  char *save_filename = input_filename;  int save_lineno = lineno;  tree result = decl;    if (decl == NULL_TREE)    return decl;  if (!LOOKUP_ONLY)    {      int pointer_type_breaks_cycle = 0;      /* Look for a cycle.	 We could do this test more efficiently by setting a flag.  FIXME */      for (link = prev_chain; link != NULL; link = link->prev)	{	  if (TREE_CODE_CLASS (TREE_CODE (link->decl)) != 'd')	    pointer_type_breaks_cycle = 1;	  if (link->decl == decl)	    {	      if (!pointer_type_breaks_cycle)		{		  error_with_decl (decl, "Cycle: `%s' depends on ...");		  cycle_error_print (prev_chain, decl);		  error_with_decl (decl, "  `%s'");		  return error_mark_node;		}	      /* There is a cycle, but it includes a pointer type,		 so we're OK.  However, we still have to continue		 the satisfy (for example in case this is a TYPE_DECL		 that points to a LANG_DECL).  The cycle-check for		 POINTER_TYPE/REFERENCE_TYPE should stop the recursion. */	      break;	    }	}      new_link.decl = decl;      new_link.prev = prev_chain;      chain = &new_link;    }  input_filename = DECL_SOURCE_FILE (decl);  lineno = DECL_SOURCE_LINE (decl);  switch ((enum chill_tree_code)TREE_CODE (decl))    {    case ALIAS_DECL:      if (!LOOKUP_ONLY && !DECL_POSTFIX_ALL(decl))	result = safe_satisfy_decl (DECL_ABSTRACT_ORIGIN (decl), chain);      break;    case BASED_DECL:      SATISFY (TREE_TYPE (decl));      SATISFY (DECL_ABSTRACT_ORIGIN (decl));      break;    case CONST_DECL:      SATISFY (TREE_TYPE (decl));      SATISFY (DECL_INITIAL (decl));      if (!LOOKUP_ONLY)	{	  if (DECL_SIZE (decl) == 0)	    {	      tree init_expr = DECL_INITIAL (decl);	      tree init_type;	      tree specified_mode = TREE_TYPE (decl);	      if (init_expr == NULL_TREE		  || TREE_CODE (init_expr) == ERROR_MARK)		goto bad_const;	      init_type = TREE_TYPE (init_expr);	      if (specified_mode == NULL_TREE)		{		  if (init_type == NULL_TREE)		    {		      check_have_mode (init_expr, "SYN without mode");		      goto bad_const;		    }		  TREE_TYPE (decl) = init_type;		  CH_DERIVED_FLAG (decl) = CH_DERIVED_FLAG (init_expr);		}	      else if (CH_IS_ASSOCIATION_MODE (specified_mode) ||		       CH_IS_ACCESS_MODE (specified_mode) || CH_IS_TEXT_MODE (specified_mode) ||		       CH_IS_BUFFER_MODE (specified_mode) || CH_IS_EVENT_MODE (specified_mode))		{		  error ("SYN of this mode not allowed");		  goto bad_const;		}	      else if (!CH_COMPATIBLE (init_expr, specified_mode))		{		  error ("mode of SYN incompatible with value");		  goto bad_const;		} 	      else if (discrete_type_p (specified_mode)		       && TREE_CODE (init_expr) == INTEGER_CST		       && (compare_int_csts (LT_EXPR, init_expr,					     TYPE_MIN_VALUE (specified_mode))			   || compare_int_csts (GT_EXPR, init_expr,						TYPE_MAX_VALUE(specified_mode))			   ))		{		  error ("SYN value outside range of its mode");		  /* set an always-valid initial value to prevent 		     other errors. */		  DECL_INITIAL (decl) = TYPE_MIN_VALUE (specified_mode);		}	      else if (CH_STRING_TYPE_P (specified_mode) 		       && (init_type && CH_STRING_TYPE_P (init_type))		       && integer_zerop (string_assignment_condition (specified_mode, init_expr)))		{		  error ("INIT string too large for mode");		  DECL_INITIAL (decl) = error_mark_node;		}	      else		{		  struct ch_class class;		  class.mode = TREE_TYPE (decl);		  class.kind = CH_VALUE_CLASS;		  DECL_INITIAL (decl)		    = convert_to_class (class, DECL_INITIAL (decl));		}	      /* DECL_SIZE is set to prevent re-doing this stuff. */	      DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));	      if (! TREE_CONSTANT (DECL_INITIAL (decl))		  && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK)		{		  error_with_decl (decl,				   "value of %s is not a valid constant");		  DECL_INITIAL (decl) = error_mark_node;		}	    }	  result = DECL_INITIAL (decl);	}      break;    bad_const:      DECL_INITIAL (decl) = error_mark_node;      TREE_TYPE (decl) = error_mark_node;      return error_mark_node;    case FUNCTION_DECL:      SATISFY (TREE_TYPE (decl));      if (CH_DECL_PROCESS (decl))	safe_satisfy_decl (DECL_TASKING_CODE_DECL (decl), 			   prev_chain);      break;    case PARM_DECL:      SATISFY (TREE_TYPE (decl));      break;    /* RESULT_DECL doesn't need to be satisfied;         it's only built internally in pass 2 */    case TYPE_DECL:      SATISFY (TREE_TYPE (decl));      if (CH_DECL_SIGNAL (decl))	safe_satisfy_decl (DECL_TASKING_CODE_DECL (decl), 			   prev_chain);      if (!LOOKUP_ONLY)	{	  if (TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE)	    TYPE_NAME (TREE_TYPE (decl)) = decl;	  layout_decl (decl, 0);	  if (CH_DECL_SIGNAL (decl) && CH_TYPE_NONVALUE_P (TREE_TYPE (decl)))	    error ("mode with non-value property in signal definition");	  result = TREE_TYPE (decl);	}      break;    case VAR_DECL:      SATISFY (TREE_TYPE (decl));      if (!LOOKUP_ONLY)	{	  layout_decl (decl, 0);	  if (TREE_READONLY (TREE_TYPE (decl)))	    TREE_READONLY (decl) = 1;	}      break;    default:      ;    }  /* Now set the DECL_RTL, if needed. */  if (!LOOKUP_ONLY && DECL_RTL (decl) == 0      && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL	  || TREE_CODE (decl) == CONST_DECL))    {      if (TREE_CODE (decl) == FUNCTION_DECL && decl_function_context (decl))	make_function_rtl (decl);      else if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))	expand_decl (decl);      else	{ char * asm_name;	  if (current_module == 0 || TREE_PUBLIC (decl)	      || current_function_decl)	    asm_name = NULL;	  else	    {	      asm_name = (char*)		alloca (IDENTIFIER_LENGTH (current_module->prefix_name)			+ IDENTIFIER_LENGTH (DECL_NAME (decl)) + 3);	      sprintf (asm_name, "%s__%s",		       IDENTIFIER_POINTER (current_module->prefix_name),		       IDENTIFIER_POINTER (DECL_NAME (decl)));	    }	  make_decl_rtl (decl, asm_name, TREE_PUBLIC (decl));	}    }  input_filename = save_filename;  lineno = save_lineno;  return result;}treesatisfy_decl (decl, lookup_only)     tree decl;     int lookup_only;{  return safe_satisfy_decl (decl, lookup_only ? &dummy_chain : NULL);}static voidsatisfy_list (exp, chain)     register tree exp;     struct decl_chain *chain;{  for (; exp != NULL_TREE; exp = TREE_CHAIN (exp))    {      SATISFY (TREE_VALUE (exp));      SATISFY (TREE_PURPOSE (exp));    }}static voidsatisfy_list_values (exp, chain)     register tree exp;     struct decl_chain *chain;{  for (; exp != NULL_TREE; exp = TREE_CHAIN (exp))    {      SATISFY (TREE_VALUE (exp));    }}treesatisfy (exp, chain)     tree exp;     struct decl_chain *chain;{  int arg_length;  int i;  tree decl;  if (exp == NULL_TREE)    return NULL_TREE;

⌨️ 快捷键说明

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