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

📄 nloop.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
    return;  expand_end_bindings (getdecls (), kept_level_p (), 0);  pop_momentary ();}/* 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 (loop_stack->iter_list == NULL)    loop_stack->iter_list = ip;  else    {      ITERATOR *temp = loop_stack->iter_list;      while (temp->next != NULL)	temp = temp->next;      temp->next = ip;    }  ip->itype         = DO_UNUSED;  ip->user_var      = user_var;  ip->start_exp     = start_exp;  ip->step_exp      = step_exp;  ip->end_exp       = end_exp;  ip->condition     = NULL_TREE;  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->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_CODE (TREE_TYPE (start_exp)) == SET_TYPE)	ip->itype = DO_POWERSET;      else if (discrete_type_p (TREE_TYPE (ip->start_exp)))	ip->itype = DO_RANGE;      else if (TREE_CODE (TREE_TYPE (ip->start_exp)) == ARRAY_TYPE)	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 if (start_exp == NULL_TREE && end_exp == NULL_TREE	   && step_exp == NULL_TREE && !down_flag)    ip->itype = DO_OD;  else    {      /* FIXME: Move this to the lexer? */#define CST_FITS_INT(NODE) (TREE_CODE(NODE) == INTEGER_CST &&\            int_fits_type_p (NODE, integer_type_node))      tree max_prec_type = integer_type_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 (TREE_TYPE (ip->end_exp)) == ENUMERAL_TYPE	  && CH_ENUM_IS_NUMBERED (TREE_TYPE (ip->end_exp)))	{	  error ("TO expression is a numbered SET");	  return;	}      /* Convert all three expressions to a common precision,	 which is the largest precision they exhibit, but         INTEGER_CST nodes are built in the lexer as	 long_integer_type nodes.  We'll treat convert them to	 integer_type_nodes if possible, for faster loop times. */      if (TYPE_PRECISION (max_prec_type) <	    TYPE_PRECISION (TREE_TYPE (ip->start_exp))	  && !CST_FITS_INT (ip->start_exp))	max_prec_type = TREE_TYPE (ip->start_exp);      if (! discrete_type_p (TREE_TYPE (ip->end_exp)))	{	  error ("TO expr must have discrete mode");	  return;	}      if (! CH_COMPATIBLE (ip->start_exp, 			   TREE_TYPE (ip->end_exp)))	{	  error ("start expr and TO expr must be compatible");	  return;	}      if (TYPE_PRECISION (max_prec_type) <	    TYPE_PRECISION (TREE_TYPE (ip->end_exp))	  && !CST_FITS_INT (ip->end_exp))	max_prec_type = TREE_TYPE (ip->end_exp);      if (ip->step_exp != NULL_TREE)	{	  /* assure that default 'BY 1' gets a useful type */	  if (ip->step_exp == integer_one_node)	    ip->step_exp = convert (TREE_TYPE (ip->start_exp),				    ip->step_exp);	  if (! discrete_type_p (TREE_TYPE (ip->step_exp)))	    {	      error ("BY expr must have discrete mode");	      return;	    }	  if (! CH_COMPATIBLE (ip->start_exp,		  TREE_TYPE (ip->step_exp)))	    {	      error ("start expr and BY expr must be compatible");	      return;	    }	  if (TYPE_PRECISION (max_prec_type) <		TYPE_PRECISION (TREE_TYPE (ip->step_exp))	      && !CST_FITS_INT (ip->step_exp))	    max_prec_type = TREE_TYPE (ip->step_exp);	}      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 (max_prec_type, ip->start_exp);      ip->end_exp   = 	convert (max_prec_type, ip->end_exp);      if (ip->step_exp != NULL_TREE)	{	  ip->step_exp =	    convert (max_prec_type, 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->itype = DO_STEP;    }  ip->error_flag = 0;           /* no errors! */}voidbuild_loop_start (while_control, start_label)     tree while_control, start_label;{  ITERATOR *firstp = loop_stack->iter_list;    firstp->condition = while_control;  if (firstp->error_flag)    return;  /* We didn't know at begin_loop_scope time about the condition;     adjust iterator type now. */  if (firstp->itype == DO_OD && firstp->condition)    firstp->itype = DO_WHILE;  if (initialize_iter_var ())    return;    if (maybe_skip_loop ())    return;  /* use the label as an 'exit' label,      'goto' needs another sort of label */  expand_start_loop (start_label != NULL_TREE);    if (top_loop_end_check ())    return;  emit_line_note (input_filename, lineno); }/* * Called after the last action of the loop body * has been parsed. */voidbuild_loop_end (){  ITERATOR *ip = loop_stack->iter_list;  emit_line_note (input_filename, lineno);  if (ip->error_flag)    return;  if (bottom_loop_end_check ())    return;  if (increment_temps ())    return;  if (ip->itype != DO_OD)    {      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;	    }	}    }}/* * The rest of the routines in this file are called from * the above three routines. */static intclassify_loop (){  ITERATOR *firstp = loop_stack->iter_list, *ip;  firstp->error_flag = 0;  if (firstp->itype == DO_UNUSED || firstp->itype == DO_OD)    {      /* if we have just DO .. OD, do nothing - this is just a          BEGIN .. END without creating a new scope, and no looping  */      if (firstp->condition != NULL_TREE)	firstp->itype = DO_WHILE;      else	firstp->itype = DO_OD;    }    /* Issue a warning if the any loop counter is mentioned more      than once in the iterator list. */  for (ip = firstp; ip != NULL; ip = ip->next)    {      switch (ip->itype)	{	case DO_FOREVER:	case DO_WHILE:	  break;	case DO_STEP:	case DO_RANGE:	case DO_POWERSET:	case DO_LOC:	case DO_LOC_VARYING:	  /* FIXME: check for name uniqueness */	  break;	default:	  ;	}    }  return firstp->error_flag;}/* * Reserve space for any loop-control temporaries, initialize them */static intdeclare_temps (){  ITERATOR *firstp = loop_stack->iter_list, *ip;  tree start_ptr;  for (ip = firstp; ip != NULL; ip = ip->next)    {      switch (ip->itype)	{	case DO_FOREVER:	case DO_WHILE:	  break;	case DO_STEP:	  ip->iter_type = chill_unsigned_type (TREE_TYPE (ip->start_exp));	  /* create, initialize temporaries if expressions aren't constant */	  ip->start_temp = maybe_make_for_temp (ip->start_exp, "for_start",						ip->iter_type);	  ip->end_temp = maybe_make_for_temp (ip->end_exp, "for_end",					      ip->iter_type);	  /* this is just the step-expression */	  ip->step_temp    = maybe_make_for_temp (ip->step_exp, "for_step",						  ip->iter_type);	  goto do_step_range;	  	case DO_RANGE:	  ip->iter_type = chill_unsigned_type_node;	  	  ip->start_temp =	    (ip->down_flag ? build_chill_upper : build_chill_lower)(TREE_TYPE (ip->start_exp));	  ip->end_temp =	    (ip->down_flag ? build_chill_lower : build_chill_upper)(TREE_TYPE (ip->start_exp));	  	  ip->step_temp = integer_one_node;	  	do_step_range:	  if (flag_local_loop_counter)	    {	      /* (re-)declare the user's iteration variable in the 		 loop's scope. */	      tree id_node = ip->user_var;	      IDENTIFIER_LOCAL_VALUE (id_node) = ip->user_var = 		decl_temp1 (id_node, ip->iter_type, 0, NULL_TREE,			    0, 0);	    }	  else	    {	      /* in this case, it's a previously-declared 		 VAR_DECL node, checked in build_loop_iterator. */	      if (TREE_CODE (ip->user_var) == IDENTIFIER_NODE)		ip->user_var = lookup_name (ip->user_var);	      if (ip->user_var == NULL_TREE)		{		  error ("loop identifier undeclared");		  ip->error_flag = 1;		  return 1;		}	    }	  ip->iter_var = 	    decl_temp1 (get_unique_identifier ("iter_var"),			ip->iter_type, 0, NULL_TREE, 0, 0);	  break;	case DO_POWERSET:	  ip->iter_type = chill_unsigned_type (			    TYPE_DOMAIN (TREE_TYPE (ip->start_exp)));	  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, ip->iter_type, 0, NULL_TREE, 0, 0);	    }	  else	    {	      /* in this case, it's a previously-declared VAR_DECL node */	      ip->user_var = lookup_name (ip->user_var);	    }	  /* the user's powerset-expression, evaluated and saved in a temp */	  ip->powerset_temp = maybe_make_for_temp (ip->start_exp, "for_set",						 TREE_TYPE (ip->start_exp));	  mark_addressable (ip->powerset_temp);	  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;	      	      if (TREE_CODE (TREE_TYPE (array_type)) == BOOLEAN_TYPE)		{		  error ("Can't iterate through array of BOOL");		  ip->error_flag = 1;		  return ip->error_flag;		}	      	      /* 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, 

⌨️ 快捷键说明

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