aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-11 22:33:03 +0200
committerEugen Wissner <belka@caraus.de>2026-07-11 22:33:03 +0200
commit14d4977e2ab2409bb7344395ca01d19e49f130f1 (patch)
tree5e08f1356a970b53f16ee554642eb555550d1491 /gcc
parentb7dd49c1d5832ac7d82edba27316884ab53e614c (diff)
downloadelna-14d4977e2ab2409bb7344395ca01d19e49f130f1.tar.gz
Implement record extension
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/elna-generic.cc119
1 files changed, 11 insertions, 108 deletions
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<tree, va_gc> *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<boot::expression *>& arguments)
+ void generic_visitor::build_record_call(location_t, tree symbol,
+ const std::vector<boot::expression *>& arguments)
{
vec<constructor_elt, va_gc> *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);