FreeBSD/contrib/gcc/c-parser.c
/* Parse a typeof specifier (a GNU extension).

   typeof-specifier:
     typeof ( expression )
     typeof ( type-name )
*/
Parse a typeof specifier (a GNU extension).
Parse a typeof specifier ( a GNU extension ) .
static struct c_typespec
c_parser_typeof_specifier (c_parser *parser)
{
  struct c_typespec ret;
  ret.kind = ctsk_typeof;
  ret.spec = error_mark_node;
  gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
  c_parser_consume_token (parser);
  skip_evaluation++;
  in_typeof++;
  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
    {
      skip_evaluation--;
      in_typeof--;
      return ret;
    }
  if (c_parser_next_token_starts_typename (parser))
    {
      struct c_type_name *type = c_parser_type_name (parser);
      skip_evaluation--;
      in_typeof--;
      if (type != NULL)
	{
	  ret.spec = groktypename (type);
	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
	}
    }
  else
    {
      bool was_vm;
      struct c_expr expr = c_parser_expression (parser);
      skip_evaluation--;
      in_typeof--;
      if (TREE_CODE (expr.value) == COMPONENT_REF
	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
	error ("%<typeof%> applied to a bit-field");
      ret.spec = TREE_TYPE (expr.value);
      was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
      if (!skip_evaluation && was_vm)
	{
	  tree e = expr.value;
	  if (DECL_P (e) || CONSTANT_CLASS_P (e))
	    e = build1 (NOP_EXPR, void_type_node, e);
	  if (EXPR_P (e))
	    SET_EXPR_LOCATION (e, input_location);
	  add_stmt (e);
	}
      pop_maybe_used (was_vm);
    }
  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
  return ret;
}
static struct c_typespec c_parser_typeof_specifier ( c_parser * parser ) { struct c_typespec ret ; ret . kind = ctsk_typeof ; ret . spec = error_mark_node ; gcc_assert ( c_parser_next_token_is_keyword ( parser , RID_TYPEOF ) ) ; c_parser_consume_token ( parser ) ; skip_evaluation ++ ; in_typeof ++ ; if ( ! c_parser_require ( parser , CPP_OPEN_PAREN , " " ) ) { skip_evaluation -- ; in_typeof -- ; return ret ; } if ( c_parser_next_token_starts_typename ( parser ) ) { struct c_type_name * type = c_parser_type_name ( parser ) ; skip_evaluation -- ; in_typeof -- ; if ( type != NULL ) { ret . spec = groktypename ( type ) ; pop_maybe_used ( variably_modified_type_p ( ret . spec , NULL_TREE ) ) ; } } else { bool was_vm ; struct c_expr expr = c_parser_expression ( parser ) ; skip_evaluation -- ; in_typeof -- ; if ( TREE_CODE ( expr . value ) == COMPONENT_REF && DECL_C_BIT_FIELD ( TREE_OPERAND ( expr . value , 1 ) ) ) error ( " " ) ; ret . spec = TREE_TYPE ( expr . value ) ; was_vm = variably_modified_type_p ( ret . spec , NULL_TREE ) ; if ( ! skip_evaluation && was_vm ) { tree e = expr . value ; if ( DECL_P ( e ) || CONSTANT_CLASS_P ( e ) ) e = build1 ( NOP_EXPR , void_type_node , e ) ; if ( EXPR_P ( e ) ) SET_EXPR_LOCATION ( e , input_location ) ; add_stmt ( e ) ; } pop_maybe_used ( was_vm ) ; } c_parser_skip_until_found ( parser , CPP_CLOSE_PAREN , " " ) ; return ret ; }
Parse a typeof specifier (a GNU extension).
Parse a typeof specifier ( a GNU extension ) .
/* This should be returned with the type so that when the type
	 is evaluated, this can be evaluated.  For now, we avoid
	 evaluation when the context might.  */ /* If the expression is not of a type to which we cannot assign a line
	     number, wrap the thing in a no-op NOP_EXPR.  */