From 3bd432f7fe5fa4d3f84ddeaf5806398c141e4f28 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 12 Nov 2007 19:48:03 +0000 Subject: [PATCH] partly implemented reference_expression_to_firm and unary expression_to_firm [r18376] --- ast.c | 8 +- ast2firm.c | 295 ++++++++++++++++++++++++++++++++++++++++--------- ast_t.h | 14 ++- parser.c | 145 ++++++++++++++---------- type.c | 8 +- write_fluffy.c | 2 +- 6 files changed, 346 insertions(+), 126 deletions(-) diff --git a/ast.c b/ast.c index d8b34d8..5bd7cea 100644 --- a/ast.c +++ b/ast.c @@ -374,8 +374,8 @@ static void print_declaration_statement( { int first = 1; declaration_t *declaration = statement->declarations_begin; - for( ; declaration != statement->declarations_end->context_next; - declaration = declaration->context_next) { + for( ; declaration != statement->declarations_end->next; + declaration = declaration->next) { if(!first) { print_indent(); } else { @@ -410,7 +410,7 @@ static void print_for_statement(const for_statement_t *statement) if(statement->context.declarations != NULL) { assert(statement->initialisation == NULL); print_declaration(statement->context.declarations); - if(statement->context.declarations->context_next != NULL) { + if(statement->context.declarations->next != NULL) { panic("multiple declarations in for statement not supported yet"); } } else if(statement->initialisation) { @@ -570,7 +570,7 @@ void print_ast(const translation_unit_t *unit) set_print_compound_entries(true); declaration_t *declaration = unit->context.declarations; - for( ; declaration != NULL; declaration = declaration->context_next) { + for( ; declaration != NULL; declaration = declaration->next) { if(declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY) continue; if(declaration->namespace != NAMESPACE_NORMAL && diff --git a/ast2firm.c b/ast2firm.c index 7039327..51e80f5 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -22,6 +22,17 @@ static type_t *type_const_char; static type_t *type_void; static type_t *type_int; +typedef enum declaration_type_t { + DECLARATION_TYPE_UNKNOWN, + DECLARATION_TYPE_FUNCTION, + DECLARATION_TYPE_GLOBAL_VARIABLE, + DECLARATION_TYPE_PARAMETER, + DECLARATION_TYPE_PARAMETER_ENTITY, + DECLARATION_TYPE_LOCAL_VARIABLE, + DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY, + DECLARATION_TYPE_COMPOUND_MEMBER +} declaration_type_t; + typedef struct type2firm_env_t type2firm_env_t; struct type2firm_env_t { int can_cache; /* nonzero if type can safely be cached because @@ -76,6 +87,8 @@ void init_ast2firm(void) type in firm */ ir_type_void_ptr = new_type_pointer(new_id_from_str("void_ptr"), ir_type_void, mode_P_data); + + type_void->firm_type = ir_type_void; } void exit_ast2firm(void) @@ -281,7 +294,8 @@ static unsigned count_parameters(const function_type_t *function_type) -static ir_type *get_atomic_type(type2firm_env_t *env, const atomic_type_t *type) +static ir_type *create_atomic_type(type2firm_env_t *env, + const atomic_type_t *type) { (void) env; ir_mode *mode = get_atomic_mode(type); @@ -291,8 +305,8 @@ static ir_type *get_atomic_type(type2firm_env_t *env, const atomic_type_t *type) return irtype; } -static ir_type *get_method_type(type2firm_env_t *env, - const function_type_t *function_type) +static ir_type *create_method_type(type2firm_env_t *env, + const function_type_t *function_type) { type_t *result_type = function_type->result_type; @@ -321,7 +335,7 @@ static ir_type *get_method_type(type2firm_env_t *env, return irtype; } -static ir_type *get_pointer_type(type2firm_env_t *env, pointer_type_t *type) +static ir_type *create_pointer_type(type2firm_env_t *env, pointer_type_t *type) { type_t *points_to = type->points_to; ir_type *ir_points_to; @@ -329,9 +343,8 @@ static ir_type *get_pointer_type(type2firm_env_t *env, pointer_type_t *type) * again (might be a struct). We therefore first create a void* pointer * and then set the real points_to type */ - ir_type *ir_type_void = get_ir_type(type_void); - ir_type *ir_type = new_type_pointer(unique_ident("pointer"), - ir_type_void, mode_P_data); + ir_type *ir_type = new_type_pointer(unique_ident("pointer"), + ir_type_void, mode_P_data); type->type.firm_type = ir_type; ir_points_to = _get_ir_type(env, points_to); @@ -340,7 +353,7 @@ static ir_type *get_pointer_type(type2firm_env_t *env, pointer_type_t *type) return ir_type; } -static ir_type *get_array_type(type2firm_env_t *env, array_type_t *type) +static ir_type *create_array_type(type2firm_env_t *env, array_type_t *type) { type_t *element_type = type->element_type; ir_type *ir_element_type = _get_ir_type(env, element_type); @@ -366,7 +379,7 @@ static ir_type *get_array_type(type2firm_env_t *env, array_type_t *type) #define INVALID_TYPE ((ir_type_ptr)-1) -static ir_type *get_struct_type(type2firm_env_t *env, compound_type_t *type) +static ir_type *create_struct_type(type2firm_env_t *env, compound_type_t *type) { symbol_t *symbol = type->declaration->symbol; ident *id; @@ -394,7 +407,8 @@ static ir_type *get_struct_type(type2firm_env_t *env, compound_type_t *type) ir_entity *entity = new_entity(ir_type, ident, entry_ir_type); set_entity_offset(entity, offset); add_struct_member(ir_type, entity); - entry->entity = entity; + entry->declaration_type = DECLARATION_TYPE_COMPOUND_MEMBER; + entry->v.entity = entity; offset += entry_size; if(entry_alignment > align_all) { @@ -414,7 +428,7 @@ static ir_type *get_struct_type(type2firm_env_t *env, compound_type_t *type) return ir_type; } -static ir_type *get_union_type(type2firm_env_t *env, compound_type_t *type) +static ir_type *create_union_type(type2firm_env_t *env, compound_type_t *type) { declaration_t *declaration = type->declaration; symbol_t *symbol = declaration->symbol; @@ -441,7 +455,8 @@ static ir_type *get_union_type(type2firm_env_t *env, compound_type_t *type) ir_entity *entity = new_entity(ir_type, ident, entry_ir_type); add_union_member(ir_type, entity); set_entity_offset(entity, 0); - entry->entity = entity; + entry->declaration_type = DECLARATION_TYPE_COMPOUND_MEMBER; + entry->v.entity = entity; if(entry_size > size) { size = entry_size; @@ -475,22 +490,22 @@ static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type) ir_type *firm_type = NULL; switch(type->type) { case TYPE_ATOMIC: - firm_type = get_atomic_type(env, (atomic_type_t*) type); + firm_type = create_atomic_type(env, (atomic_type_t*) type); break; case TYPE_FUNCTION: - firm_type = get_method_type(env, (function_type_t*) type); + firm_type = create_method_type(env, (function_type_t*) type); break; case TYPE_POINTER: - firm_type = get_pointer_type(env, (pointer_type_t*) type); + firm_type = create_pointer_type(env, (pointer_type_t*) type); break; case TYPE_ARRAY: - firm_type = get_array_type(env, (array_type_t*) type); + firm_type = create_array_type(env, (array_type_t*) type); break; case TYPE_COMPOUND_STRUCT: - firm_type = get_struct_type(env, (compound_type_t*) type); + firm_type = create_struct_type(env, (compound_type_t*) type); break; case TYPE_COMPOUND_UNION: - firm_type = get_union_type(env, (compound_type_t*) type); + firm_type = create_union_type(env, (compound_type_t*) type); break; case TYPE_ENUM: firm_type = ir_type_int; @@ -527,10 +542,11 @@ static inline ir_mode *get_ir_mode(type_t *type) return mode; } -static ir_entity* get_entity_function(declaration_t *declaration) +static ir_entity* get_function_entity(declaration_t *declaration) { - if(declaration->entity != NULL) - return declaration->entity; + if(declaration->declaration_type == DECLARATION_TYPE_FUNCTION) + return declaration->v.entity; + assert(declaration->declaration_type == DECLARATION_TYPE_UNKNOWN); symbol_t *symbol = declaration->symbol; ident *id = new_id_from_str(symbol->string); @@ -551,12 +567,16 @@ static ir_entity* get_entity_function(declaration_t *declaration) set_entity_visibility(entity, visibility_external_allocated); } - declaration->entity = entity; + declaration->declaration_type = DECLARATION_TYPE_FUNCTION; + declaration->v.entity = entity; + return entity; } +static ir_node *expression_to_firm(const expression_t *expression); + static dbg_info *get_dbg_info(const source_position_t *pos) { return (dbg_info*) pos; @@ -577,14 +597,24 @@ static ir_node *const_to_firm(const const_t *cnst) return new_d_Const(dbgi, mode, tv); } +static ir_node *create_symconst(dbg_info *dbgi, ir_entity *entity) +{ + assert(entity != NULL); + union symconst_symbol sym; + sym.entity_p = entity; + return new_d_SymConst(dbgi, sym, symconst_addr_ent); +} + static ir_node *string_literal_to_firm(const string_literal_t* literal) { ir_type *global_type = get_glob_type(); ir_type *type = new_type_array(unique_ident("strtype"), 1, ir_type_const_char); - ir_entity *ent = new_entity(global_type, unique_ident("Lstr"), type); - set_entity_variability(ent, variability_constant); + ident *id = unique_ident("Lstr"); + ir_entity *entity = new_entity(global_type, id, type); + set_entity_ld_ident(entity, id); + set_entity_variability(entity, variability_constant); ir_type *elem_type = ir_type_const_char; ir_mode *mode = get_type_mode(elem_type); @@ -602,50 +632,72 @@ static ir_node *string_literal_to_firm(const string_literal_t* literal) tvs[i] = new_tarval_from_long(string[i], mode); } - set_array_entity_values(ent, tvs, slen); + set_array_entity_values(entity, tvs, slen); free(tvs); dbg_info *dbgi = get_dbg_info(&literal->expression.source_position); - union symconst_symbol sym; - sym.entity_p = ent; - return new_d_SymConst(dbgi, sym, symconst_addr_ent); + return create_symconst(dbgi, entity); +} + +static ir_node *reference_expression_to_firm(const reference_expression_t *ref) +{ + dbg_info *dbgi = get_dbg_info(&ref->expression.source_position); + declaration_t *declaration = ref->declaration; + + switch((declaration_type_t) declaration->declaration_type) { + case DECLARATION_TYPE_UNKNOWN: + break; + case DECLARATION_TYPE_PARAMETER: { + ir_node *args = get_irg_args(current_ir_graph); + ir_mode *mode = get_ir_mode(declaration->type); + ir_node *block = get_irg_start_block(current_ir_graph); + long pn = declaration->v.value_number; + + return new_r_Proj(current_ir_graph, block, args, mode, pn); + } + case DECLARATION_TYPE_FUNCTION: { + return create_symconst(dbgi, declaration->v.entity); + } + case DECLARATION_TYPE_PARAMETER_ENTITY: + case DECLARATION_TYPE_LOCAL_VARIABLE: + case DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY: + case DECLARATION_TYPE_GLOBAL_VARIABLE: + case DECLARATION_TYPE_COMPOUND_MEMBER: + panic("not implemented reference type"); + } + + panic("reference to declaration with unknown type found"); } -#if 0 static ir_node *call_expression_to_firm(const call_expression_t *call) { expression_t *function = call->function; ir_node *callee = expression_to_firm(function); assert(function->datatype->type == TYPE_FUNCTION); - pointer_type_t *pointer_type = (pointer_type_t*) function->datatype; - type_t *points_to = pointer_type->points_to; - - assert(points_to->type == TYPE_FUNCTION); - method_type_t *method_type = (method_type_t*) points_to; - ir_type *ir_method_type = get_ir_type((type_t*) method_type); - ir_type *new_method_type = NULL; + function_type_t *function_type = (function_type_t*) function->datatype; int n_parameters = 0; call_argument_t *argument = call->arguments; - while(argument != NULL) { - n_parameters++; - argument = argument->next; + for( ; argument != NULL; argument = argument->next) { + ++n_parameters; } - if(method_type->variable_arguments) { + ir_type *ir_method_type = get_ir_type((type_t*) function_type); + ir_type *new_method_type = NULL; + if(function_type->variadic) { /* we need to construct a new method type matching the call * arguments... */ + int n_res = get_method_n_ress(ir_method_type); new_method_type = new_type_method(unique_ident("calltype"), - n_parameters, - get_method_n_ress(ir_method_type)); + n_parameters, n_res); set_method_calling_convention(new_method_type, get_method_calling_convention(ir_method_type)); set_method_additional_properties(new_method_type, get_method_additional_properties(ir_method_type)); - for(int i = 0; i < get_method_n_ress(ir_method_type); ++i) { + for(int i = 0; i < n_res; ++i) { set_method_res_type(new_method_type, i, get_method_res_type(ir_method_type, i)); } @@ -654,10 +706,9 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) argument = call->arguments; int n = 0; - while(argument != NULL) { + for( ; argument != NULL; argument = argument->next) { expression_t *expression = argument->expression; - - ir_node *arg_node = expression_to_firm(expression); + ir_node *arg_node = expression_to_firm(expression); in[n] = arg_node; if(new_method_type != NULL) { @@ -665,9 +716,9 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) set_method_param_type(new_method_type, n, irtype); } - argument = argument->next; n++; } + assert(n == n_parameters); if(new_method_type != NULL) ir_method_type = new_method_type; @@ -679,9 +730,9 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) ir_node *mem = new_d_Proj(dbgi, node, mode_M, pn_Call_M_regular); set_store(mem); - type_t *result_type = method_type->result_type; + type_t *result_type = function_type->result_type; ir_node *result = NULL; - if(result_type->type != TYPE_VOID) { + if(result_type != type_void) { ir_mode *mode = get_ir_mode(result_type); ir_node *resproj = new_d_Proj(dbgi, node, mode_T, pn_Call_T_result); result = new_d_Proj(dbgi, resproj, mode, 0); @@ -689,15 +740,130 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) return result; } -#endif -static ir_node *expression_to_firm(expression_t *expression) +static ir_node *load_from_expression_addr(type_t *type, ir_node *addr, + dbg_info *dbgi) +{ + ir_mode *mode = get_ir_mode(type); + ir_node *memory = get_store(); + ir_node *load = new_d_Load(dbgi, memory, addr, mode); + ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); + ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); + set_store(load_mem); + + return load_res; +} + +static ir_node *expression_addr(const expression_t *expression) +{ + (void) expression; + panic("expression_addr not implemented yet"); + return NULL; +} + +static void set_value_for_expression(const expression_t *expression, + ir_node *value) +{ + (void) expression; + (void) value; + panic("set_value_for_expression not implemented yet"); +} + +static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) +{ + ir_mode *value_mode = get_irn_mode(value); + + if(value_mode == dest_mode) + return value; + + if(dest_mode == mode_b) { + ir_node *zero = new_Const(value_mode, get_mode_null(value_mode)); + ir_node *cmp = new_d_Cmp(dbgi, value, zero); + ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg); + return proj; + } + + return new_d_Conv(dbgi, value, dest_mode); +} + +static ir_node *unary_expression_to_firm(const unary_expression_t *expression) +{ + dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); + type_t *type = expression->expression.datatype; + ir_mode *mode = get_ir_mode(type); + + if(expression->type == UNEXPR_TAKE_ADDRESS) + return expression_addr(expression->value); + + const expression_t *value = expression->value; + ir_node *value_node = expression_to_firm(value); + + switch(expression->type) { + case UNEXPR_NEGATE: + return new_d_Minus(dbgi, value_node, mode); + case UNEXPR_PLUS: + return value_node; + case UNEXPR_BITWISE_NEGATE: + return new_d_Not(dbgi, value_node, mode); + case UNEXPR_NOT: + if(get_irn_mode(value_node) != mode_b) { + value_node = create_conv(dbgi, value_node, mode_b); + } + value_node = new_d_Not(dbgi, value_node, mode_b); + if(mode != mode_b) { + value_node = create_conv(dbgi, value_node, mode); + } + return value_node; + case UNEXPR_DEREFERENCE: + return load_from_expression_addr(type, value_node, dbgi); + case UNEXPR_POSTFIX_INCREMENT: { + ir_node *one = new_Const(mode, get_mode_one(mode)); + ir_node *new_value = new_d_Add(dbgi, value_node, one, mode); + set_value_for_expression(value, new_value); + return value_node; + } + case UNEXPR_POSTFIX_DECREMENT: { + ir_node *one = new_Const(mode, get_mode_one(mode)); + ir_node *new_value = new_d_Sub(dbgi, value_node, one, mode); + set_value_for_expression(value, new_value); + return value_node; + } + case UNEXPR_PREFIX_INCREMENT: { + ir_node *one = new_Const(mode, get_mode_one(mode)); + ir_node *new_value = new_d_Add(dbgi, value_node, one, mode); + set_value_for_expression(value, new_value); + return new_value; + } + case UNEXPR_PREFIX_DECREMENT: { + ir_node *one = new_Const(mode, get_mode_one(mode)); + ir_node *new_value = new_d_Sub(dbgi, value_node, one, mode); + set_value_for_expression(value, new_value); + return new_value; + } + case UNEXPR_CAST: + return create_conv(dbgi, value_node, mode); + + case UNEXPR_TAKE_ADDRESS: + case UNEXPR_INVALID: + break; + } + panic("invalid UNEXPR type found"); +} + +static ir_node *expression_to_firm(const expression_t *expression) { switch(expression->type) { case EXPR_CONST: return const_to_firm((const const_t*) expression); case EXPR_STRING_LITERAL: return string_literal_to_firm((const string_literal_t*) expression); + case EXPR_REFERENCE: + return reference_expression_to_firm((const reference_expression_t*) + expression); + case EXPR_CALL: + return call_expression_to_firm((const call_expression_t*) expression); + case EXPR_UNARY: + return unary_expression_to_firm((const unary_expression_t*) expression); default: break; } @@ -737,6 +903,11 @@ static void compound_statement_to_firm(compound_statement_t *compound) } } +static void expression_statement_to_firm(expression_statement_t *statement) +{ + expression_to_firm(statement->expression); +} + static void statement_to_firm(statement_t *statement) { switch(statement->type) { @@ -746,6 +917,9 @@ static void statement_to_firm(statement_t *statement) case STATEMENT_RETURN: return_statement_to_firm((return_statement_t*) statement); return; + case STATEMENT_EXPRESSION: + expression_statement_to_firm((expression_statement_t*) statement); + return; default: break; } @@ -759,15 +933,28 @@ static int get_function_n_local_vars(declaration_t *declaration) return 30; } -static void create_function(declaration_t *declaration) +static void initialize_function_parameters(declaration_t *declaration) { - ir_entity *entity = get_entity_function(declaration); + int n = 0; + declaration_t *parameter = declaration->context.declarations; + for( ; parameter != NULL; parameter = parameter->next) { + assert(parameter->declaration_type == DECLARATION_TYPE_UNKNOWN); - //context2firm(declaration->context); + parameter->declaration_type = DECLARATION_TYPE_PARAMETER; + parameter->v.value_number = n; + ++n; + } +} + +static void create_function(declaration_t *declaration) +{ + ir_entity *entity = get_function_entity(declaration); if(declaration->init.statement == NULL) return; + initialize_function_parameters(declaration); + int n_local_vars = get_function_n_local_vars(declaration); ir_graph *irg = new_ir_graph(entity, n_local_vars); ir_node *first_block = get_cur_block(); diff --git a/ast_t.h b/ast_t.h index 3a090c4..61bd6a4 100644 --- a/ast_t.h +++ b/ast_t.h @@ -222,8 +222,8 @@ struct initializer_t { }; struct declaration_t { - unsigned short namespace; - unsigned short storage_class; + unsigned char namespace; + unsigned char storage_class; type_t *type; symbol_t *symbol; source_position_t source_position; @@ -236,11 +236,15 @@ struct declaration_t { context_t *parent_context; /** next declaration in a context */ - declaration_t *context_next; - /** next declaration with same symbol */ declaration_t *next; + /** next declaration with same symbol */ + declaration_t *symbol_next; - ir_entity *entity; + unsigned char declaration_type; /* used in ast2firm module */ + union { + unsigned int value_number; /* used in ast2firm module */ + ir_entity *entity; /* used in ast2firm module */ + } v; }; typedef enum { diff --git a/parser.c b/parser.c index 44b5dc6..520da3a 100644 --- a/parser.c +++ b/parser.c @@ -303,8 +303,8 @@ static void set_context(context_t *new_context) last_declaration = new_context->declarations; if(last_declaration != NULL) { - while(last_declaration->context_next != NULL) { - last_declaration = last_declaration->context_next; + while(last_declaration->next != NULL) { + last_declaration = last_declaration->next; } } } @@ -323,7 +323,7 @@ static bool is_compatible_declaration (declaration_t *declaration, static declaration_t *get_declaration(symbol_t *symbol, namespace_t namespace) { declaration_t *declaration = symbol->declaration; - for( ; declaration != NULL; declaration = declaration->next) { + for( ; declaration != NULL; declaration = declaration->symbol_next) { if(declaration->namespace == namespace) return declaration; } @@ -393,16 +393,16 @@ static declaration_t *environment_push(declaration_t *declaration) symbol->declaration = declaration; } else { declaration_t *iter = symbol->declaration; - for( ; iter != NULL; iter = iter->next) { - declaration_t *next = iter->next; - if(next == NULL) { - iter->next = declaration; - assert(declaration->next == NULL); + for( ; iter != NULL; iter = iter->symbol_next) { + declaration_t *symbol_next = iter->symbol_next; + if(symbol_next == NULL) { + iter->symbol_next = declaration; + assert(declaration->symbol_next == NULL); break; } - if(next->namespace == namespace) { - iter->next = declaration; - declaration->next = next->next; + if(symbol_next->namespace == namespace) { + iter->symbol_next = declaration; + declaration->symbol_next = symbol_next->symbol_next; break; } } @@ -435,17 +435,19 @@ static void environment_pop_to(size_t new_top) assert(declaration != NULL); if(declaration->namespace == namespace) { if(old_declaration == NULL) { - symbol->declaration = declaration->next; + symbol->declaration = declaration->symbol_next; } else { symbol->declaration = old_declaration; - assert(old_declaration->next == declaration->next); + assert(old_declaration->symbol_next == + declaration->symbol_next); } } else { - for( ; declaration != NULL; declaration = declaration->next) { - declaration_t *next = declaration->next; - if(next->namespace == namespace) { - declaration->next = old_declaration; - assert(old_declaration->next == next->next); + for(; declaration != NULL; declaration = declaration->symbol_next) { + declaration_t *symbol_next = declaration->symbol_next; + if(symbol_next->namespace == namespace) { + declaration->symbol_next = old_declaration; + assert(old_declaration->symbol_next + == symbol_next->symbol_next); break; } } @@ -1272,8 +1274,8 @@ static declaration_t *parse_parameters(function_type_t *type) parameter->type = declaration->type; if(last_parameter != NULL) { - last_declaration->context_next = declaration; - last_parameter->next = parameter; + last_declaration->next = declaration; + last_parameter->next = parameter; } else { type->parameters = parameter; declarations = declaration; @@ -1574,7 +1576,7 @@ static declaration_t *record_declaration(declaration_t *declaration) } if(last_declaration != NULL) { - last_declaration->context_next = declaration; + last_declaration->next = declaration; } else { context->declarations = declaration; } @@ -1636,7 +1638,7 @@ static void parse_init_declarators(const declaration_specifiers_t *specifiers) /* push function parameters */ declaration_t *parameter = declaration->context.declarations; - for( ; parameter != NULL; parameter = parameter->context_next) { + for( ; parameter != NULL; parameter = parameter->next) { environment_push(parameter); } @@ -1841,8 +1843,8 @@ static declaration_t *create_implicit_function(symbol_t *symbol, context = global_context; environment_push(declaration); - declaration->context_next = context->declarations; - context->declarations = declaration; + declaration->next = context->declarations; + context->declarations = declaration; context = last_context; @@ -2386,49 +2388,76 @@ static expression_t *parse_extension(unsigned precedence) return parse_sub_expression(precedence); } -#define CREATE_UNARY_EXPRESSION_PARSER(token_type, unexpression_type) \ -static \ -expression_t *parse_##unexpression_type(unsigned precedence) \ -{ \ - eat(token_type); \ - \ - unary_expression_t *unary_expression \ - = allocate_ast_zero(sizeof(unary_expression[0])); \ - unary_expression->expression.type = EXPR_UNARY; \ - unary_expression->type = unexpression_type; \ - unary_expression->value = parse_sub_expression(precedence); \ - \ - return (expression_t*) unary_expression; \ -} - -CREATE_UNARY_EXPRESSION_PARSER('-', UNEXPR_NEGATE) -CREATE_UNARY_EXPRESSION_PARSER('+', UNEXPR_PLUS) -CREATE_UNARY_EXPRESSION_PARSER('!', UNEXPR_NOT) -CREATE_UNARY_EXPRESSION_PARSER('*', UNEXPR_DEREFERENCE) -CREATE_UNARY_EXPRESSION_PARSER('&', UNEXPR_TAKE_ADDRESS) -CREATE_UNARY_EXPRESSION_PARSER('~', UNEXPR_BITWISE_NEGATE) -CREATE_UNARY_EXPRESSION_PARSER(T_PLUSPLUS, UNEXPR_PREFIX_INCREMENT) -CREATE_UNARY_EXPRESSION_PARSER(T_MINUSMINUS, UNEXPR_PREFIX_DECREMENT) - -#define CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(token_type, unexpression_type) \ -static \ -expression_t *parse_##unexpression_type(unsigned precedence, \ - expression_t *left) \ +static type_t *get_unexpr_arithmetic_type(const expression_t *expression) +{ + /* TODO */ + return expression->datatype; +} + +static type_t *get_unexpr_dereference_type(const expression_t *expression) +{ + (void) expression; + /* TODO... */ + return NULL; +} + +static type_t *get_unexpr_take_addr_type(const expression_t *expression) +{ + type_t *type = expression->datatype; + return make_pointer_type(type, 0); +} + +#define CREATE_UNARY_EXPRESSION_PARSER(token_type, unexpression_type, tfunc) \ +static expression_t *parse_##unexpression_type(unsigned precedence) \ +{ \ + eat(token_type); \ + \ + unary_expression_t *unary_expression \ + = allocate_ast_zero(sizeof(unary_expression[0])); \ + unary_expression->expression.type = EXPR_UNARY; \ + unary_expression->type = unexpression_type; \ + unary_expression->value = parse_sub_expression(precedence); \ + unary_expression->expression.datatype = tfunc(unary_expression->value); \ + \ + return (expression_t*) unary_expression; \ +} + +CREATE_UNARY_EXPRESSION_PARSER('-', UNEXPR_NEGATE, get_unexpr_arithmetic_type) +CREATE_UNARY_EXPRESSION_PARSER('+', UNEXPR_PLUS, get_unexpr_arithmetic_type) +CREATE_UNARY_EXPRESSION_PARSER('!', UNEXPR_NOT, get_unexpr_arithmetic_type) +CREATE_UNARY_EXPRESSION_PARSER('*', UNEXPR_DEREFERENCE, + get_unexpr_dereference_type) +CREATE_UNARY_EXPRESSION_PARSER('&', UNEXPR_TAKE_ADDRESS, + get_unexpr_take_addr_type) +CREATE_UNARY_EXPRESSION_PARSER('~', UNEXPR_BITWISE_NEGATE, + get_unexpr_arithmetic_type) +CREATE_UNARY_EXPRESSION_PARSER(T_PLUSPLUS, UNEXPR_PREFIX_INCREMENT, + get_unexpr_arithmetic_type) +CREATE_UNARY_EXPRESSION_PARSER(T_MINUSMINUS, UNEXPR_PREFIX_DECREMENT, + get_unexpr_arithmetic_type) + +#define CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(token_type, unexpression_type, \ + tfunc) \ +static expression_t *parse_##unexpression_type(unsigned precedence, \ + expression_t *left) \ { \ (void) precedence; \ eat(token_type); \ \ unary_expression_t *unary_expression \ = allocate_ast_zero(sizeof(unary_expression[0])); \ - unary_expression->expression.type = EXPR_UNARY; \ - unary_expression->type = unexpression_type; \ - unary_expression->value = left; \ + unary_expression->expression.type = EXPR_UNARY; \ + unary_expression->type = unexpression_type; \ + unary_expression->value = left; \ + unary_expression->expression.datatype = tfunc(left); \ \ return (expression_t*) unary_expression; \ } -CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(T_PLUSPLUS, UNEXPR_POSTFIX_INCREMENT) -CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(T_MINUSMINUS, UNEXPR_POSTFIX_DECREMENT) +CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(T_PLUSPLUS, UNEXPR_POSTFIX_INCREMENT, + get_unexpr_arithmetic_type) +CREATE_UNARY_POSTFIX_EXPRESSION_PARSER(T_MINUSMINUS, UNEXPR_POSTFIX_DECREMENT, + get_unexpr_arithmetic_type) #define CREATE_BINEXPR_PARSER(token_type, binexpression_type) \ static \ @@ -2850,7 +2879,7 @@ static statement_t *parse_declaration_statement(void) if(before == NULL) { statement->declarations_begin = context->declarations; } else { - statement->declarations_begin = before->context_next; + statement->declarations_begin = before->next; } statement->declarations_end = last_declaration; diff --git a/type.c b/type.c index 3531655..7ac4db7 100644 --- a/type.c +++ b/type.c @@ -110,7 +110,7 @@ static void print_function_type_post(const function_type_t *type, } } else { declaration_t *parameter = context->declarations; - for( ; parameter != NULL; parameter = parameter->context_next) { + for( ; parameter != NULL; parameter = parameter->next) { if(first) { first = 0; } else { @@ -166,9 +166,9 @@ void print_enum_definition(const declaration_t *declaration) change_indent(1); - declaration_t *entry = declaration->context_next; + declaration_t *entry = declaration->next; for( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY; - entry = entry->context_next) { + entry = entry->next) { print_indent(); fprintf(out, "%s", entry->symbol->string); @@ -204,7 +204,7 @@ void print_compound_definition(const declaration_t *declaration) change_indent(1); declaration_t *iter = declaration->context.declarations; - for( ; iter != NULL; iter = iter->context_next) { + for( ; iter != NULL; iter = iter->next) { print_indent(); print_declaration(iter); fputc('\n', out); diff --git a/write_fluffy.c b/write_fluffy.c index 78a41fe..986a37d 100644 --- a/write_fluffy.c +++ b/write_fluffy.c @@ -246,7 +246,7 @@ static void write_enum(const symbol_t *symbol, const enum_type_t *type) { fprintf(out, "enum %s:\n", symbol->string); - declaration_t *entry = type->declaration->context_next; + declaration_t *entry = type->declaration->next; for ( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY; entry = entry->next) { fprintf(out, "\t%s", entry->symbol->string); -- 2.20.1