FreeBSD/contrib/gcc/cp/typeck.c
/* Apply unary lvalue-demanding operator CODE to the expression ARG
   for certain kinds of expressions which are not really lvalues
   but which we can accept as lvalues.

   If ARG is not a kind of expression we can handle, return
   NULL_TREE.  */
Apply unary lvalue-demanding operator CODE to the expression ARG
for certain kinds of expressions which are not really lvalues
but which we can accept as lvalues.

If ARG is not a kind of expression we can handle, return
NULL_TREE.
Apply unary lvalue - demanding operator CODE to the expression ARG for certain kinds of expressions which are not really lvalues but which we can accept as lvalues . If ARG is not a kind of expression we can handle return NULL_TREE .
tree
unary_complex_lvalue (enum tree_code code, tree arg)
{
  if (processing_template_decl)
    return NULL_TREE;
  if (TREE_CODE (arg) == COMPOUND_EXPR)
    {
      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
      return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
		     TREE_OPERAND (arg, 0), real_result);
    }
  if (TREE_CODE (arg) == COND_EXPR
      || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR)
    return rationalize_conditional_expr (code, arg);
  if (TREE_CODE (arg) == MODIFY_EXPR
      || TREE_CODE (arg) == PREINCREMENT_EXPR
      || TREE_CODE (arg) == PREDECREMENT_EXPR)
    {
      tree lvalue = TREE_OPERAND (arg, 0);
      if (TREE_SIDE_EFFECTS (lvalue))
	{
	  lvalue = stabilize_reference (lvalue);
	  arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
			lvalue, TREE_OPERAND (arg, 1));
	}
      return unary_complex_lvalue
	(code, build2 (COMPOUND_EXPR, TREE_TYPE (lvalue), arg, lvalue));
    }
  if (code != ADDR_EXPR)
    return NULL_TREE;
  if (TREE_CODE (arg) == MODIFY_EXPR
      || TREE_CODE (arg) == INIT_EXPR)
    {
      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
      arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
		    arg, real_result);
      TREE_NO_WARNING (arg) = 1;
      return arg;
    }
  if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
      || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
      || TREE_CODE (arg) == OFFSET_REF)
    return NULL_TREE;
  {
    tree targ = arg;
    if (TREE_CODE (targ) == SAVE_EXPR)
      targ = TREE_OPERAND (targ, 0);
    if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (TREE_TYPE (targ)))
      {
	if (TREE_CODE (arg) == SAVE_EXPR)
	  targ = arg;
	else
	  targ = build_cplus_new (TREE_TYPE (arg), arg);
	return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ);
      }
    if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF)
      return build3 (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)),
		     TREE_OPERAND (targ, 0), current_function_decl, NULL);
  }
  return NULL_TREE;
}
tree unary_complex_lvalue ( enum tree_code code , tree arg ) { if ( processing_template_decl ) return NULL_TREE ; if ( TREE_CODE ( arg ) == COMPOUND_EXPR ) { tree real_result = build_unary_op ( code , TREE_OPERAND ( arg , 1 ) , 0 ) ; return build2 ( COMPOUND_EXPR , TREE_TYPE ( real_result ) , TREE_OPERAND ( arg , 0 ) , real_result ) ; } if ( TREE_CODE ( arg ) == COND_EXPR || TREE_CODE ( arg ) == MIN_EXPR || TREE_CODE ( arg ) == MAX_EXPR ) return rationalize_conditional_expr ( code , arg ) ; if ( TREE_CODE ( arg ) == MODIFY_EXPR || TREE_CODE ( arg ) == PREINCREMENT_EXPR || TREE_CODE ( arg ) == PREDECREMENT_EXPR ) { tree lvalue = TREE_OPERAND ( arg , 0 ) ; if ( TREE_SIDE_EFFECTS ( lvalue ) ) { lvalue = stabilize_reference ( lvalue ) ; arg = build2 ( TREE_CODE ( arg ) , TREE_TYPE ( arg ) , lvalue , TREE_OPERAND ( arg , 1 ) ) ; } return unary_complex_lvalue ( code , build2 ( COMPOUND_EXPR , TREE_TYPE ( lvalue ) , arg , lvalue ) ) ; } if ( code != ADDR_EXPR ) return NULL_TREE ; if ( TREE_CODE ( arg ) == MODIFY_EXPR || TREE_CODE ( arg ) == INIT_EXPR ) { tree real_result = build_unary_op ( code , TREE_OPERAND ( arg , 0 ) , 0 ) ; arg = build2 ( COMPOUND_EXPR , TREE_TYPE ( real_result ) , arg , real_result ) ; TREE_NO_WARNING ( arg ) = 1 ; return arg ; } if ( TREE_CODE ( TREE_TYPE ( arg ) ) == FUNCTION_TYPE || TREE_CODE ( TREE_TYPE ( arg ) ) == METHOD_TYPE || TREE_CODE ( arg ) == OFFSET_REF ) return NULL_TREE ; { tree targ = arg ; if ( TREE_CODE ( targ ) == SAVE_EXPR ) targ = TREE_OPERAND ( targ , 0 ) ; if ( TREE_CODE ( targ ) == CALL_EXPR && IS_AGGR_TYPE ( TREE_TYPE ( targ ) ) ) { if ( TREE_CODE ( arg ) == SAVE_EXPR ) targ = arg ; else targ = build_cplus_new ( TREE_TYPE ( arg ) , arg ) ; return build1 ( ADDR_EXPR , build_pointer_type ( TREE_TYPE ( arg ) ) , targ ) ; } if ( TREE_CODE ( arg ) == SAVE_EXPR && TREE_CODE ( targ ) == INDIRECT_REF ) return build3 ( SAVE_EXPR , build_pointer_type ( TREE_TYPE ( arg ) ) , TREE_OPERAND ( targ , 0 ) , current_function_decl , NULL ) ; } return NULL_TREE ; }
Apply unary lvalue-demanding operator CODE to the expression ARG
for certain kinds of expressions which are not really lvalues
but which we can accept as lvalues.
Apply unary lvalue - demanding operator CODE to the expression ARG for certain kinds of expressions which are not really lvalues but which we can accept as lvalues .
/* Inside a template, making these kinds of adjustments is
     pointless; we are only concerned with the type of the
     expression.  */ /* Handle (a, b) used as an "lvalue".  */ /* Handle (a ? b : c) used as an "lvalue".  */ /* Handle (a = b), (++a), and (--a) used as an "lvalue".  */ /* Handle (a = b) used as an "lvalue" for `&'.  */ /* We permit compiler to make function calls returning
     objects of aggregate type look like lvalues.  */ /* Don't let anything else be handled specially.  */