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

📄 expr.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
			   0, VOIDmode, 3, XEXP (targetx, 0), Pmode,			   op0, GET_MODE (op0),			   expand_expr (tsize, NULL_RTX, MEM, 					EXPAND_CONST_ADDRESS),			   TYPE_MODE (long_unsigned_type_node));	if (targetx != target)	  emit_move_insn (target, targetx);	return target;      }    case SET_DIFF_EXPR:      lib_func = "__diffpowerset";      goto format_2;    case SET_IOR_EXPR:      lib_func = "__orpowerset";      goto format_2;    case SET_XOR_EXPR:      lib_func = "__xorpowerset";      goto format_2;    /* void __diffpowerset (char *out, char *left, char *right,                            unsigned bitlength) */    case SET_AND_EXPR:      lib_func = "__andpowerset";    format_2:      {	tree expr = TREE_OPERAND (exp, 0);	tree tsize = powersetlen (expr);	rtx targetx;	if (TREE_CODE (TREE_TYPE (expr)) != SET_TYPE)	  tsize = fold (build (MULT_EXPR, long_unsigned_type_node,			       tsize, 			       size_int (BITS_PER_UNIT)));	/* expand 1st operand to a pointer to the set */        op0 = expand_expr (force_addr_of (expr),			   NULL_RTX, MEM, EXPAND_CONST_ADDRESS);	/* expand 2nd operand to a pointer to the set */        op1 = expand_expr (force_addr_of (TREE_OPERAND (exp, 1)),			   NULL_RTX, MEM,			   EXPAND_CONST_ADDRESS);/* FIXME: re-examine this code - the unary operator code above has recently   (93/03/12) been changed a lot.  Should this code also change? */	/* build a temp for the result, target is its address */	if (target == NULL_RTX)	  {	    target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)), 					int_size_in_bytes (TREE_TYPE (exp)),					0);	    preserve_temp_slots (target);	  }	if (GET_CODE (target) == MEM)	  targetx = target;	else	  targetx = assign_stack_temp (GET_MODE (target),				       GET_MODE_SIZE (GET_MODE (target)), 0);	emit_library_call (gen_rtx(SYMBOL_REF, Pmode, lib_func),			   0, VOIDmode, 4, XEXP (targetx, 0), Pmode,			   op0, GET_MODE (op0), op1, GET_MODE (op1),			   expand_expr (tsize, NULL_RTX, MEM, 					EXPAND_CONST_ADDRESS),			   TYPE_MODE (long_unsigned_type_node));	if (target != targetx)	  emit_move_insn (target, targetx);	return target;      }    case SET_IN_EXPR:      {	tree set = TREE_OPERAND (exp, 1);	tree pos = convert (long_unsigned_type_node, TREE_OPERAND (exp, 0));	tree set_type = TREE_TYPE (set);	tree set_length = discrete_count (TYPE_DOMAIN (set_type));	tree min_val = convert (long_integer_type_node,				TYPE_MIN_VALUE (TYPE_DOMAIN (set_type)));	tree fcall;		/* FIXME: Function-call not needed if pos and width are constant! */	if (! mark_addressable (set))	  {	    error ("powerset is not addressable");	    return const0_rtx;	  }	/* we use different functions for bitstrings and powersets */	if (CH_BOOLS_TYPE_P (set_type))	  fcall =             build_chill_function_call (               lookup_name (get_identifier ("__inbitstring")),	         tree_cons (NULL_TREE, 	           convert (long_unsigned_type_node, pos), 		     tree_cons (NULL_TREE,		       build1 (ADDR_EXPR, build_pointer_type (set_type), set),		         tree_cons (NULL_TREE, 		           convert (long_unsigned_type_node, set_length),		             tree_cons (NULL_TREE, min_val,                               tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),                                 build_tree_list (NULL_TREE, get_chill_linenumber ())))))));	else	  fcall =             build_chill_function_call (               lookup_name (get_identifier ("__inpowerset")),	         tree_cons (NULL_TREE, 	           convert (long_unsigned_type_node, pos), 		     tree_cons (NULL_TREE,		       build1 (ADDR_EXPR, build_pointer_type (set_type), set),		         tree_cons (NULL_TREE, 		           convert (long_unsigned_type_node, set_length),		             build_tree_list (NULL_TREE, min_val)))));	return expand_expr (fcall, NULL_RTX, VOIDmode, 0);      }    case PACKED_ARRAY_REF:      {	tree array = TREE_OPERAND (exp, 0);	tree pos = save_expr (TREE_OPERAND (exp, 1));	tree array_type = TREE_TYPE (array);	tree array_length = discrete_count (TYPE_DOMAIN (array_type));	tree min_val = convert (long_integer_type_node,				TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)));	tree fcall;		/* FIXME: Function-call not needed if pos and width are constant! */	/* TODO: make sure this makes sense. */	if (! mark_addressable (array))	  {	    error ("array is not addressable");	    return const0_rtx;	  }	fcall =	  build_chill_function_call (               lookup_name (get_identifier ("__inpowerset")),	         tree_cons (NULL_TREE, 	           convert (long_unsigned_type_node, pos), 		     tree_cons (NULL_TREE,		       build1 (ADDR_EXPR, build_pointer_type (array_type), array),		         tree_cons (NULL_TREE, 		           convert (long_unsigned_type_node, array_length),		             build_tree_list (NULL_TREE, min_val)))));	return expand_expr (fcall, NULL_RTX, VOIDmode, 0);      }    case UNDEFINED_EXPR:      if (target == 0)	{	  target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)), 				      int_size_in_bytes (TREE_TYPE (exp)), 0);	  preserve_temp_slots (target);	}      /* We don't actually need to *do* anything ... */      return target;    default:      break;    }  /* NOTREACHED */  return NULL;}/* Check that the argument list has a length in [min_length .. max_length].   (max_length == -1 means "infinite".)   If so return the actual length.   Otherwise, return an error message and return -1. */static intcheck_arglist_length (args, min_length, max_length, name)     tree args;     int min_length;     int max_length;     tree name;{  int length = list_length (args);  if (length < min_length)    error ("Too few arguments in call to `%s'", IDENTIFIER_POINTER (name));  else if (max_length != -1 && length > max_length)    error ("Too many arguments in call to `%s'", IDENTIFIER_POINTER (name));  else    return length;  return -1;}/* * This is the code from c-typeck.c, with the C-specific cruft * removed (possibly I just didn't understand it, but it was * apparently simply discarding part of my LIST). */static treeinternal_build_compound_expr (list, first_p)     tree list;     int first_p ATTRIBUTE_UNUSED;{  register tree rest;  if (TREE_CHAIN (list) == 0)    return TREE_VALUE (list);  rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);  if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))    return rest;  return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);}/* Given a list of expressions, return a compound expression   that performs them all and returns the value of the last of them.  *//* FIXME: this should be merged with the C version */treebuild_chill_compound_expr (list)     tree list;{  return internal_build_compound_expr (list, TRUE);}/* Given an expression PTR for a pointer, return an expression   for the value pointed to.   do_empty_check is 0, don't perform a NULL pointer check,   else do it. */treebuild_chill_indirect_ref (ptr, mode, do_empty_check)     tree ptr;     tree mode;     int do_empty_check;{  register tree type;  if (ptr == NULL_TREE || TREE_CODE (ptr) == ERROR_MARK)    return ptr;  if (mode != NULL_TREE && TREE_CODE (mode) == ERROR_MARK)    return error_mark_node;  type = TREE_TYPE (ptr);  if (TREE_CODE (type) == REFERENCE_TYPE)    {      type = TREE_TYPE (type);      ptr = convert (type, ptr);    }  /* check for ptr is really a POINTER */  if (TREE_CODE (type) != POINTER_TYPE)    {      error ("cannot dereference, not a pointer.");      return error_mark_node;    }    if (mode && TREE_CODE (mode) == IDENTIFIER_NODE)    {      tree decl = lookup_name (mode);      if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)	{	  if (pass == 2)	    error ("missing '.' operator or undefined mode name `%s'.",		   IDENTIFIER_POINTER (mode));#if 0	  error ("You have forgotten the '.' operator which must");	  error (" precede a STRUCT field reference, or `%s' is an undefined mode", 		 IDENTIFIER_POINTER (mode));#endif	  return error_mark_node;	}    }  if (mode)    {      mode = get_type_of (mode);      ptr = convert (build_pointer_type (mode), ptr);    }  else if (type == ptr_type_node)    {      error ("Can't dereference PTR value using unary `->'.");      return error_mark_node;    }  if (do_empty_check)    ptr = check_non_null (ptr);  type = TREE_TYPE (ptr);  if (TREE_CODE (type) == POINTER_TYPE)    {      if (TREE_CODE (ptr) == ADDR_EXPR	  && !flag_volatile	  && (TREE_TYPE (TREE_OPERAND (ptr, 0))	      == TREE_TYPE (type)))	return TREE_OPERAND (ptr, 0);      else	{	  tree t = TREE_TYPE (type);	  register tree ref = build1 (INDIRECT_REF,				      TYPE_MAIN_VARIANT (t), ptr);	  if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)	    {	      error ("dereferencing pointer to incomplete type");	      return error_mark_node;	    }	  if (TREE_CODE (t) == VOID_TYPE)	    warning ("dereferencing `void *' pointer");	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,	     so that we get the proper error message if the result is used	     to assign to.  Also, &* is supposed to be a no-op.	     And ANSI C seems to specify that the type of the result	     should be the const type.  */	  /* A de-reference of a pointer to const is not a const.  It is valid	     to change it via some other pointer.  */	  TREE_READONLY (ref) = TYPE_READONLY (t);	  TREE_SIDE_EFFECTS (ref)	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (ptr) || flag_volatile;	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t) || flag_volatile;	  return ref;	}    }  else if (TREE_CODE (ptr) != ERROR_MARK)    error ("invalid type argument of `->'");  return error_mark_node;}/* NODE is a COMPONENT_REF whose mode is an IDENTIFIER,   which is replaced by the proper FIELD_DECL.   Also do the right thing for variant records. */treeresolve_component_ref (node)     tree node;{  tree datum = TREE_OPERAND (node, 0);  tree field_name = TREE_OPERAND (node, 1);  tree type = TREE_TYPE (datum);  tree field;  if (TREE_CODE (datum) == ERROR_MARK)    return error_mark_node;  if (TREE_CODE (type) == REFERENCE_TYPE)    {      type = TREE_TYPE (type);      TREE_OPERAND (node, 0) = datum = convert (type, datum);    }  if (TREE_CODE (type) != RECORD_TYPE)    {      error ("operand of '.' is not a STRUCT");      return error_mark_node;    }  TREE_READONLY (node) = TREE_READONLY (datum);  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (datum);  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))    {      if (TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)	{	  tree variant;	  for (variant = TYPE_FIELDS (TREE_TYPE (field));	       variant;  variant = TREE_CHAIN (variant))	    {	      tree vfield;	      for (vfield = TYPE_FIELDS (TREE_TYPE (variant));		   vfield; vfield = TREE_CHAIN (vfield))		{		  if (DECL_NAME (vfield) == field_name)		    { /* Found a variant field */		      datum = build (COMPONENT_REF, TREE_TYPE (field),				     datum, field);		      datum = build (COMPONENT_REF, TREE_TYPE (variant),				     datum, variant);		      TREE_OPERAND (node, 0) = datum;		      TREE_OPERAND (node, 1) = vfield;		      TREE_TYPE (node) = TREE_TYPE (vfield);		      TREE_READONLY (node) |= TYPE_READONLY (TREE_TYPE (node));#if 0		      if (flag_testing_tags)			{			  tree tagtest = NOT IMPLEMENTED;			  tree tagf = ridpointers[(int) RID_RANGEFAIL];			  node = check_expression (node, tagtest,						   tagf);			}#endif		      return node;		    }		}	    }	}      if (DECL_NAME (field) == field_name)	{ /* Found a fixed field */	  TREE_OPERAND (node, 1) = field;	  TREE_TYPE (node) = TREE_TYPE (field);	  TREE_READONLY (node) |= TYPE_READONLY (TREE_TYPE (node));	  return fold (node);	}    }  error ("No field named `%s'", IDENTIFIER_POINTER (field_name));  return error_mark_node;}treebuild_component_ref (datum, field_name)  tree datum, field_name;{  tree node = build_nt (COMPONENT_REF, datum, field_name);  if (pass != 1)    node = resolve_component_ref (node);  return node;}/* function checks (for build_chill_component_ref) if a given type is really an instance type. CH_IS_INSTANCE_MODE is not strict enough in this case, i.e. SYNMODE foo = STRUCT (a, b UINT) is compatible to INSTANCE. */static intis_really_instance (type)     tree type;{  tree decl = TYPE_NAME (type);  if (decl == NULL_TREE)    /* this is not an instance */    return 0;  if (DECL_NAME (decl) == ridpointers[(int)RID_INSTANCE])    /* this is an instance */    return 1;  if (TYPE_FIELDS (type) == TYPE_FIELDS (instance_type_node))    /* we have a NEWMODE'd instance */    return 1;  return 0;}/* This function is called by the parse.   Here we check if the user tries to access a field in a type which is   layouted as a structure but isn't like INSTANCE, BUFFER, EVENT, ASSOCIATION,   ACCESS, TEXT, or VARYING array or character string.   We don't do this in build_component_ref cause this function gets   called from the compiler to access fields in one of the above mentioned   modes. */treebuild_chill_component_ref (datum, field_name)     tree datum, field_name;{  tree type = TREE_TYPE (datum);  if ((type != NULL_TREE && TREE_CODE (type) == RECORD_TYPE) &&      ((CH_IS_INSTANCE_MODE (type) && is_really_instance (type)) ||	CH_IS_BUFFER_MODE (type) ||       CH_IS_EVENT_MODE (type) || CH_IS_ASSOCIATION_MODE (type) ||       CH_IS_ACCESS_MODE (type) || CH_IS_TEXT_MODE (type) ||       chill_varying_type_p (type)))    {      error ("operand of '.' is not a STRUCT");      return error_mark_node;    }  return build_component_ref (datum, field_name);}/* * Check for invalid binary operands & unary operands * RIGHT is 1 if checking right operand or unary operand; * it is 0 if checking left operand. * * return 1 if the given operand is NOT compatible as the * operand of the given operator *

⌨️ 快捷键说明

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