}
}
+/**
+ * Expect the the current token is the expected token.
+ * If not, generate an error, eat the current statement,
+ * and goto the end_error label.
+ */
#define expect(expected) \
do { \
if(UNLIKELY(token.type != (expected))) { \
parse_error_expected(NULL, (expected), 0); \
eat_statement(); \
- return NULL; \
+ goto end_error; \
} \
next_token(); \
} while(0)
}
last = designator;
}
+end_error:
+ return NULL;
}
static initializer_t *initializer_from_string(array_type_t *type,
typeof_type->typeoft.typeof_type = type;
return typeof_type;
+end_error:
+ return NULL;
}
typedef enum {
expect(']');
return (construct_type_t*) array;
+end_error:
+ return NULL;
}
static construct_type_t *parse_function_declarator(declaration_t *declaration)
expect(')');
return (construct_type_t*) construct_function_type;
+end_error:
+ return NULL;
}
static construct_type_t *parse_inner_declarator(declaration_t *declaration,
}
return first;
+end_error:
+ return NULL;
}
static type_t *construct_declarator_type(construct_type_t *construct_list,
return expression;
}
+/**
+ * Parse a cast expression.
+ */
static expression_t *parse_cast(void)
{
source_position_t source_position = token.source_position;
cast->unary.value = value;
return cast;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parse a statement expression.
+ */
static expression_t *parse_statement_expression(void)
{
expression_t *expression = allocate_expression_zero(EXPR_STATEMENT);
expect(')');
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parse a braced expression.
+ */
static expression_t *parse_brace_expression(void)
{
eat('(');
expect(')');
return result;
+end_error:
+ return create_invalid_expression();
}
static expression_t *parse_function_keyword(void)
}
return result;
+end_error:
+ return NULL;
}
+/**
+ * Parse the __builtin_offsetof() expression.
+ */
static expression_t *parse_offsetof(void)
{
eat(T___builtin_offsetof);
DEL_ARR_F(path.path);
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a _builtin_va_start() expression.
+ */
static expression_t *parse_va_start(void)
{
eat(T___builtin_va_start);
}
}
errorf(expr->base.source_position, "second argument of 'va_start' must be last parameter of the current function");
-
+end_error:
return create_invalid_expression();
}
+/**
+ * Parses a _builtin_va_arg() expression.
+ */
static expression_t *parse_va_arg(void)
{
eat(T___builtin_va_arg);
expect(')');
return expression;
+end_error:
+ return create_invalid_expression();
}
static expression_t *parse_builtin_symbol(void)
return expression;
}
+/**
+ * Parses a __builtin_constant() expression.
+ */
static expression_t *parse_builtin_constant(void)
{
eat(T___builtin_constant_p);
expression->base.type = type_int;
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a __builtin_prefetch() expression.
+ */
static expression_t *parse_builtin_prefetch(void)
{
eat(T___builtin_prefetch);
expression->base.type = type_void;
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a __builtin_is_*() compare expression.
+ */
static expression_t *parse_compare_builtin(void)
{
expression_t *expression;
}
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a __builtin_expect() expression.
+ */
static expression_t *parse_builtin_expect(void)
{
eat(T___builtin_expect);
expression->base.type = expression->binary.left->base.type;
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a MS assume() expression.
+ */
static expression_t *parse_assume(void) {
eat(T_assume);
expression->base.type = type_void;
return expression;
+end_error:
+ return create_invalid_expression();
}
+/**
+ * Parses a primary expression.
+ */
static expression_t *parse_primary_expression(void)
{
switch (token.type) {
}
return tp_expression;
+end_error:
+ return create_invalid_expression();
}
static expression_t *parse_sizeof(unsigned precedence)
}
return result;
+end_error:
+ return create_invalid_expression();
}
static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right);
= create_implicit_cast(false_expression, result_type);
conditional->base.type = result_type;
return result;
+end_error:
+ return create_invalid_expression();
}
/**
return expression;
}
+/**
+ * Parse a __builtin_classify_type() expression.
+ */
static expression_t *parse_builtin_classify_type(const unsigned precedence)
{
eat(T___builtin_classify_type);
result->classify_type.type_expression = expression;
return result;
+end_error:
+ return create_invalid_expression();
}
static void semantic_incdec(unary_expression_t *expression)
{
switch (expr->kind) {
case EXPR_UNKNOWN: break;
- case EXPR_INVALID: break;
+ case EXPR_INVALID: return true; /* do NOT warn */
case EXPR_REFERENCE: return false;
case EXPR_CONST: return false;
case EXPR_CHARACTER_CONSTANT: return false;
case EXPR_BINARY_ISUNORDERED: return false;
}
- panic("unexpected statement");
+ panic("unexpected expression");
}
static void semantic_comma(binary_expression_t *expression)
}
return result;
+end_error:
+ return NULL;
}
/**
expect(')');
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**
statement->case_label.statement = parse_statement();
return statement;
+end_error:
+ return NULL;
}
/**
statement->case_label.statement = parse_statement();
return statement;
+end_error:
+ return NULL;
}
/**
}
return statement;
+end_error:
+ return NULL;
}
/**
}
return statement;
+end_error:
+ return NULL;
}
static statement_t *parse_loop_body(statement_t *const loop)
statement->whiles.body = parse_loop_body(statement);
return statement;
+end_error:
+ return NULL;
}
/**
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**
environment_pop_to(top);
return statement;
+end_error:
+ return NULL;
}
/**
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**
statement->returns.value = return_value;
return statement;
+end_error:
+ return NULL;
}
/**
expect(';');
return statement;
+end_error:
+ return NULL;
}
/**