FreeBSD/contrib/gcc/cp/parser.c
/* Parse a cast-expression.

   cast-expression:
     unary-expression
     ( type-id ) cast-expression

   ADDRESS_P is true iff the unary-expression is appearing as the
   operand of the `&' operator.   CAST_P is true if this expression is
   the target of a cast.

   Returns a representation of the expression.  */
Parse a cast-expression.

ADDRESS_P is true iff the unary-expression is appearing as the
operand of the `&' operator.   CAST_P is true if this expression is
the target of a cast.

Returns a representation of the expression.
Parse a cast - expression . ADDRESS_P is true iff the unary - expression is appearing as the operand of the ` & ' operator . CAST_P is true if this expression is the target of a cast . Returns a representation of the expression .
static tree
cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
{
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      tree type = NULL_TREE;
      tree expr = NULL_TREE;
      bool compound_literal_p;
      const char *saved_message;
      cp_parser_parse_tentatively (parser);
      saved_message = parser->type_definition_forbidden_message;
      parser->type_definition_forbidden_message
	= "types may not be defined in casts";
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_save_tokens (parser->lexer);
      compound_literal_p
	= (cp_parser_skip_to_closing_parenthesis (parser, false, false,
						  true)
	   && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
      cp_lexer_rollback_tokens (parser->lexer);
      if (compound_literal_p)
	cp_parser_simulate_error (parser);
      else
	{
	  bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	  parser->in_type_id_in_expr_p = true;
	  type = cp_parser_type_id (parser);
	  cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
	  parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	}
      parser->type_definition_forbidden_message = saved_message;
      if (!cp_parser_error_occurred (parser))
	expr = cp_parser_cast_expression (parser,
					  false,
					  true);
      if (cp_parser_parse_definitely (parser))
	{
	  if (warn_old_style_cast
	      && !in_system_header
	      && !VOID_TYPE_P (type)
	      && current_lang_name != lang_name_c)
	    warning (OPT_Wold_style_cast, "use of old-style cast");
	  if (!cast_valid_in_integral_constant_expression_p (type)
	      && (cp_parser_non_integral_constant_expression
		  (parser,
		   "a cast to a type other than an integral or "
		   "enumeration type")))
	    return error_mark_node;
	  expr = build_c_cast (type, expr);
	  return expr;
	}
    }
  return cp_parser_unary_expression (parser, address_p, cast_p);
}
static tree cp_parser_cast_expression ( cp_parser * parser , bool address_p , bool cast_p ) { if ( cp_lexer_next_token_is ( parser -> lexer , CPP_OPEN_PAREN ) ) { tree type = NULL_TREE ; tree expr = NULL_TREE ; bool compound_literal_p ; const char * saved_message ; cp_parser_parse_tentatively ( parser ) ; saved_message = parser -> type_definition_forbidden_message ; parser -> type_definition_forbidden_message = " " ; cp_lexer_consume_token ( parser -> lexer ) ; cp_lexer_save_tokens ( parser -> lexer ) ; compound_literal_p = ( cp_parser_skip_to_closing_parenthesis ( parser , false , false , true ) && cp_lexer_next_token_is ( parser -> lexer , CPP_OPEN_BRACE ) ) ; cp_lexer_rollback_tokens ( parser -> lexer ) ; if ( compound_literal_p ) cp_parser_simulate_error ( parser ) ; else { bool saved_in_type_id_in_expr_p = parser -> in_type_id_in_expr_p ; parser -> in_type_id_in_expr_p = true ; type = cp_parser_type_id ( parser ) ; cp_parser_require ( parser , CPP_CLOSE_PAREN , " " ) ; parser -> in_type_id_in_expr_p = saved_in_type_id_in_expr_p ; } parser -> type_definition_forbidden_message = saved_message ; if ( ! cp_parser_error_occurred ( parser ) ) expr = cp_parser_cast_expression ( parser , false , true ) ; if ( cp_parser_parse_definitely ( parser ) ) { if ( warn_old_style_cast && ! in_system_header && ! VOID_TYPE_P ( type ) && current_lang_name != lang_name_c ) warning ( OPT_Wold_style_cast , " " ) ; if ( ! cast_valid_in_integral_constant_expression_p ( type ) && ( cp_parser_non_integral_constant_expression ( parser , " " " " ) ) ) return error_mark_node ; expr = build_c_cast ( type , expr ) ; return expr ; } } return cp_parser_unary_expression ( parser , address_p , cast_p ) ; }
Parse a cast-expression.
Parse a cast - expression .
/* If it's a `(', then we might be looking at a cast.  */ /* There's no way to know yet whether or not this is a cast.
	 For example, `(int (3))' is a unary-expression, while `(int)
	 3' is a cast.  So, we resort to parsing tentatively.  */ /* Types may not be defined in a cast.  */ /* Consume the `('.  */ /* A very tricky bit is that `(struct S) { 3 }' is a
	 compound-literal (which we permit in C++ as an extension).
	 But, that construct is not a cast-expression -- it is a
	 postfix-expression.  (The reason is that `(struct S) { 3 }.i'
	 is legal; if the compound-literal were a cast-expression,
	 you'd need an extra set of parentheses.)  But, if we parse
	 the type-id, and it happens to be a class-specifier, then we
	 will commit to the parse at that point, because we cannot
	 undo the action that is done when creating a new class.  So,
	 then we cannot back up and do a postfix-expression.

	 Therefore, we scan ahead to the closing `)', and check to see
	 if the token after the `)' is a `{'.  If so, we are not
	 looking at a cast-expression.

	 Save tokens so that we can put them back.  */ /* Skip tokens until the next token is a closing parenthesis.
	 If we find the closing `)', and the next token is a `{', then
	 we are looking at a compound-literal.  */ /*consume_paren=*/ /* Roll back the tokens we skipped.  */ /* If we were looking at a compound-literal, simulate an error
	 so that the call to cp_parser_parse_definitely below will
	 fail.  */ /* Look for the type-id.  */ /* Look for the closing `)'.  */ /* Restore the saved message.  */ /* If ok so far, parse the dependent expression. We cannot be
	 sure it is a cast. Consider `(T ())'.  It is a parenthesized
	 ctor of T, but looks like a cast to function returning T
	 without a dependent expression.  */ /*address_p=*/ /*cast_p=*/ /* Warn about old-style casts, if so requested.  */ /* Only type conversions to integral or enumeration types
	     can be used in constant-expressions.  */ /* Perform the cast.  */ /* If we get here, then it's not a cast, so it must be a
     unary-expression.  */