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

📄 loop.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
  pushlevel (0); /* this happens only in pass 2 */  declare_temps ();  clear_last_expr ();  push_momentary ();  expand_start_bindings (0);}voidnonvalue_end_loop_scope (){  expand_end_bindings (getdecls (), kept_level_p (), 0);  pop_momentary ();  poplevel (kept_level_p (), 1, 0);}/* The iterator structure records all aspects of a  * 'FOR i := start [DOWN] TO end' clause or * 'FOR i IN modename' or 'FOR i IN powerset' clause. * It's saved on the iter_list of the current LOOP. */voidbuild_loop_iterator (user_var, start_exp, step_exp, end_exp, 		     down_flag, in_flag, ever_flag)     tree user_var, start_exp, step_exp, end_exp;     int  down_flag, in_flag, ever_flag;{  ITERATOR *ip = (ITERATOR *)xmalloc (sizeof (ITERATOR));  /* chain this iterator onto the current loop */  if (loopstack->iter_list == NULL)    loopstack->iter_list = ip;  else    {      ITERATOR *temp = loopstack->iter_list;      while (temp->next != NULL)	temp = temp->next;      temp->next = ip;    }  ip->user_var      = user_var;  ip->start_exp     = start_exp;  ip->step_exp      = step_exp;  ip->end_exp       = end_exp;  ip->start_temp    = NULL_TREE;  ip->end_temp      = NULL_TREE;  ip->step_temp     = NULL_TREE;  ip->down_flag     = down_flag;  ip->powerset_temp = NULL_TREE;  ip->iter_var      = NULL_TREE;  ip->iter_type     = NULL_TREE;  ip->stepin_type   = NULL_TREE;  ip->loc_ptr_temp  = NULL_TREE;  ip->error_flag    = 1;          /* assume error will be found */  ip->next          = (ITERATOR *)0;  if (ever_flag)    ip->itype = DO_FOREVER;  else if (in_flag && start_exp != NULL_TREE)    {      if (TREE_CODE (start_exp) == ERROR_MARK)	return;      if (TREE_TYPE (start_exp) == NULL_TREE)	{	  if (TREE_CODE (start_exp) == CONSTRUCTOR)	    error ("modeless tuple not allowed in this context");	  else	    error ("IN expression does not have a mode");	  return;	}      if (TREE_CODE (TREE_TYPE (start_exp)) == SET_TYPE)	{	  if (CH_BOOLS_TYPE_P (TREE_TYPE (start_exp)))	    {	      sorry ("location enumeration for BOOLS");	      return;	    }	  ip->itype = DO_POWERSET;	}      else if (discrete_type_p (TREE_TYPE (ip->start_exp)))	{	  /* range enumeration */	  tree type = TREE_TYPE (ip->start_exp);	  /* save the original type for later use in determine to do a	     rangecheck or not */	  ip->stepin_type = type;	  ip->itype = DO_STEP;	  if (ip->down_flag)	    {	      ip->start_exp = build_chill_upper (type);	      ip->end_exp = build_chill_lower (type);	    }	  else	    {	      ip->start_exp = build_chill_lower (type);	      ip->end_exp = build_chill_upper (type);	    }	}      else if (TREE_CODE (TREE_TYPE (ip->start_exp)) == ARRAY_TYPE)	{	  if (TYPE_PACKED (TREE_TYPE (ip->start_exp)))	    {	      sorry ("location enumeration for bit-packed arrays");	      return;	    }	  ip->itype = DO_LOC;	}      else if (chill_varying_type_p (TREE_TYPE (ip->start_exp)))	ip->itype = DO_LOC_VARYING;      else	{	  error ("Loop's IN expression is not a composite object");	  return;	}    }  else    ip->itype = DO_STEP;  if (ip->itype == DO_STEP)    {      struct ch_class class;      if (ip->step_exp == NULL_TREE)	ip->step_exp = integer_one_node;      if (! discrete_type_p (TREE_TYPE (ip->start_exp)))	{	  error ("start expr must have discrete mode");	  return;	}      if (TREE_CODE (TREE_TYPE (ip->start_exp)) == ENUMERAL_TYPE	  && CH_ENUM_IS_NUMBERED (TREE_TYPE (ip->start_exp)))	{	  error ("DO FOR start expression is a numbered SET");	  return;	}      if (TREE_CODE (ip->end_exp) == ERROR_MARK)	return;      if (TREE_CODE (TREE_TYPE (ip->end_exp)) == ENUMERAL_TYPE	  && CH_ENUM_IS_NUMBERED (TREE_TYPE (ip->end_exp)))	{	  error ("TO expression is a numbered SET");	  return;	}      if (! discrete_type_p (TREE_TYPE (ip->end_exp)))	{	  error ("TO expr must have discrete mode");	  return;	}      if (! CH_COMPATIBLE_CLASSES (ip->start_exp, ip->end_exp))	{	  error ("start expr and TO expr must be compatible");	  return;	}      if (step_exp != NULL_TREE)	{	  if (TREE_CODE (step_exp) == ERROR_MARK)	    return;	  if (! discrete_type_p (TREE_TYPE (step_exp)))	    {	      error ("BY expr must have discrete mode");	      return;	    }	  if (! CH_COMPATIBLE_CLASSES (ip->start_exp, step_exp))	    {	      error ("start expr and BY expr must be compatible");	      return;	    }	}      if (! flag_local_loop_counter)	{	  /* In this case, it's a previously-declared VAR_DECL node. */	  tree id_node = ip->user_var;	  if (TREE_CODE (ip->user_var) == IDENTIFIER_NODE)	    ip->user_var = lookup_name (ip->user_var);	  /* Chill 1984 allows the name to be a defining occurrence,	     but does not require it. */	  if (ip->user_var == NULL_TREE)	    {	      warning ("loop identifier undeclared");	      ip->user_var = id_node;	      /* We declare a local name below. */	    }	  else	    {	      if (TREE_CODE (TREE_TYPE (ip->user_var)) == REFERENCE_TYPE)		ip->user_var = convert_from_reference (ip->user_var);	      if (! CH_COMPATIBLE_CLASSES (ip->start_exp, ip->user_var))		{		  error ("loop variable incompatible with start expression");		  return;		}	      class = chill_expr_class (ip->user_var);	    }	}      /* Otherwise, declare a new name. */      if (TREE_CODE (ip->user_var) == IDENTIFIER_NODE)	{	  class = CH_RESULTING_CLASS (chill_expr_class (ip->start_exp),				      chill_expr_class (ip->end_exp));	  if (step_exp)	    class = CH_RESULTING_CLASS (class, chill_expr_class (step_exp));	  /* Integer literals noramally have type 'long long'	     (see convert_integer in lex.c).  That is usually overkill. */	  if (class.kind == CH_DERIVED_CLASS	      && class.mode == long_long_integer_type_node	      && int_fits_type_p (ip->start_exp, integer_type_node)	      && int_fits_type_p (ip->end_exp, integer_type_node))	    class.mode = integer_type_node;	}      if (TREE_CODE (ip->start_exp) == INTEGER_CST	  && TREE_CODE (ip->end_exp) == INTEGER_CST	  && compare_int_csts (ip->down_flag ? LT_EXPR : GT_EXPR,			       ip->start_exp, ip->end_exp))	warning ("body of DO FOR will never execute");      ip->start_exp = convert_to_class (class, ip->start_exp);      ip->end_exp   = convert_to_class (class, ip->end_exp);      ip->step_exp = convert_to_class (class, ip->step_exp);      if (TREE_CODE (ip->step_exp) != INTEGER_CST)	{	  /* generate runtime check for negative BY expr */	  ip->step_exp = 	    check_range (ip->step_exp, ip->step_exp,			 integer_zero_node, NULL_TREE);	}      else if (compare_int_csts (LE_EXPR, ip->step_exp, integer_zero_node))	{	  error ("BY expression is negative or zero");	  return;	}    }  ip->error_flag = 0;           /* no errors! */}voidbuild_loop_start (start_label)     tree start_label;{  ITERATOR *firstp = loopstack->iter_list;    if (firstp->error_flag)    return;  maybe_skip_loop ();  if (initialize_iter_var ())    return;  /* use the label as an 'exit' label,      'goto' needs another sort of label */  expand_start_loop (start_label != NULL_TREE);}/* * Called after the last action of the loop body * has been parsed. */voidbuild_loop_end (){  ITERATOR *ip = loopstack->iter_list;  emit_line_note (input_filename, lineno);  if (ip->error_flag)    return;  if (bottom_loop_end_check ())    return;  if (increment_temps ())    return;  expand_end_loop ();  for (; ip != NULL; ip = ip->next)    {      switch (ip->itype)	{	case DO_LOC_VARYING:	case DO_STEP:	  expand_end_cond ();	  break;	default:	  break;	}    }}/* * Reserve space for any loop-control temporaries, initialize them */static intdeclare_temps (){  ITERATOR *firstp = loopstack->iter_list, *ip;  tree start_ptr;  for (ip = firstp; ip != NULL; ip = ip->next)    {      switch (ip->itype)	{	case DO_FOREVER:	  break;	case DO_STEP:	  ip->iter_type	    = type_for_size (TYPE_PRECISION (TREE_TYPE (ip->start_exp)), 1);	  /* create, initialize temporaries if expressions aren't constant */	  ip->start_temp = maybe_make_for_temp (ip->start_exp, "for_start",						TREE_TYPE (ip->start_exp));	  ip->end_temp = maybe_make_for_temp (ip->end_exp, "for_end",					      TREE_TYPE (ip->end_exp));	  /* this is just the step-expression */	  ip->step_temp    = maybe_make_for_temp (ip->step_exp, "for_step",						  TREE_TYPE (ip->step_exp));	  if (TREE_CODE (ip->user_var) == IDENTIFIER_NODE)	    {	      /* (re-)declare the user's iteration variable in the 		 loop's scope. */	      tree id_node = ip->user_var;	      ip->user_var = 		decl_temp1 (id_node, TREE_TYPE (ip->start_exp), 0, NULL_TREE,			    0, 0);	      CH_DERIVED_FLAG (ip->user_var) = CH_DERIVED_FLAG (ip->start_exp);	      pushdecl (ip->user_var);	    }	  ip->iter_var = 	    decl_temp1 (get_unique_identifier ("iter_var"),			ip->iter_type, 0, NULL_TREE, 0, 0);	  break;	case DO_POWERSET:	  /* the user's powerset-expression */	  ip->powerset_temp = save_expr (ip->start_exp);	  mark_addressable (ip->powerset_temp);	  ip->iter_type = integer_type_node;	  ip->iter_var = decl_temp1 (get_unique_identifier ("iter_var"),				     ip->iter_type, 0,				     !ip->down_flag ? integer_zero_node				     : powersetlen (ip->powerset_temp),				     0, 0);	  if (flag_local_loop_counter)	    {	      /* declare the user's iteration variable in the loop's scope. */	      /* in this case, it's just an IDENTIFIER_NODE */	      ip->user_var = 		decl_temp1 (ip->user_var,			    TYPE_DOMAIN (TREE_TYPE (ip->start_exp)),			    0, NULL_TREE, 0, 0);	      pushdecl (ip->user_var);	    }	  else	    {	      /* in this case, it's a previously-declared VAR_DECL node */	      ip->user_var = lookup_name (ip->user_var);	    }	  break;	case DO_LOC:	case DO_LOC_VARYING:	  ip->iter_type = chill_unsigned_type_node;	  /* create the counter temp */	  ip->iter_var = 	    build_temporary_variable ("iter_var", ip->iter_type);	  if (!CH_LOCATION_P (ip->start_exp))	    ip->start_exp	      = decl_temp1 (get_unique_identifier ("iter_loc"),			    TREE_TYPE (ip->start_exp), 0,			    ip->start_exp, 0, 0);	  if (ip->itype == DO_LOC)	    {	      tree array_type = TREE_TYPE (ip->start_exp);	      tree ptr_type;	      tree temp;	      	      /* FIXME: check for array type in ip->start_exp */	      /* create pointer temporary */	      ip->base_type = TREE_TYPE (array_type);	      ptr_type = build_pointer_type (ip->base_type);	      ip->loc_ptr_temp =		build_temporary_variable ("loc_ptr_tmp", ptr_type);	      	      /* declare the user's iteration variable in 		 the loop's scope, as an expression, to be		 passed to build_component_ref later */	      save_expr_under_name (ip->user_var, 		build1 (INDIRECT_REF, ip->base_type, 			ip->loc_ptr_temp));	      	      /* FIXME: see stor_layout */	      ip->step_temp = size_in_bytes (ip->base_type);	      	      temp = TYPE_DOMAIN (array_type);	      /* pointer to first array entry to look at */	      start_ptr = build1 (ADDR_EXPR, ptr_type, ip->start_exp);	      mark_addressable (ip->start_exp);	      ip->start_temp = ip->down_flag ? 

⌨️ 快捷键说明

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