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

📄 stmt.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
				i, argvec, constraints,				filename, line));	  MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;	}      /* If there are no outputs (but there are some clobbers)	 store the bare ASM_OPERANDS into the PARALLEL.  */      if (i == 0)	XVECEXP (body, 0, i++) = obody;      /* Store (clobber REG) for each clobbered register specified.  */      for (tail = clobbers; tail; tail = TREE_CHAIN (tail))	{	  char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));	  int j = decode_reg_name (regname);	  if (j < 0)	    {	      if (j == -3)	/* `cc', which is not a register */		continue;	      if (j == -4)	/* `memory', don't cache memory across asm */		{		  XVECEXP (body, 0, i++)		    = gen_rtx (CLOBBER, VOIDmode,			       gen_rtx (MEM, BLKmode,					gen_rtx (SCRATCH, VOIDmode, 0)));		  continue;		}	      /* Ignore unknown register, error already signalled.  */	      continue;	    }	  /* Use QImode since that's guaranteed to clobber just one reg.  */	  XVECEXP (body, 0, i++)	    = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, QImode, j));	}      insn = emit_insn (body);    }  free_temp_slots ();}/* Generate RTL to evaluate the expression EXP   and remember it in case this is the VALUE in a ({... VALUE; }) constr.  */voidexpand_expr_stmt (exp)     tree exp;{  if (output_bytecode)    {      int org_stack_depth = stack_depth;      bc_expand_expr (exp);      /* Restore stack depth */      if (stack_depth < org_stack_depth)	abort ();            bc_emit_instruction (drop);      last_expr_type = TREE_TYPE (exp);      return;    }  /* If -W, warn about statements with no side effects,     except for an explicit cast to void (e.g. for assert()), and     except inside a ({...}) where they may be useful.  */  if (expr_stmts_for_value == 0 && exp != error_mark_node)    {      if (! TREE_SIDE_EFFECTS (exp) && (extra_warnings || warn_unused)	  && !(TREE_CODE (exp) == CONVERT_EXPR	       && TREE_TYPE (exp) == void_type_node))	warning_with_file_and_line (emit_filename, emit_lineno,				    "statement with no effect");      else if (warn_unused)	warn_if_unused_value (exp);    }  /* If EXP is of function type and we are expanding statements for     value, convert it to pointer-to-function.  */  if (expr_stmts_for_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)    exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);  last_expr_type = TREE_TYPE (exp);  if (! flag_syntax_only)    last_expr_value = expand_expr (exp,				   (expr_stmts_for_value				    ? NULL_RTX : const0_rtx),				   VOIDmode, 0);  /* If all we do is reference a volatile value in memory,     copy it to a register to be sure it is actually touched.  */  if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM      && TREE_THIS_VOLATILE (exp))    {      if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)	;      else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)	copy_to_reg (last_expr_value);      else	{	  rtx lab = gen_label_rtx ();	  	  /* Compare the value with itself to reference it.  */	  emit_cmp_insn (last_expr_value, last_expr_value, EQ,			 expand_expr (TYPE_SIZE (last_expr_type),				      NULL_RTX, VOIDmode, 0),			 BLKmode, 0,			 TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT);	  emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (lab));	  emit_label (lab);	}    }  /* If this expression is part of a ({...}) and is in memory, we may have     to preserve temporaries.  */  preserve_temp_slots (last_expr_value);  /* Free any temporaries used to evaluate this expression.  Any temporary     used as a result of this expression will already have been preserved     above.  */  free_temp_slots ();  emit_queue ();}/* Warn if EXP contains any computations whose results are not used.   Return 1 if a warning is printed; 0 otherwise.  */intwarn_if_unused_value (exp)     tree exp;{  if (TREE_USED (exp))    return 0;  switch (TREE_CODE (exp))    {    case PREINCREMENT_EXPR:    case POSTINCREMENT_EXPR:    case PREDECREMENT_EXPR:    case POSTDECREMENT_EXPR:    case MODIFY_EXPR:    case INIT_EXPR:    case TARGET_EXPR:    case CALL_EXPR:    case METHOD_CALL_EXPR:    case RTL_EXPR:    case WITH_CLEANUP_EXPR:    case EXIT_EXPR:      /* We don't warn about COND_EXPR because it may be a useful	 construct if either arm contains a side effect.  */    case COND_EXPR:      return 0;    case BIND_EXPR:      /* For a binding, warn if no side effect within it.  */      return warn_if_unused_value (TREE_OPERAND (exp, 1));    case SAVE_EXPR:      return warn_if_unused_value (TREE_OPERAND (exp, 1));    case TRUTH_ORIF_EXPR:    case TRUTH_ANDIF_EXPR:      /* In && or ||, warn if 2nd operand has no side effect.  */      return warn_if_unused_value (TREE_OPERAND (exp, 1));    case COMPOUND_EXPR:      if (TREE_NO_UNUSED_WARNING (exp))	return 0;      if (warn_if_unused_value (TREE_OPERAND (exp, 0)))	return 1;      /* Let people do `(foo (), 0)' without a warning.  */      if (TREE_CONSTANT (TREE_OPERAND (exp, 1)))	return 0;      return warn_if_unused_value (TREE_OPERAND (exp, 1));    case NOP_EXPR:    case CONVERT_EXPR:    case NON_LVALUE_EXPR:      /* Don't warn about values cast to void.  */      if (TREE_TYPE (exp) == void_type_node)	return 0;      /* Don't warn about conversions not explicit in the user's program.  */      if (TREE_NO_UNUSED_WARNING (exp))	return 0;      /* Assignment to a cast usually results in a cast of a modify.	 Don't complain about that.  There can be an arbitrary number of	 casts before the modify, so we must loop until we find the first	 non-cast expression and then test to see if that is a modify.  */      {	tree tem = TREE_OPERAND (exp, 0);	while (TREE_CODE (tem) == CONVERT_EXPR || TREE_CODE (tem) == NOP_EXPR)	  tem = TREE_OPERAND (tem, 0);	if (TREE_CODE (tem) == MODIFY_EXPR || TREE_CODE (tem) == INIT_EXPR	    || TREE_CODE (tem) == CALL_EXPR)	  return 0;      }      goto warn;    case INDIRECT_REF:      /* Don't warn about automatic dereferencing of references, since	 the user cannot control it.  */      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)	return warn_if_unused_value (TREE_OPERAND (exp, 0));      /* ... fall through ... */          default:      /* Referencing a volatile value is a side effect, so don't warn.  */      if ((TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'	   || TREE_CODE_CLASS (TREE_CODE (exp)) == 'r')	  && TREE_THIS_VOLATILE (exp))	return 0;    warn:      warning_with_file_and_line (emit_filename, emit_lineno,				  "value computed is not used");      return 1;    }}/* Clear out the memory of the last expression evaluated.  */voidclear_last_expr (){  last_expr_type = 0;}/* Begin a statement which will return a value.   Return the RTL_EXPR for this statement expr.   The caller must save that value and pass it to expand_end_stmt_expr.  */treeexpand_start_stmt_expr (){  int momentary;  tree t;  /* When generating bytecode just note down the stack depth */  if (output_bytecode)    return (build_int_2 (stack_depth, 0));  /* Make the RTL_EXPR node temporary, not momentary,     so that rtl_expr_chain doesn't become garbage.  */  momentary = suspend_momentary ();  t = make_node (RTL_EXPR);  resume_momentary (momentary);  do_pending_stack_adjust ();  start_sequence_for_rtl_expr (t);  NO_DEFER_POP;  expr_stmts_for_value++;  return t;}/* Restore the previous state at the end of a statement that returns a value.   Returns a tree node representing the statement's value and the   insns to compute the value.   The nodes of that expression have been freed by now, so we cannot use them.   But we don't want to do that anyway; the expression has already been   evaluated and now we just want to use the value.  So generate a RTL_EXPR   with the proper type and RTL value.   If the last substatement was not an expression,   return something with type `void'.  */treeexpand_end_stmt_expr (t)     tree t;{  if (output_bytecode)    {      int i;      tree t;                  /* At this point, all expressions have been evaluated in order.	 However, all expression values have been popped when evaluated,	 which means we have to recover the last expression value.  This is	 the last value removed by means of a `drop' instruction.  Instead	 of adding code to inhibit dropping the last expression value, it	 is here recovered by undoing the `drop'.  Since `drop' is	 equivalent to `adjustackSI [1]', it can be undone with `adjstackSI	 [-1]'. */            bc_adjust_stack (-1);            if (!last_expr_type)	last_expr_type = void_type_node;            t = make_node (RTL_EXPR);      TREE_TYPE (t) = last_expr_type;      RTL_EXPR_RTL (t) = NULL;      RTL_EXPR_SEQUENCE (t) = NULL;            /* Don't consider deleting this expr or containing exprs at tree level.  */      TREE_THIS_VOLATILE (t) = 1;            last_expr_type = 0;      return t;    }  OK_DEFER_POP;  if (last_expr_type == 0)    {      last_expr_type = void_type_node;      last_expr_value = const0_rtx;    }  else if (last_expr_value == 0)    /* There are some cases where this can happen, such as when the       statement is void type.  */    last_expr_value = const0_rtx;  else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))    /* Remove any possible QUEUED.  */    last_expr_value = protect_from_queue (last_expr_value, 0);  emit_queue ();  TREE_TYPE (t) = last_expr_type;  RTL_EXPR_RTL (t) = last_expr_value;  RTL_EXPR_SEQUENCE (t) = get_insns ();  rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);  end_sequence ();  /* Don't consider deleting this expr or containing exprs at tree level.  */  TREE_SIDE_EFFECTS (t) = 1;  /* Propagate volatility of the actual RTL expr.  */  TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);  last_expr_type = 0;  expr_stmts_for_value--;  return t;}/* Generate RTL for the start of an if-then.  COND is the expression   whose truth should be tested.   If EXITFLAG is nonzero, this conditional is visible to   `exit_something'.  */voidexpand_start_cond (cond, exitflag)     tree cond;     int exitflag;{  struct nesting *thiscond = ALLOC_NESTING ();  /* Make an entry on cond_stack for the cond we are entering.  */  thiscond->next = cond_stack;  thiscond->all = nesting_stack;  thiscond->depth = ++nesting_depth;  thiscond->data.cond.next_label = gen_label_rtx ();  /* Before we encounter an `else', we don't need a separate exit label     unless there are supposed to be exit statements     to exit this conditional.  */  thiscond->exit_label = exitflag ? gen_label_rtx () : 0;  thiscond->data.cond.endif_label = thiscond->exit_label;  cond_stack = thiscond;  nesting_stack = thiscond;  if (output_bytecode)    bc_expand_start_cond (cond, exitflag);  else    do_jump (cond, thiscond->data.cond.next_label, NULL_RTX);}/* Generate RTL between then-clause and the elseif-clause   of an if-then-elseif-....  */voidexpand_start_elseif (cond)     tree cond;{  if (cond_stack->data.cond.endif_label == 0)    cond_stack->data.cond.endif_label = gen_label_rtx ();  emit_jump (cond_stack->data.cond.endif_label);  emit_label (cond_stack->data.cond.next_label);  cond_stack->data.cond.next_label = gen_label_rtx ();  do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);}/* Generate RTL between the then-clause and the else-clause   of an if-then-else.  */voidexpand_start_else (){  if (cond_stack->data.cond.endif_label == 0)    cond_stack->data.cond.endif_label = gen_label_rtx ();  if (output_bytecode)    {      bc_

⌨️ 快捷键说明

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