FreeBSD/contrib/gcc/cp/typeck.c
/* Construct and perhaps optimize a tree representation
   for a unary operation.  CODE, a tree_code, specifies the operation
   and XARG is the operand.  */
Construct and perhaps optimize a tree representation
for a unary operation.  CODE, a tree_code, specifies the operation
and XARG is the operand.
Construct and perhaps optimize a tree representation for a unary operation . CODE a tree_code specifies the operation and XARG is the operand .
tree
build_x_unary_op (enum tree_code code, tree xarg)
{
  tree orig_expr = xarg;
  tree exp;
  int ptrmem = 0;
  if (processing_template_decl)
    {
      if (type_dependent_expression_p (xarg))
	return build_min_nt (code, xarg, NULL_TREE);
      xarg = build_non_dependent_expr (xarg);
    }
  exp = NULL_TREE;
  if (code == ADDR_EXPR
      && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
      && ((CLASS_TYPE_P (TREE_TYPE (xarg))
	   && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
	  || (TREE_CODE (xarg) == OFFSET_REF)))
    ;
  else
    exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
			NULL);
  if (!exp && code == ADDR_EXPR)
    {
      if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
	  && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
	{
	  if (TREE_CODE (xarg) != OFFSET_REF
	      || !TYPE_P (TREE_OPERAND (xarg, 0)))
	    {
	      error ("invalid use of %qE to form a pointer-to-member-function",
		     xarg);
	      if (TREE_CODE (xarg) != OFFSET_REF)
		inform ("  a qualified-id is required");
	      return error_mark_node;
	    }
	  else
	    {
	      error ("parentheses around %qE cannot be used to form a"
		     " pointer-to-member-function",
		     xarg);
	      PTRMEM_OK_P (xarg) = 1;
	    }
	}
      if (TREE_CODE (xarg) == OFFSET_REF)
	{
	  ptrmem = PTRMEM_OK_P (xarg);
	  if (!ptrmem && !flag_ms_extensions
	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
	    {
	      xarg = build2 (OFFSET_REF, TREE_TYPE (xarg),
			     TREE_OPERAND (xarg, 0),
			     ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
	      PTRMEM_OK_P (xarg) = ptrmem;
	    }
	}
      else if (TREE_CODE (xarg) == TARGET_EXPR)
	warning (0, "taking address of temporary");
      exp = build_unary_op (ADDR_EXPR, xarg, 0);
    }
  if (processing_template_decl && exp != error_mark_node)
    exp = build_min_non_dep (code, exp, orig_expr,
			     NULL_TREE);
  if (TREE_CODE (exp) == ADDR_EXPR)
    PTRMEM_OK_P (exp) = ptrmem;
  return exp;
}
tree build_x_unary_op ( enum tree_code code , tree xarg ) { tree orig_expr = xarg ; tree exp ; int ptrmem = 0 ; if ( processing_template_decl ) { if ( type_dependent_expression_p ( xarg ) ) return build_min_nt ( code , xarg , NULL_TREE ) ; xarg = build_non_dependent_expr ( xarg ) ; } exp = NULL_TREE ; if ( code == ADDR_EXPR && TREE_CODE ( xarg ) != TEMPLATE_ID_EXPR && ( ( CLASS_TYPE_P ( TREE_TYPE ( xarg ) ) && ! COMPLETE_TYPE_P ( complete_type ( TREE_TYPE ( xarg ) ) ) ) || ( TREE_CODE ( xarg ) == OFFSET_REF ) ) ) ; else exp = build_new_op ( code , LOOKUP_NORMAL , xarg , NULL_TREE , NULL_TREE , NULL ) ; if ( ! exp && code == ADDR_EXPR ) { if ( ! flag_ms_extensions && TREE_CODE ( TREE_TYPE ( xarg ) ) == METHOD_TYPE && ( TREE_CODE ( xarg ) != OFFSET_REF || ! PTRMEM_OK_P ( xarg ) ) ) { if ( TREE_CODE ( xarg ) != OFFSET_REF || ! TYPE_P ( TREE_OPERAND ( xarg , 0 ) ) ) { error ( " " , xarg ) ; if ( TREE_CODE ( xarg ) != OFFSET_REF ) inform ( " " ) ; return error_mark_node ; } else { error ( " " " " , xarg ) ; PTRMEM_OK_P ( xarg ) = 1 ; } } if ( TREE_CODE ( xarg ) == OFFSET_REF ) { ptrmem = PTRMEM_OK_P ( xarg ) ; if ( ! ptrmem && ! flag_ms_extensions && TREE_CODE ( TREE_TYPE ( TREE_OPERAND ( xarg , 1 ) ) ) == METHOD_TYPE ) { xarg = build2 ( OFFSET_REF , TREE_TYPE ( xarg ) , TREE_OPERAND ( xarg , 0 ) , ovl_cons ( TREE_OPERAND ( xarg , 1 ) , NULL_TREE ) ) ; PTRMEM_OK_P ( xarg ) = ptrmem ; } } else if ( TREE_CODE ( xarg ) == TARGET_EXPR ) warning ( 0 , " " ) ; exp = build_unary_op ( ADDR_EXPR , xarg , 0 ) ; } if ( processing_template_decl && exp != error_mark_node ) exp = build_min_non_dep ( code , exp , orig_expr , NULL_TREE ) ; if ( TREE_CODE ( exp ) == ADDR_EXPR ) PTRMEM_OK_P ( exp ) = ptrmem ; return exp ; }
Construct and perhaps optimize a tree representation
for a unary operation.
Construct and perhaps optimize a tree representation for a unary operation .
/* [expr.unary.op] says:

       The address of an object of incomplete type can be taken.

     (And is just the ordinary address operator, not an overloaded
     "operator &".)  However, if the type is a template
     specialization, we must complete the type at this point so that
     an overloaded "operator &" will be available if required.  */ /* Don't look for a function.  */ /*overloaded_p=*/ /*  A pointer to member-function can be formed only by saying
	  &X::mf.  */ /* A single non-static member, make sure we don't allow a
		 pointer-to-member.  */ /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/