return (dbg_info*) pos;
}
-static ir_node *const_to_firm(const const_t *cnst)
+static ir_node *const_to_firm(const const_expression_t *cnst)
{
dbg_info *dbgi = get_dbg_info(&cnst->expression.source_position);
ir_mode *mode = get_ir_mode(cnst->expression.datatype);
return create_symconst(dbgi, entity);
}
-static ir_node *string_literal_to_firm(const string_literal_t* literal)
+static ir_node *string_literal_to_firm(
+ const string_literal_expression_t* literal)
{
return string_to_firm(&literal->expression.source_position, "Lstr",
literal->value);
}
ir_node *callee = expression_to_firm(function);
- function_type_t *function_type;
- assert(function->datatype->type == TYPE_POINTER);
- pointer_type_t *const ptr_type = &function->datatype->pointer;
+ type_t *type = function->base.datatype;
+ assert(type->type == TYPE_POINTER);
+ pointer_type_t *const ptr_type = &type->pointer;
assert(ptr_type->points_to->type == TYPE_FUNCTION);
- function_type = &ptr_type->points_to->function;
+ function_type_t *function_type = &ptr_type->points_to->function;
int n_parameters = 0;
call_argument_t *argument = call->arguments;
in[n] = arg_node;
if(new_method_type != NULL) {
- ir_type *irtype = get_ir_type(expression->datatype);
+ ir_type *irtype = get_ir_type(expression->base.datatype);
set_method_param_type(new_method_type, n, irtype);
}
}
}
- dbg_info *dbgi = get_dbg_info(&expression->source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
ir_node *addr = expression_to_addr(expression);
- assert(get_irn_mode(value) == get_ir_mode(expression->datatype));
+ assert(get_irn_mode(value) == get_ir_mode(expression->base.datatype));
ir_node *memory = get_store();
ir_node *store = new_d_Store(dbgi, memory, addr, value);
ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M);
dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
ir_node *left = expression_to_firm(expression->left);
ir_node *right = expression_to_firm(expression->right);
- type_t *type = expression->right->datatype;
+ type_t *type = expression->right->base.datatype;
/* be careful with the modes, because in arithmetic assign nodes only
* the right operand has the mode of the arithmetic already */
ir_mode *mode = get_ir_mode(type);
expression_t *expr_left = expression->left;
expression_t *expr_right = expression->right;
- type_t *type_left = skip_typeref(expr_left->datatype);
- type_t *type_right = skip_typeref(expr_right->datatype);
+ type_t *type_left = skip_typeref(expr_left->base.datatype);
+ type_t *type_right = skip_typeref(expr_right->base.datatype);
if(is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
ir_mode *const mode = get_ir_mode(type);
ir_node *const left = expression_to_firm(expr_left);
ir_node *const right = expression_to_firm(expr_right);
type_t *const type = expression->expression.datatype;
- type_t *const type_left = skip_typeref(expr_left->datatype);
- type_t *const type_right = skip_typeref(expr_right->datatype);
+ type_t *const type_left = skip_typeref(expr_left->base.datatype);
+ type_t *const type_right = skip_typeref(expr_right->base.datatype);
if (is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
ir_mode *const mode = get_ir_mode(type);
case BINEXPR_SHIFTRIGHT_ASSIGN:
case BINEXPR_SHIFTRIGHT: {
expression_t *expr_left = expression->left;
- type_t *type_left = skip_typeref(expr_left->datatype);
+ type_t *type_left = skip_typeref(expr_left->base.datatype);
if(is_type_signed(type_left)) {
res = new_d_Shrs(dbgi, left, right, mode);
ir_node *pin = new_Pin(new_NoMem());
/* be careful with the modes, because in arithmetic assign nodes only
* the right operand has the mode of the arithmetic already */
- type_t *type = expression->right->datatype;
+ type_t *type = expression->right->base.datatype;
ir_mode *mode = get_ir_mode(type);
left = create_conv(dbgi, left, mode);
ir_node *op;
ir_node *offset = expression_to_firm(expression->index);
offset = create_conv(dbgi, offset, mode_Iu);
- type_t *ref_type = skip_typeref(expression->array_ref->datatype);
+ type_t *ref_type = skip_typeref(expression->array_ref->base.datatype);
assert(is_type_pointer(ref_type));
pointer_type_t *pointer_type = (pointer_type_t*) ref_type;
{
type_t *type = expression->type;
if(type == NULL) {
- type = expression->size_expression->datatype;
+ type = expression->size_expression->base.datatype;
assert(type != NULL);
}
static ir_node *classify_type_to_firm(const classify_type_expression_t *const expr)
{
- const type_t *const type = expr->type_expression->datatype;
+ const type_t *const type = expr->type_expression->base.datatype;
gcc_type_class tc;
switch (type->type)
return new_d_Const(dbgi, mode, tv);
}
-static ir_node *function_name_to_firm(const string_literal_t *const expr)
+static ir_node *function_name_to_firm(
+ const string_literal_expression_t *const expr)
{
if (current_function_name == NULL) {
const source_position_t *const src_pos =
{
switch(expression->type) {
case EXPR_CONST:
- return const_to_firm((const const_t*) expression);
+ return const_to_firm(&expression->conste);
case EXPR_STRING_LITERAL:
- return string_literal_to_firm((const string_literal_t*) expression);
+ return string_literal_to_firm(&expression->string_literal);
case EXPR_REFERENCE:
- return reference_expression_to_firm(
- (const reference_expression_t*) expression);
+ return reference_expression_to_firm(&expression->reference);
case EXPR_CALL:
- return call_expression_to_firm((const call_expression_t*) expression);
+ return call_expression_to_firm(&expression->call);
case EXPR_UNARY:
- return unary_expression_to_firm((const unary_expression_t*) expression);
+ return unary_expression_to_firm(&expression->unary);
case EXPR_BINARY:
- return binary_expression_to_firm(
- (const binary_expression_t*) expression);
+ return binary_expression_to_firm(&expression->binary);
case EXPR_ARRAY_ACCESS:
- return array_access_to_firm(
- (const array_access_expression_t*) expression);
+ return array_access_to_firm(&expression->array_access);
case EXPR_SIZEOF:
- return sizeof_to_firm((const sizeof_expression_t*) expression);
+ return sizeof_to_firm(&expression->sizeofe);
case EXPR_CONDITIONAL:
- return conditional_to_firm((const conditional_expression_t*)expression);
+ return conditional_to_firm(&expression->conditional);
case EXPR_SELECT:
- return select_to_firm((const select_expression_t*) expression);
+ return select_to_firm(&expression->select);
case EXPR_CLASSIFY_TYPE:
- return classify_type_to_firm((const classify_type_expression_t*)expression);
+ return classify_type_to_firm(&expression->classify_type);
case EXPR_FUNCTION:
case EXPR_PRETTY_FUNCTION:
- return function_name_to_firm((const string_literal_t*)expression);
+ return function_name_to_firm(&expression->string_literal);
case EXPR_STATEMENT:
- return statement_expression_to_firm(
- (const statement_expression_t*) expression);
+ return statement_expression_to_firm(&expression->statement);
case EXPR_OFFSETOF:
case EXPR_VA_ARG:
case EXPR_BUILTIN_SYMBOL:
ir_node *res = _expression_to_firm(expression);
if(res != NULL && get_irn_mode(res) == mode_b) {
- ir_mode *mode = get_ir_mode(expression->datatype);
+ ir_mode *mode = get_ir_mode(expression->base.datatype);
res = create_conv(NULL, res, mode);
}
break;
}
- dbg_info *dbgi = get_dbg_info(&expression->source_position);
+ dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
ir_node *condition = expression_to_modeb(expression);
ir_node *cond = new_d_Cond(dbgi, condition);
ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
{
ir_node *result = NULL;
statement_t *statement = compound->statements;
- for( ; statement != NULL; statement = statement->next) {
+ for( ; statement != NULL; statement = statement->base.next) {
//context2firm(&statement->context);
- if(statement->next == NULL && statement->type == STATEMENT_EXPRESSION) {
+ if(statement->base.next == NULL
+ && statement->type == STATEMENT_EXPRESSION) {
result = expression_statement_to_firm(
(expression_statement_t*) statement);
break;
if(get_cur_block() == NULL)
return;
- dbg_info *dbgi = get_dbg_info(&statement->source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
ir_node *jump = new_d_Jmp(dbgi);
add_immBlock_pred(target_block, jump);
static int count_decls_in_stmts(const statement_t *stmt)
{
int count = 0;
- for (; stmt != NULL; stmt = stmt->next) {
+ for (; stmt != NULL; stmt = stmt->base.next) {
switch (stmt->type) {
case STATEMENT_DECLARATION: {
const declaration_statement_t *const decl_stmt =
declaration_t *declarations;
};
-struct expression_t {
+struct expression_base_t {
expresion_type_t type;
type_t *datatype;
source_position_t source_position;
};
-struct const_t {
- expression_t expression;
+struct const_expression_t {
+ expression_base_t expression;
union {
long long int_value;
long double float_value;
} v;
};
-struct string_literal_t {
- expression_t expression;
- const char *value;
+struct string_literal_expression_t {
+ expression_base_t expression;
+ const char *value;
};
struct builtin_symbol_expression_t {
- expression_t expression;
- symbol_t *symbol;
+ expression_base_t expression;
+ symbol_t *symbol;
};
struct reference_expression_t {
- expression_t expression;
- symbol_t *symbol;
- declaration_t *declaration;
+ expression_base_t expression;
+ symbol_t *symbol;
+ declaration_t *declaration;
};
struct call_argument_t {
};
struct call_expression_t {
- expression_t expression;
- expression_t *function;
- call_argument_t *arguments;
+ expression_base_t expression;
+ expression_t *function;
+ call_argument_t *arguments;
};
typedef enum {
} unary_expression_type_t;
struct unary_expression_t {
- expression_t expression;
+ expression_base_t expression;
unary_expression_type_t type;
expression_t *value;
};
} binary_expression_type_t;
struct binary_expression_t {
- expression_t expression;
+ expression_base_t expression;
binary_expression_type_t type;
expression_t *left;
expression_t *right;
};
struct select_expression_t {
- expression_t expression;
- expression_t *compound;
- symbol_t *symbol;
+ expression_base_t expression;
+ expression_t *compound;
+ symbol_t *symbol;
- declaration_t *compound_entry;
+ declaration_t *compound_entry;
};
struct array_access_expression_t {
- expression_t expression;
- expression_t *array_ref;
- expression_t *index;
- bool flipped; /* index/ref was written in a 5[a] way */
+ expression_base_t expression;
+ expression_t *array_ref;
+ expression_t *index;
+ bool flipped; /* index/ref was written in a 5[a] way */
};
struct sizeof_expression_t {
- expression_t expression;
- type_t *type;
- expression_t *size_expression;
+ expression_base_t expression;
+ type_t *type;
+ expression_t *size_expression;
};
struct designator_t {
};
struct offsetof_expression_t {
- expression_t expression;
- type_t *type;
- designator_t *designator;
+ expression_base_t expression;
+ type_t *type;
+ designator_t *designator;
};
struct va_arg_expression_t {
- expression_t expression;
- expression_t *arg;
- type_t *type;
+ expression_base_t expression;
+ expression_t *arg;
+ type_t *type;
};
struct conditional_expression_t {
- expression_t expression;
- expression_t *condition;
- expression_t *true_expression;
- expression_t *false_expression;
+ expression_base_t expression;
+ expression_t *condition;
+ expression_t *true_expression;
+ expression_t *false_expression;
};
struct statement_expression_t {
- expression_t expression;
- statement_t *statement;
+ expression_base_t expression;
+ statement_t *statement;
};
struct classify_type_expression_t {
- expression_t expression;
- expression_t *type_expression;
+ expression_base_t expression;
+ expression_t *type_expression;
+};
+
+union expression_t {
+ expresion_type_t type;
+ expression_base_t base;
+ const_expression_t conste;
+ string_literal_expression_t string_literal;
+ builtin_symbol_expression_t builtin_symbol;
+ reference_expression_t reference;
+ call_expression_t call;
+ unary_expression_t unary;
+ binary_expression_t binary;
+ select_expression_t select;
+ array_access_expression_t array_access;
+ sizeof_expression_t sizeofe;
+ offsetof_expression_t offsetofe;
+ va_arg_expression_t va_arg;
+ conditional_expression_t conditional;
+ statement_expression_t statement;
+ classify_type_expression_t classify_type;
};
typedef enum {
STATEMENT_FOR
} statement_type_t;
-struct statement_t {
+struct statement_base_t {
statement_type_t type;
statement_t *next;
source_position_t source_position;
};
struct return_statement_t {
- statement_t statement;
- expression_t *return_value;
+ statement_base_t statement;
+ expression_t *return_value;
};
struct compound_statement_t {
- statement_t statement;
- statement_t *statements;
- context_t context;
+ statement_base_t statement;
+ statement_t *statements;
+ context_t context;
};
struct declaration_statement_t {
- statement_t statement;
- declaration_t *declarations_begin;
- declaration_t *declarations_end;
+ statement_base_t statement;
+ declaration_t *declarations_begin;
+ declaration_t *declarations_end;
};
struct if_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *true_statement;
- statement_t *false_statement;
+ statement_base_t statement;
+ expression_t *condition;
+ statement_t *true_statement;
+ statement_t *false_statement;
};
struct switch_statement_t {
- statement_t statement;
- expression_t *expression;
- statement_t *body;
+ statement_base_t statement;
+ expression_t *expression;
+ statement_t *body;
};
struct goto_statement_t {
- statement_t statement;
- declaration_t *label;
+ statement_base_t statement;
+ declaration_t *label;
};
struct case_label_statement_t {
- statement_t statement;
- expression_t *expression;
- statement_t *label_statement;
+ statement_base_t statement;
+ expression_t *expression;
+ statement_t *label_statement;
};
struct label_statement_t {
- statement_t statement;
- declaration_t *label;
- statement_t *label_statement;
+ statement_base_t statement;
+ declaration_t *label;
+ statement_t *label_statement;
};
struct expression_statement_t {
- statement_t statement;
- expression_t *expression;
+ statement_base_t statement;
+ expression_t *expression;
};
struct while_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *body;
+ statement_base_t statement;
+ expression_t *condition;
+ statement_t *body;
};
struct do_while_statement_t {
- statement_t statement;
- expression_t *condition;
- statement_t *body;
+ statement_base_t statement;
+ expression_t *condition;
+ statement_t *body;
};
struct for_statement_t {
- statement_t statement;
- expression_t *initialisation;
- expression_t *condition;
- expression_t *step;
- statement_t *body;
- context_t context;
+ statement_base_t statement;
+ expression_t *initialisation;
+ expression_t *condition;
+ expression_t *step;
+ statement_t *body;
+ context_t context;
+};
+
+union statement_t {
+ statement_type_t type;
+ statement_base_t base;
+ return_statement_t returns;
+ compound_statement_t compound;
+ declaration_statement_t declaration;
+ if_statement_t ifs;
+ switch_statement_t switchs;
+ goto_statement_t gotos;
+ case_label_statement_t case_label;
+ label_statement_t label;
+ expression_statement_t expression;
+ while_statement_t whiles;
+ do_while_statement_t do_while;
+ for_statement_t fors;
};
struct translation_unit_t {
return (expression_t*) cast;
}
-static bool is_null_expression(const expression_t *const expr)
+static bool is_null_expression(const expression_t *const expression)
{
- if (expr->type != EXPR_CONST) return false;
+ if (expression->type != EXPR_CONST)
+ return false;
- type_t *const type = skip_typeref(expr->datatype);
- if (!is_type_integer(type)) return false;
+ type_t *const type = skip_typeref(expression->base.datatype);
+ if (!is_type_integer(type))
+ return false;
- const const_t *const const_expr = (const const_t*)expr;
- return const_expr->v.int_value == 0;
+ return expression->conste.v.int_value == 0;
}
static expression_t *create_implicit_cast(expression_t *expression,
type_t *dest_type)
{
- type_t *source_type = expression->datatype;
+ type_t *source_type = expression->base.datatype;
if(source_type == NULL)
return expression;
if(is_type_floating(dest_type) && !is_type_scalar(source_type)) {
type_error_incompatible("can't cast types",
- expression->source_position, source_type, dest_type);
+ expression->base.source_position, source_type,
+ dest_type);
return expression;
}
}
type_error_incompatible("can't implicitly cast types",
- expression->source_position, source_type, dest_type);
+ expression->base.source_position, source_type, dest_type);
return expression;
default:
static void semantic_assign(type_t *orig_type_left, expression_t **right,
const char *context)
{
- type_t *orig_type_right = (*right)->datatype;
+ type_t *orig_type_right = (*right)->base.datatype;
if(orig_type_right == NULL)
return;
}
if (is_type_pointer(type_left) && is_type_pointer(type_right)) {
- pointer_type_t *pointer_type_left = (pointer_type_t*) type_left;
- pointer_type_t *pointer_type_right = (pointer_type_t*) type_right;
+ pointer_type_t *pointer_type_left = &type_left->pointer;
+ pointer_type_t *pointer_type_right = &type_right->pointer;
type_t *points_to_left = pointer_type_left->points_to;
type_t *points_to_right = pointer_type_right->points_to;
|| atype == ATOMIC_TYPE_SCHAR
|| atype == ATOMIC_TYPE_UCHAR) {
- string_literal_t *literal = (string_literal_t*) expression;
+ string_literal_expression_t *literal
+ = &expression->string_literal;
return initializer_from_string(array_type, literal->value);
}
}
}
expression_t *expression = parse_assignment_expression();
- type_t *expression_type = skip_typeref(expression->datatype);
+ type_t *expression_type = skip_typeref(expression->base.datatype);
return parse_sub_initializer(type, expression, expression_type);
}
initializer_t *result = NULL;
initializer_t **elems;
if(type->type == TYPE_ARRAY) {
- array_type_t *array_type = (array_type_t*) type;
+ array_type_t *array_type = &type->array;
type_t *element_type = array_type->element_type;
element_type = skip_typeref(element_type);
} else {
assert(type->type == TYPE_COMPOUND_STRUCT
|| type->type == TYPE_COMPOUND_UNION);
- compound_type_t *compound_type = (compound_type_t*) type;
+ compound_type_t *compound_type = &type->compound;
context_t *context = & compound_type->declaration->context;
declaration_t *first = context->declarations;
type = parse_typename();
} else {
expression = parse_expression();
- type = expression->datatype;
+ type = expression->base.datatype;
}
break;
default:
expression = parse_expression();
- type = expression->datatype;
+ type = expression->base.datatype;
break;
}
/* Array as last part of a paramter type is just syntactic sugar. Turn it
* into a pointer */
if (declaration->type->type == TYPE_ARRAY) {
- const array_type_t *const arr_type =
- (const array_type_t*)declaration->type;
+ const array_type_t *const arr_type = &declaration->type->array;
type_t *element_type = arr_type->element_type;
declaration->type = make_pointer_type(element_type, TYPE_QUALIFIER_NONE);
}
initializer_t *initializer = parse_initializer(type);
if(type->type == TYPE_ARRAY && initializer != NULL) {
- array_type_t *array_type = (array_type_t*) type;
+ array_type_t *array_type = &type->array;
if(array_type->size == NULL) {
- const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+ const_expression_t
+ *cnst = allocate_ast_zero(sizeof(cnst[0]));
cnst->expression.type = EXPR_CONST;
cnst->expression.datatype = type_size_t;
switch (specifiers.type->type) {
case TYPE_COMPOUND_STRUCT:
case TYPE_COMPOUND_UNION: {
- const compound_type_t *const comp_type =
- (const compound_type_t*)specifiers.type;
+ const compound_type_t *const comp_type
+ = &specifiers.type->compound;
if (comp_type->declaration->symbol == NULL) {
parse_warning_pos(source_position,
"unnamed struct/union that defines no instances");
static expression_t *make_invalid_expression(void)
{
- expression_t *expression = allocate_ast_zero(sizeof(expression[0]));
- expression->type = EXPR_INVALID;
- expression->source_position = token.source_position;
+ expression_t *expression = allocate_ast_zero(sizeof(expression[0]));
+ expression->type = EXPR_INVALID;
+ expression->base.source_position = token.source_position;
return expression;
}
static expression_t *parse_string_const(void)
{
- string_literal_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+ string_literal_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
cnst->expression.type = EXPR_STRING_LITERAL;
cnst->expression.datatype = type_string;
static expression_t *parse_int_const(void)
{
- const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+ const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
cnst->expression.type = EXPR_CONST;
cnst->expression.datatype = token.datatype;
static expression_t *parse_float_const(void)
{
- const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+ const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
cnst->expression.type = EXPR_CONST;
cnst->expression.datatype = token.datatype;
return NULL;
if(type->type == TYPE_ARRAY) {
- array_type_t *array_type = (array_type_t*) type;
+ array_type_t *array_type = &type->array;
type_t *element_type = array_type->element_type;
unsigned qualifiers = array_type->type.qualifiers;
*/
type_t *revert_automatic_type_conversion(const expression_t *expression)
{
- if(expression->datatype == NULL)
+ if(expression->base.datatype == NULL)
return NULL;
switch(expression->type) {
= (const unary_expression_t*) expression;
if(unary->type == UNEXPR_DEREFERENCE) {
expression_t *value = unary->value;
- type_t *type = skip_typeref(value->datatype);
- pointer_type_t *pointer_type = (pointer_type_t*) type;
+ type_t *type = skip_typeref(value->base.datatype);
+ pointer_type_t *pointer_type = &type->pointer;
return pointer_type->points_to;
}
}
case EXPR_ARRAY_ACCESS: {
const array_access_expression_t *array_access
- = (const array_access_expression_t*) expression;
- type_t *type_left = skip_typeref(array_access->array_ref->datatype);
+ = &expression->array_access;
+ const expression_t *array_ref = array_access->array_ref;
+ type_t *type_left = skip_typeref(array_ref->base.datatype);
assert(is_type_pointer(type_left));
- pointer_type_t *pointer_type = (pointer_type_t*) type_left;
+ pointer_type_t *pointer_type = &type_left->pointer;
return pointer_type->points_to;
}
break;
}
- return expression->datatype;
+ return expression->base.datatype;
}
static expression_t *parse_reference(void)
/* find last statement and use it's type */
const statement_t *last_statement = NULL;
const statement_t *iter = compound_statement->statements;
- for( ; iter != NULL; iter = iter->next) {
+ for( ; iter != NULL; iter = iter->base.next) {
last_statement = iter;
}
const expression_statement_t *expression_statement =
(const expression_statement_t*) last_statement;
expression->expression.datatype
- = expression_statement->expression->datatype;
+ = expression_statement->expression->base.datatype;
} else {
expression->expression.datatype = type_void;
}
parse_error("'__func__' used outside of a function");
}
- string_literal_t *expression = allocate_ast_zero(sizeof(expression[0]));
+ string_literal_expression_t *expression
+ = allocate_ast_zero(sizeof(expression[0]));
+
expression->expression.type = EXPR_FUNCTION;
expression->expression.datatype = type_string;
expression->value = "TODO: FUNCTION";
eat(T___PRETTY_FUNCTION__);
/* TODO */
- string_literal_t *expression = allocate_ast_zero(sizeof(expression[0]));
+ string_literal_expression_t *expression
+ = allocate_ast_zero(sizeof(expression[0]));
+
expression->expression.type = EXPR_PRETTY_FUNCTION;
expression->expression.datatype = type_string;
expression->value = "TODO: PRETTY FUNCTION";
array_access->expression.type = EXPR_ARRAY_ACCESS;
- type_t *type_left = skip_typeref(left->datatype);
- type_t *type_inside = skip_typeref(inside->datatype);
- type_t *result_type;
+ type_t *type_left = left->base.datatype;
+ type_t *type_inside = inside->base.datatype;
+ type_t *result_type = NULL;
if(type_left != NULL && type_inside != NULL) {
+ type_left = skip_typeref(type_left);
+ type_inside = skip_typeref(type_inside);
+
if(is_type_pointer(type_left)) {
- pointer_type_t *pointer = (pointer_type_t*) type_left;
+ pointer_type_t *pointer = &type_left->pointer;
result_type = pointer->points_to;
array_access->array_ref = left;
array_access->index = inside;
} else if(is_type_pointer(type_inside)) {
- pointer_type_t *pointer = (pointer_type_t*) type_inside;
+ pointer_type_t *pointer = &type_inside->pointer;
result_type = pointer->points_to;
array_access->array_ref = inside;
array_access->index = left;
sizeof_expression->type = parse_typename();
expect(')');
} else {
- expression_t *expression = parse_sub_expression(precedence);
- expression->datatype = revert_automatic_type_conversion(expression);
+ expression_t *expression = parse_sub_expression(precedence);
+ expression->base.datatype = revert_automatic_type_conversion(expression);
- sizeof_expression->type = expression->datatype;
+ sizeof_expression->type = expression->base.datatype;
sizeof_expression->size_expression = expression;
}
select->symbol = symbol;
next_token();
- type_t *orig_type = compound->datatype;
+ type_t *orig_type = compound->base.datatype;
if(orig_type == NULL)
return make_invalid_expression();
fputc('\n', stderr);
return make_invalid_expression();
}
- pointer_type_t *pointer_type = (pointer_type_t*) type;
+ pointer_type_t *pointer_type = &type->pointer;
type_left = pointer_type->points_to;
}
type_left = skip_typeref(type_left);
return make_invalid_expression();
}
- compound_type_t *compound_type = (compound_type_t*) type_left;
+ compound_type_t *compound_type = &type_left->compound;
declaration_t *declaration = compound_type->declaration;
if(!declaration->init.is_defined) {
call->expression.type = EXPR_CALL;
call->function = expression;
- function_type_t *function_type;
- type_t *orig_type = expression->datatype;
+ function_type_t *function_type = NULL;
+ type_t *orig_type = expression->base.datatype;
if(orig_type != NULL) {
- function_type = NULL;
type_t *type = skip_typeref(orig_type);
if(is_type_pointer(type)) {
- pointer_type_t *pointer_type = (pointer_type_t*) type;
+ pointer_type_t *pointer_type = &type->pointer;
type = skip_typeref(pointer_type->points_to);
if (type->type == TYPE_FUNCTION) {
- function_type = (function_type_t*) type;
+ function_type = &type->function;
call->expression.datatype = function_type->result_type;
}
}
} else {
/* do default promotion */
for( ; argument != NULL; argument = argument->next) {
- type_t *type = argument->expression->datatype;
+ type_t *type = argument->expression->base.datatype;
type = skip_typeref(type);
if(type == NULL)
conditional->condition = expression;
/* 6.5.15.2 */
- type_t *condition_type_orig = conditional->condition->datatype;
+ type_t *condition_type_orig = conditional->condition->base.datatype;
if(condition_type_orig != NULL) {
type_t *condition_type = skip_typeref(condition_type_orig);
if(condition_type != NULL && !is_type_scalar(condition_type)) {
- type_error("expected a scalar type", expression->source_position,
- condition_type_orig);
+ type_error("expected a scalar type",
+ expression->base.source_position, condition_type_orig);
}
}
expression_t *const f_expr = parse_sub_expression(precedence);
conditional->false_expression = f_expr;
- type_t *const true_type = t_expr->datatype;
+ type_t *const true_type = t_expr->base.datatype;
if(true_type == NULL)
return (expression_t*) conditional;
- type_t *const false_type = f_expr->datatype;
+ type_t *const false_type = f_expr->base.datatype;
if(false_type == NULL)
return (expression_t*) conditional;
/* TODO */
} else {
type_error_incompatible("while parsing conditional",
- expression->source_position, true_type,
+ expression->base.source_position, true_type,
skipped_false_type);
}
static void semantic_incdec(unary_expression_t *expression)
{
- type_t *orig_type = expression->value->datatype;
+ type_t *orig_type = expression->value->base.datatype;
if(orig_type == NULL)
return;
static void semantic_unexpr_arithmetic(unary_expression_t *expression)
{
- type_t *orig_type = expression->value->datatype;
+ type_t *orig_type = expression->value->base.datatype;
if(orig_type == NULL)
return;
static void semantic_unexpr_scalar(unary_expression_t *expression)
{
- type_t *orig_type = expression->value->datatype;
+ type_t *orig_type = expression->value->base.datatype;
if(orig_type == NULL)
return;
static void semantic_unexpr_integer(unary_expression_t *expression)
{
- type_t *orig_type = expression->value->datatype;
+ type_t *orig_type = expression->value->base.datatype;
if(orig_type == NULL)
return;
static void semantic_dereference(unary_expression_t *expression)
{
- type_t *orig_type = expression->value->datatype;
+ type_t *orig_type = expression->value->base.datatype;
if(orig_type == NULL)
return;
type_t *type = skip_typeref(orig_type);
if(!is_type_pointer(type)) {
parser_print_error_prefix();
- fputs("'Unary *' needs pointer or arrray type, but type ", stderr);
+ fputs("Unary '*' needs pointer or arrray type, but type ", stderr);
print_type_quoted(orig_type);
fputs(" given.\n", stderr);
return;
}
- pointer_type_t *pointer_type = (pointer_type_t*)type;
+ pointer_type_t *pointer_type = &type->pointer;
type_t *result_type = pointer_type->points_to;
result_type = automatic_type_conversion(result_type);
static void semantic_take_addr(unary_expression_t *expression)
{
- expression_t *value = expression->value;
- value->datatype = revert_automatic_type_conversion(value);
+ expression_t *value = expression->value;
+ value->base.datatype = revert_automatic_type_conversion(value);
- type_t *orig_type = value->datatype;
+ type_t *orig_type = value->base.datatype;
if(orig_type == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
{
expression_t *left = expression->left;
expression_t *right = expression->right;
- type_t *orig_type_left = left->datatype;
- type_t *orig_type_right = right->datatype;
+ type_t *orig_type_left = left->base.datatype;
+ type_t *orig_type_right = right->base.datatype;
if(orig_type_left == NULL || orig_type_right == NULL)
return;
static void semantic_binexpr_assign(binary_expression_t *expression)
{
expression_t *left = expression->left;
- type_t *orig_type_left = left->datatype;
+ type_t *orig_type_left = left->base.datatype;
if(orig_type_left == NULL)
return;
static void semantic_comma(binary_expression_t *expression)
{
- expression->expression.datatype = expression->right->datatype;
+ expression->expression.datatype = expression->right->base.datatype;
}
#define CREATE_BINEXPR_PARSER(token_type, binexpression_type, sfunc, lr) \
left = parse_primary_expression();
}
assert(left != NULL);
- left->source_position = source_position;
+ left->base.source_position = source_position;
while(true) {
if(token.type < 0) {
assert(left != NULL);
assert(left->type != EXPR_UNKNOWN);
- left->source_position = source_position;
+ left->base.source_position = source_position;
}
return left;
eat(T_continue);
expect(';');
- statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->type = STATEMENT_CONTINUE;
- statement->source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_CONTINUE;
+ statement->base.source_position = token.source_position;
return statement;
}
eat(T_break);
expect(';');
- statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->type = STATEMENT_BREAK;
- statement->source_position = token.source_position;
+ statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+ statement->type = STATEMENT_BREAK;
+ statement->base.source_position = token.source_position;
return statement;
}
statement->statement.source_position = token.source_position;
assert(current_function->type->type == TYPE_FUNCTION);
- function_type_t *function_type = (function_type_t*) current_function->type;
+ function_type_t *function_type = ¤t_function->type->function;
type_t *return_type = function_type->result_type;
- expression_t *return_value;
+ expression_t *return_value = NULL;
if(token.type != ';') {
return_value = parse_expression();
+ }
+ expect(';');
+
+ if(return_type == NULL)
+ return (statement_t*) statement;
+
+ return_type = skip_typeref(return_type);
- if(return_type == type_void && return_value->datatype != type_void) {
+ if(return_value != NULL) {
+ type_t *return_value_type = skip_typeref(return_value->base.datatype);
+
+ if(is_type_atomic(return_type, ATOMIC_TYPE_VOID)
+ && !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) {
parse_warning("'return' with a value, in function returning void");
return_value = NULL;
} else {
}
}
} else {
- return_value = NULL;
- if(return_type != type_void) {
+ if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
parse_warning("'return' without value, in function returning "
"non-void");
}
}
statement->return_value = return_value;
- expect(';');
-
return (statement_t*) statement;
}
break;
}
- assert(statement == NULL || statement->source_position.input_name != NULL);
+ assert(statement == NULL
+ || statement->base.source_position.input_name != NULL);
return statement;
}
continue;
if(last_statement != NULL) {
- last_statement->next = statement;
+ last_statement->base.next = statement;
} else {
compound_statement->statements = statement;
}
- while(statement->next != NULL)
- statement = statement->next;
+ while(statement->base.next != NULL)
+ statement = statement->base.next;
last_statement = statement;
}