From 14d4977e2ab2409bb7344395ca01d19e49f130f1 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 11 Jul 2026 22:33:03 +0200 Subject: Implement record extension --- gcc/gcc/elna-generic.cc | 119 +++++------------------------------------------- 1 file changed, 11 insertions(+), 108 deletions(-) (limited to 'gcc') diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index 9c8990b..497bcc6 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -46,86 +46,29 @@ namespace elna::gcc vec *argument_trees = nullptr; tree symbol_type = TREE_TYPE(TREE_TYPE(procedure_address)); - tree current_parameter = TYPE_ARG_TYPES(symbol_type); - vec_alloc(argument_trees, arguments.size()); for (boot::expression *const argument : arguments) { - location_t argument_location = get_location(&argument->position()); - if (VOID_TYPE_P(TREE_VALUE(current_parameter))) - { - error_at(argument_location, "Too many arguments, expected %i, got %lu", - list_length(TYPE_ARG_TYPES(symbol_type)) - 1, arguments.size()); - this->current_expression = error_mark_node; - break; - } argument->accept(this); this->current_expression = prepare_rvalue(this->current_expression); - if (!is_assignable_from(TREE_VALUE(current_parameter), this->current_expression)) - { - error_at(argument_location, - "Cannot assign value of type '%s' to variable of type '%s'", - print_type(TREE_TYPE(this->current_expression)).c_str(), - print_type(TREE_VALUE(current_parameter)).c_str()); - this->current_expression = error_mark_node; - } - current_parameter = TREE_CHAIN(current_parameter); argument_trees->quick_push(this->current_expression); } - tree stmt = fold_build_call_array_loc(call_location, TREE_TYPE(symbol_type), + this->current_expression = fold_build_call_array_loc(call_location, TREE_TYPE(symbol_type), procedure_address, vec_safe_length(argument_trees), vec_safe_address(argument_trees)); - - if (!VOID_TYPE_P(TREE_VALUE(current_parameter))) - { - error_at(call_location, "Too few arguments, expected %i, got %lu", - list_length(TYPE_ARG_TYPES(symbol_type)) - 1, arguments.size()); - this->current_expression = error_mark_node; - } - else - { - this->current_expression = stmt; - } } - void generic_visitor::build_record_call(location_t call_location, - tree symbol, const std::vector& arguments) + void generic_visitor::build_record_call(location_t, tree symbol, + const std::vector& arguments) { vec *tree_arguments = nullptr; tree record_fields = TYPE_FIELDS(symbol); for (boot::expression *const argument : arguments) { - location_t argument_location = get_location(&argument->position()); - - if (is_void_type(record_fields)) - { - error_at(argument_location, "Too many arguments, expected %i, got %lu", - list_length(TYPE_FIELDS(symbol)), arguments.size()); - this->current_expression = error_mark_node; - break; - } argument->accept(this); - tree unqualified_field = get_qualified_type(TREE_TYPE(record_fields), TYPE_UNQUALIFIED); - if (!is_assignable_from(unqualified_field, this->current_expression)) - { - error_at(argument_location, - "Cannot assign value of type '%s' to variable of type '%s'", - print_type(TREE_TYPE(this->current_expression)).c_str(), - print_type(TREE_TYPE(record_fields)).c_str()); - this->current_expression = error_mark_node; - } CONSTRUCTOR_APPEND_ELT(tree_arguments, record_fields, this->current_expression); record_fields = TREE_CHAIN(record_fields); } - if (!is_void_type(record_fields)) - { - error_at(call_location, "Too few arguments, expected %i, got %lu", - list_length(TYPE_FIELDS(symbol)), arguments.size()); - this->current_expression = error_mark_node; - } - else - { - this->current_expression = build_constructor(symbol, tree_arguments); - } + this->current_expression = build_constructor(symbol, tree_arguments); } void generic_visitor::build_assert_builtin(location_t call_location, @@ -217,7 +160,7 @@ namespace elna::gcc void generic_visitor::visit(boot::cast_expression *expression) { - tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope()); + tree cast_target = get_inner_alias(expression->type_decoration, this->symbols->scope()); expression->value().accept(this); tree cast_source = TREE_TYPE(this->current_expression); @@ -746,16 +689,7 @@ namespace elna::gcc if (declaration->initializer != nullptr) { declaration->initializer->accept(this); - if (is_assignable_from(TREE_TYPE(declaration_tree), this->current_expression)) - { - DECL_INITIAL(declaration_tree) = this->current_expression; - } - else - { - error_at(declaration_location, "Cannot initialize variable of type '%s' with a value of type '%s'", - print_type(TREE_TYPE(declaration_tree)).c_str(), - print_type(TREE_TYPE(this->current_expression)).c_str()); - } + DECL_INITIAL(declaration_tree) = this->current_expression; } else if (!declaration->is_extern && POINTER_TYPE_P(TREE_TYPE(declaration_tree))) { @@ -1027,18 +961,12 @@ namespace elna::gcc error_at(statement_location, "Cannot modify a constant expression of type '%s'", print_type(TREE_TYPE(lvalue)).c_str()); } - else if (is_assignable_from(TREE_TYPE(lvalue), rvalue)) + else { tree assignment = build2_loc(statement_location, MODIFY_EXPR, void_type_node, lvalue, rvalue); append_statement(assignment); } - else - { - error_at(statement_location, "Cannot assign value of type '%s' to variable of type '%s'", - print_type(TREE_TYPE(rvalue)).c_str(), - print_type(TREE_TYPE(lvalue)).c_str()); - } this->current_expression = NULL_TREE; } @@ -1143,7 +1071,6 @@ namespace elna::gcc boot::expression *return_expression = &statement->return_expression(); location_t statement_position = get_location(&statement->position()); tree set_result{ NULL_TREE }; - tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl)); if (TREE_THIS_VOLATILE(current_function_decl) == 1) { @@ -1157,26 +1084,9 @@ namespace elna::gcc set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(current_function_decl), this->current_expression); } - if (return_type == void_type_node && set_result != NULL_TREE) - { - error_at(statement_position, "Proper procedure is not allowed to return a value"); - } - else if (return_type != void_type_node && set_result == NULL_TREE) - { - error_at(statement_position, "Procedure is expected to return a value of type '%s'", - print_type(return_type).c_str()); - } - else if (return_type != void_type_node && !is_assignable_from(return_type, this->current_expression)) - { - error_at(statement_position, "Cannot return '%s' from a procedure returning '%s'", - print_type(return_type).c_str(), - print_type(TREE_TYPE(this->current_expression)).c_str()); - } - else - { - tree return_stmt = build1_loc(statement_position, RETURN_EXPR, void_type_node, set_result); - append_statement(return_stmt); - } + tree return_stmt = build1_loc(statement_position, RETURN_EXPR, void_type_node, set_result); + append_statement(return_stmt); + this->current_expression = NULL_TREE; } @@ -1215,14 +1125,7 @@ namespace elna::gcc case_label->accept(this); location_t case_location = get_location(&case_label->position()); - if (assert_constant(case_location) - && !is_assignable_from(unqualified_condition, this->current_expression)) - { - error_at(case_location, "Case type '%s' does not match the expression type '%s'", - print_type(TREE_TYPE(this->current_expression)).c_str(), - print_type(unqualified_condition).c_str()); - this->current_expression = error_mark_node; - } + assert_constant(case_location); tree case_label_declaration = create_artificial_label(case_location); tree case_expression = build_case_label(this->current_expression, NULL_TREE, case_label_declaration); -- cgit v1.2.3