LABELED_BLOCK_BODY (node) = NULL_TREE;
{ LABELED_BLOCK_BODY (node) = NULL_TREE; CAN_COMPLETE_NORMALLY (node) = 1; }
java_complete_lhs (node)     tree node;{  tree nn, cn, wfl_op1, wfl_op2, wfl_op3;  int flag;  /* CONVERT_EXPR always has its type set, even though it needs to be     worked out. */  if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)    return node;  /* The switch block implements cases processing container nodes     first.  Contained nodes are always written back. Leaves come     next and return a value. */  switch (TREE_CODE (node))    {    case BLOCK:      /* 1- Block section.	 Set the local values on decl names so we can identify them	 faster when they're referenced. At that stage, identifiers	 are legal so we don't check for declaration errors. */      for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))	{	  DECL_CONTEXT (cn) = current_function_decl;	  IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;	}      if (BLOCK_EXPR_BODY (node) == NULL_TREE)	  CAN_COMPLETE_NORMALLY (node) = 1;      else	{	  tree stmt = BLOCK_EXPR_BODY (node);	  tree *ptr;	  int error_seen = 0;	  if (TREE_CODE (stmt) == COMPOUND_EXPR)	    {	      /* Re-order from (((A; B); C); ...; Z) to 		 (A; (B; (C ; (...; Z)))).		 This makes it easier to scan the statements left-to-right		 without using recursion (which might overflow the stack		 if the block has many statements. */	      for (;;)		{		  tree left = TREE_OPERAND (stmt, 0);		  if (TREE_CODE (left) != COMPOUND_EXPR)		    break;		  TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);		  TREE_OPERAND (left, 1) = stmt;		  stmt = left;		}	      BLOCK_EXPR_BODY (node) = stmt;	    }	  /* Now do the actual complete, without deep recursion for             long blocks. */	  ptr = &BLOCK_EXPR_BODY (node);	  while (TREE_CODE (*ptr) == COMPOUND_EXPR		 && TREE_OPERAND (*ptr, 1) != empty_stmt_node)	    {	      tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));	      tree *next = &TREE_OPERAND (*ptr, 1);	      TREE_OPERAND (*ptr, 0) = cur;	      if (cur == empty_stmt_node)		{		  /* Optimization;  makes it easier to detect empty bodies.		     Most useful for <clinit> with all-constant initializer. */		  *ptr = *next;		  continue;		}	      if (TREE_CODE (cur) == ERROR_MARK)		error_seen++;	      else if (! CAN_COMPLETE_NORMALLY (cur))		{		  wfl_op2 = *next;		  for (;;)		    {		      if (TREE_CODE (wfl_op2) == BLOCK)			wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);		      else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)			wfl_op2 = TREE_OPERAND (wfl_op2, 0);		      else			break;		    }		  if (TREE_CODE (wfl_op2) != CASE_EXPR		      && TREE_CODE (wfl_op2) != DEFAULT_EXPR)		    unreachable_stmt_error (*ptr);		}	      ptr = next;	    }	  *ptr = java_complete_tree (*ptr);	  if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)	    return error_mark_node;	  CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);	}      /* Turn local bindings to null */      for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))	IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;      TREE_TYPE (node) = void_type_node;      break;      /* 2- They are expressions but ultimately deal with statements */    case THROW_EXPR:      wfl_op1 = TREE_OPERAND (node, 0);      COMPLETE_CHECK_OP_0 (node);      /* CAN_COMPLETE_NORMALLY (node) = 0; */      return patch_throw_statement (node, wfl_op1);    case SYNCHRONIZED_EXPR:      wfl_op1 = TREE_OPERAND (node, 0);      return patch_synchronized_statement (node, wfl_op1);    case TRY_EXPR:      return patch_try_statement (node);    case TRY_FINALLY_EXPR:      COMPLETE_CHECK_OP_0 (node);      COMPLETE_CHECK_OP_1 (node);      CAN_COMPLETE_NORMALLY (node)	= (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))	   && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));      TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));      return node;    case CLEANUP_POINT_EXPR:      COMPLETE_CHECK_OP_0 (node);      TREE_TYPE (node) = void_type_node;      CAN_COMPLETE_NORMALLY (node) = 	CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));      return node;    case WITH_CLEANUP_EXPR:      COMPLETE_CHECK_OP_0 (node);      COMPLETE_CHECK_OP_2 (node);      CAN_COMPLETE_NORMALLY (node) = 	CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));      TREE_TYPE (node) = void_type_node;      return node;    case LABELED_BLOCK_EXPR:      PUSH_LABELED_BLOCK (node);      if (LABELED_BLOCK_BODY (node))	COMPLETE_CHECK_OP_1 (node);      TREE_TYPE (node) = void_type_node;      POP_LABELED_BLOCK ();      if (LABELED_BLOCK_BODY (node) == empty_stmt_node)	LABELED_BLOCK_BODY (node) = NULL_TREE;      else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))	CAN_COMPLETE_NORMALLY (node) = 1;      return node;    case EXIT_BLOCK_EXPR:      /* We don't complete operand 1, because it's the return value of         the EXIT_BLOCK_EXPR which doesn't exist it Java */      return patch_bc_statement (node);    case CASE_EXPR:      cn = java_complete_tree (TREE_OPERAND (node, 0));      if (cn == error_mark_node)	return cn;      /* First, the case expression must be constant */      cn = fold (cn);      if (!TREE_CONSTANT (cn) && !flag_emit_xref)	{	  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);	  parse_error_context (node, "Constant expression required");	  return error_mark_node;	}      nn = ctxp->current_loop;      /* It must be assignable to the type of the switch expression. */      if (!try_builtin_assignconv (NULL_TREE, 				   TREE_TYPE (TREE_OPERAND (nn, 0)), cn))	{	  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);	  parse_error_context 	    (wfl_operator,	     "Incompatible type for case. Can't convert `%s' to `int'",	     lang_printable_name (TREE_TYPE (cn), 0));	  return error_mark_node;	}      cn = fold (convert (int_type_node, cn));      /* Multiple instance of a case label bearing the same	 value is checked during code generation. The case	 expression is allright so far. */      TREE_OPERAND (node, 0) = cn;      TREE_TYPE (node) = void_type_node;      CAN_COMPLETE_NORMALLY (node) = 1;      TREE_SIDE_EFFECTS (node) = 1;      break;    case DEFAULT_EXPR:      nn = ctxp->current_loop;      /* Only one default label is allowed per switch statement */      if (SWITCH_HAS_DEFAULT (nn))	{	  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);	  parse_error_context (wfl_operator, 			       "Duplicate case label: `default'");	  return error_mark_node;	}      else	SWITCH_HAS_DEFAULT (nn) = 1;      TREE_TYPE (node) = void_type_node;      TREE_SIDE_EFFECTS (node) = 1;      CAN_COMPLETE_NORMALLY (node) = 1;      break;    case SWITCH_EXPR:    case LOOP_EXPR:      PUSH_LOOP (node);      /* Check whether the loop was enclosed in a labeled         statement. If not, create one, insert the loop in it and         return the node */      nn = patch_loop_statement (node);      /* Anyways, walk the body of the loop */      if (TREE_CODE (node) == LOOP_EXPR)	TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));      /* Switch statement: walk the switch expression and the cases */      else	node = patch_switch_statement (node);      if (TREE_OPERAND (node, 0) == error_mark_node)	nn = error_mark_node;      else	{	  TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;	  /* If we returned something different, that's because we	     inserted a label. Pop the label too. */	  if (nn != node)	    {	      if (CAN_COMPLETE_NORMALLY (node))		CAN_COMPLETE_NORMALLY (nn) = 1;	      POP_LABELED_BLOCK ();	    }	}      POP_LOOP ();      return nn;    case EXIT_EXPR:      TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));      return patch_exit_expr (node);    case COND_EXPR:      /* Condition */      TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));      if (TREE_OPERAND (node, 0) == error_mark_node)	return error_mark_node;      /* then-else branches */      TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));      if (TREE_OPERAND (node, 1) == error_mark_node)	return error_mark_node;      TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));      if (TREE_OPERAND (node, 2) == error_mark_node)	return error_mark_node;      return patch_if_else_statement (node);      break;    case CONDITIONAL_EXPR:      /* Condition */      wfl_op1 = TREE_OPERAND (node, 0);      COMPLETE_CHECK_OP_0 (node);      wfl_op2 = TREE_OPERAND (node, 1);      COMPLETE_CHECK_OP_1 (node);      wfl_op3 = TREE_OPERAND (node, 2);      COMPLETE_CHECK_OP_2 (node);      return patch_conditional_expr (node, wfl_op1, wfl_op2);      /* 3- Expression section */    case COMPOUND_EXPR:      wfl_op2 = TREE_OPERAND (node, 1);      TREE_OPERAND (node, 0) = nn = 	java_complete_tree (TREE_OPERAND (node, 0));      if (wfl_op2 == empty_stmt_node)	CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);      else	{	  if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)	    {	      /* An unreachable condition in a do-while statement		 is *not* (technically) an unreachable statement. */	      nn = wfl_op2;	      if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)		nn = EXPR_WFL_NODE (nn);	      if (TREE_CODE (nn) != EXIT_EXPR)		{		  SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);		  parse_error_context (wfl_operator, "Unreachable statement");		}	    }	  TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));	  if (TREE_OPERAND (node, 1) == error_mark_node)	    return error_mark_node;	  CAN_COMPLETE_NORMALLY (node)	    = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));	}      TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));      break;    case RETURN_EXPR:      /* CAN_COMPLETE_NORMALLY (node) = 0; */      return patch_return (node);    case EXPR_WITH_FILE_LOCATION:      if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */	  || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)	{	  tree wfl = node;	  node = resolve_expression_name (node, NULL);	  if (node == error_mark_node)	    return node;	  /* Keep line number information somewhere were it doesn't	     disrupt the completion process. */	  if (flag_emit_xref)	    {	      EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);	      TREE_OPERAND (node, 1) = wfl;	    }	  CAN_COMPLETE_NORMALLY (node) = 1;	}      else	{	  tree body;	  int save_lineno = lineno;	  lineno = EXPR_WFL_LINENO (node);	  body = java_complete_tree (EXPR_WFL_NODE (node));	  lineno = save_lineno;	  EXPR_WFL_NODE (node) = body;	  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);	  CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);	  if (body == empty_stmt_node)	    {	      /* Optimization;  makes it easier to detect empty bodies. */	      return body;	    }	  if (body == error_mark_node)	    {	      /* Its important for the evaluation of assignment that		 this mark on the TREE_TYPE is propagated. */	      TREE_TYPE (node) = error_mark_node;	      return error_mark_node;	    }	  else	    TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));	  	}      break;    case NEW_ARRAY_EXPR:      /* Patch all the dimensions */      flag = 0;      for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))	{	  int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));	  tree dim = java_complete_tree (TREE_VALUE (cn));	  if (dim == error_mark_node)	    {	      flag = 1;	      continue;	    }	  else	    {	      TREE_VALUE (cn) = dim;	      /* Setup the location of the current dimension, for		 later error report. */	      TREE_PURPOSE (cn) = 		build_expr_wfl (NULL_TREE, input_filename, 0, 0);	      EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;	    }	}      /* They complete the array creation expression, if no errors         were found. */      CAN_COMPLETE_NORMALLY (node) = 1;      return (flag ? error_mark_node	      : force_evaluation_order (patch_newarray (node)));    case NEW_CLASS_EXPR:    case CALL_EXPR:      /* Complete function's argument(s) first */      if (complete_function_arguments (node))	return error_mark_node;      else	{	  tree decl, wfl = TREE_OPERAND (node, 0);	  int in_this = CALL_THIS_CONSTRUCTOR_P (node);	  node = patch_method_invocation (node, NULL_TREE, 					  NULL_TREE, 0, &decl);	  if (node == error_mark_node)	    return error_mark_node;	  check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);	  /* If we call this(...), register signature and positions */	  if (in_this)	    DECL_CONSTRUCTOR_CALLS (current_function_decl) = 	      tree_cons (wfl, decl, 			 DECL_CONSTRUCTOR_CALLS (current_function_decl));	  CAN_COMPLETE_NORMALLY (node) = 1;	  return force_evaluation_order (node);	}    case MODIFY_EXPR:      /* Save potential wfls */      wfl_op1 = TREE_OPERAND (node, 0);      TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);      if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)	  && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)	  && DECL_INITIAL (nn) != NULL_TREE)	{	  tree value = fold_constant_for_init (nn, nn);	  if (value != NULL_TREE)	    {	      tree type = TREE_TYPE (value);	      if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)		return empty_stmt_node;	    }	  DECL_INITIAL (nn) = NULL_TREE;	}      wfl_op2 = TREE_OPERAND (node, 1);      if (TREE_OPERAND (node, 0) == error_mark_node)	return error_mark_node;      if (COMPOUND_ASSIGN_P (wfl_op2))	{	  tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 	  /* Hand stablize the lhs on both places */	  TREE_OPERAND (node, 0) = lvalue;	  TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;	  /* Now complete the RHS. We write it back later on. */	  nn = java_complete_tree (TREE_OPERAND (node, 1));	  if ((cn = patch_string (nn)))	    nn = cn;	  /* The last part of the rewrite for E1 op= E2 is to have 	     E1 = (T)(E1 op E2), with T being the type of E1. */	  nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 					       TREE_TYPE (lvalue), nn));	}      /* If we're about to patch a NEW_ARRAY_INIT, we call a special	 function to complete this RHS */      else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)	nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),				   TREE_OPERAND (node, 1));      /* Otherwise we simply complete the RHS */      else	nn = java_complete_tree (TREE_OPERAND (node, 1));      if (nn == error_mark_node)	return error_mark_node;      /* Write back the RHS as we evaluated it. */      TREE_OPERAND (node, 1) = nn;      /* In case we're handling = with a String as a RHS, we need to	 produce a String out of the RHS (it might still be a	 STRING_CST or a StringBuffer at this stage */      if ((nn = patch_string (TREE_OPERAND (node, 1))))	TREE_OPERAND (node, 1) = nn;      node = patch_assignment (node, wfl_op1, wfl_op2);      CAN_COMPLETE_NORMALLY (node) = 1;      return node;    case MULT_EXPR:    case PLUS_EXPR:    case MINUS_EXPR:    case LSHIFT_EXPR:    case RSHIFT_EXPR:    case URSHIFT_EXPR:    case BIT_AND_EXPR:    case BIT_XOR_EXPR:    case BIT_IOR_EXPR:    case TRUNC_MOD_EXPR:    case RDIV_EXPR:    case TRUTH_ANDIF_EXPR:    case TRUTH_ORIF_EXPR:    case EQ_EXPR:     case NE_EXPR:    case GT_EXPR:    case GE_EXPR:    case LT_EXPR:    case LE_EXPR:      /* Operands 0 and 1 are WFL in certain cases only. patch_binop	 knows how to handle those cases. */      wfl_op1 = TREE_OPERAND (node, 0);      wfl_op2 = TREE_OPERAND (node, 1);      CAN_COMPLETE_NORMALLY (node) = 1;      /* Don't complete string nodes if dealing with the PLUS operand. */      if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))        {          nn = java_complete_tree (wfl_op1);          if (nn == error_mark_node)            return error_mark_node;          if ((cn = patch_string (nn)))            nn = cn;          TREE_OPERAND (node, 0) = nn;        }      if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))        {          nn = java_complete_tree (wfl_op2);          if (nn == error_mark_node)            return error_mark_node;          if ((cn = patch_string (nn)))            nn = cn;          TREE_OPERAND (node, 1) = nn;        }      return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));    case INSTANCEOF_EXPR:      wfl_op1 = TREE_OPERAND (node, 0);      COMPLETE_CHECK_OP_0 (node);      if (flag_emit_xref)	{	  TREE_TYPE (node) = boolean_type_node;	  return node;	}      return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));    case UNARY_PLUS_EXPR:    case NEGATE_EXPR:    case TRUTH_NOT_EXPR:    case BIT_NOT_EXPR:    case PREDECREMENT_EXPR:    case PREINCREMENT_EXPR:    case POSTDECREMENT_EXPR:    case POSTINCREMENT_EXPR:    case CONVERT_EXPR:      /* There are cases were wfl_op1 is a WFL. patch_unaryop knows	 how to handle those cases. */      wfl_op1 = TREE_OPERAND (node, 0);      CAN_COMPLETE_NORMALLY (node) = 1;      TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);      if (TREE_OPERAND (node, 0) == error_mark_node)	return error_mark_node;      node = patch_unaryop (node, wfl_op1);      CAN_COMPLETE_NORMALLY (node) = 1;      break;    case ARRAY_REF:      /* There are cases were wfl_op1 is a WFL. patch_array_ref knows	 how to handle those cases. */      wfl_op1 = TREE_OPERAND (node, 0);      TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);      if (TREE_OPERAND (node, 0) == error_mark_node)	return error_mark_node;      if (!flag_emit_class_files && !flag_emit_xref)	TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));      /* The same applies to wfl_op2 */      wfl_op2 = TREE_OPERAND (node, 1);      TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);      if (TREE_OPERAND (node, 1) == error_mark_node)	return error_mark_node;      if (!flag_emit_class_files && !flag_emit_xref)	TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));      return patch_array_ref (node);    case RECORD_TYPE:      return node;;    case COMPONENT_REF:      /* The first step in the re-write of qualified name handling.  FIXME.	 So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */      TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));      if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)	{	  tree name = TREE_OPERAND (node, 1);	  tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);	  if (field == NULL_TREE)	    {	      error ("missing static field `%s'", IDENTIFIER_POINTER (name));	      return error_mark_node;	    }	  if (! FIELD_STATIC (field))	    {	      error ("not a static field `%s'", IDENTIFIER_POINTER (name));	      return error_mark_node;	    }	  return field;	}      else	fatal ("unimplemented java_complete_tree for COMPONENT_REF");      break;    case THIS_EXPR:      /* Can't use THIS in a static environment */      if (!current_this)	{	  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);	  parse_error_context (wfl_operator, "Keyword `this' used outside "			       "allowed context");	  TREE_TYPE (node) = error_mark_node;	  return error_mark_node;	}      if (ctxp->explicit_constructor_p)	{	  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);	  parse_error_context 	    (wfl_operator, "Can't reference `this' or `super' before the "	     "superclass constructor has been called");	  TREE_TYPE (node) = error_mark_node;	  return error_mark_node;	}      return current_this;    default:      CAN_COMPLETE_NORMALLY (node) = 1;      /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'	 and it's time to turn it into the appropriate String object	 */      if ((node = patch_string (node)))	return node;      fatal ("No case for tree code `%s' - java_complete_tree\n",	     tree_code_name [TREE_CODE (node)]);    }  return node;}