diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/gcc/elna-builtins.cc | 6 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 150 | ||||
| -rw-r--r-- | gcc/gcc/elna-tree.cc | 7 |
3 files changed, 76 insertions, 87 deletions
diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc index 42ddcfe..9e331cf 100644 --- a/gcc/gcc/elna-builtins.cc +++ b/gcc/gcc/elna-builtins.cc @@ -40,7 +40,7 @@ namespace elna::gcc elna_pointer_nil_node = null_pointer_node; elna_string_type_node = make_node(RECORD_TYPE); - tree string_ptr_type = build_pointer_type_for_mode(elna_char_type_node, VOIDmode, true); + tree string_ptr_type = build_pointer_type(elna_char_type_node); elna_string_length_field_node = build_field(UNKNOWN_LOCATION, elna_string_type_node, "length", build_qualified_type(elna_word_type_node, TYPE_QUAL_CONST)); @@ -146,7 +146,7 @@ namespace elna::gcc } else if (auto reference = type.get<boot::pointer_type>()) { - return build_global_pointer_type(get_inner_alias(reference->base, symbols)); + return build_pointer_type(get_inner_alias(reference->base, symbols)); } else if (auto reference = type.get<boot::array_type>()) { @@ -158,7 +158,7 @@ namespace elna::gcc { auto procedure = build_procedure_type(*reference, symbols); - return build_global_pointer_type(procedure); + return build_pointer_type(procedure); } else if (auto reference = type.get<boot::alias_type>()) { diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index aace38b..4067bb6 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -143,7 +143,7 @@ namespace elna::gcc else if (TREE_CODE(expression_type) == FUNCTION_TYPE) { this->current_expression = build1(ADDR_EXPR, - build_global_pointer_type(expression_type), this->current_expression); + build_pointer_type(expression_type), this->current_expression); build_procedure_call(call_location, this->current_expression, call->arguments); } else if (POINTER_TYPE_P(expression_type) && TREE_CODE(TREE_TYPE(expression_type)) == FUNCTION_TYPE) @@ -167,7 +167,7 @@ namespace elna::gcc if (is_castable_type(cast_target) && (is_castable_type(cast_source))) { - this->current_expression = build1_loc(get_location(&expression->position()), CONVERT_EXPR, + this->current_expression = fold_convert_loc(get_location(&expression->position()), cast_target, this->current_expression); } else @@ -244,7 +244,7 @@ namespace elna::gcc { tree declaration_type = build_function_type_list(elna_int_type_node, elna_int_type_node, - build_global_pointer_type(build_global_pointer_type(elna_char_type_node)), + build_pointer_type(build_pointer_type(elna_char_type_node)), NULL_TREE); tree fndecl = build_fn_decl("main", declaration_type); @@ -659,39 +659,48 @@ namespace elna::gcc TREE_ADDRESSABLE(this->current_expression) = 1; this->current_expression = build_fold_addr_expr_with_type_loc(location, this->current_expression, - build_global_pointer_type(TREE_TYPE(this->current_expression))); + build_pointer_type(TREE_TYPE(this->current_expression))); TREE_NO_TRAMPOLINE(this->current_expression) = 1; break; case boot::unary_operator::negation: - if (TREE_TYPE(this->current_expression) == elna_bool_type_node) + { + tree operand_type = TREE_TYPE(this->current_expression); + + if (operand_type == elna_bool_type_node) { this->current_expression = build1_loc(location, TRUTH_NOT_EXPR, boolean_type_node, this->current_expression); } - else if (is_integral_type(TREE_TYPE(this->current_expression))) + else if (is_integral_type(operand_type)) { this->current_expression = build1_loc(location, BIT_NOT_EXPR, - TREE_TYPE(this->current_expression), this->current_expression); + operand_type, this->current_expression); } else { error_at(location, "type '%s' cannot be negated", - print_type(TREE_TYPE(this->current_expression)).c_str()); + print_type(operand_type).c_str()); this->current_expression = error_mark_node; } break; + } case boot::unary_operator::minus: - if (is_integral_type(TREE_TYPE(this->current_expression))) + { + tree operand_type = TREE_TYPE(this->current_expression); + + if (is_integral_type(operand_type)) { - this->current_expression = fold_build1(NEGATE_EXPR, TREE_TYPE(this->current_expression), - this->current_expression); + this->current_expression = fold_build1_loc(location, NEGATE_EXPR, + operand_type, this->current_expression); } else { error_at(location, "type '%s' cannot be negated", - print_type(TREE_TYPE(this->current_expression)).c_str()); + print_type(operand_type).c_str()); this->current_expression = error_mark_node; } + break; + } } } @@ -818,8 +827,7 @@ namespace elna::gcc tree target_pointer = do_pointer_arithmetic(boot::binary_operator::sum, string_ptr, offset, location); - this->current_expression = build1_loc(location, INDIRECT_REF, - elna_char_type_node, target_pointer); + this->current_expression = build_simple_mem_ref_loc(location, target_pointer); } else { @@ -843,22 +851,6 @@ namespace elna::gcc return this->current_expression != error_mark_node; } - bool generic_visitor::expect_trait_for_integral_type(boot::traits_expression *trait) - { - if (!expect_trait_type_only(trait)) - { - return false; - } - else if (!is_integral_type(this->current_expression) && TREE_CODE(this->current_expression) != ENUMERAL_TYPE) - { - error_at(get_location(&trait->position()), "Type '%s' does not support trait '%s'", - print_type(this->current_expression).c_str(), trait->name.name().c_str()); - this->current_expression = error_mark_node; - return false; - } - return true; - } - void generic_visitor::visit(boot::traits_expression *trait) { location_t trait_location = get_location(&trait->position()); @@ -867,7 +859,7 @@ namespace elna::gcc { if (expect_trait_type_only(trait)) { - this->current_expression = build1_loc(trait_location, CONVERT_EXPR, elna_word_type_node, + this->current_expression = fold_convert_loc(trait_location, elna_word_type_node, size_in_bytes(this->current_expression)); } } @@ -881,14 +873,14 @@ namespace elna::gcc } else if (trait->name == "min") { - if (expect_trait_for_integral_type(trait)) + if (expect_trait_type_only(trait)) { this->current_expression = TYPE_MIN_VALUE(this->current_expression); } } else if (trait->name == "max") { - if (expect_trait_for_integral_type(trait)) + if (expect_trait_type_only(trait)) { this->current_expression = TYPE_MAX_VALUE(this->current_expression); } @@ -917,7 +909,7 @@ namespace elna::gcc if (field_declaration != error_mark_node) { - this->current_expression = build1(CONVERT_EXPR, elna_word_type_node, + this->current_expression = fold_convert_loc(trait_location, elna_word_type_node, byte_position(field_declaration)); } else @@ -944,7 +936,7 @@ namespace elna::gcc } else if (TREE_CODE(aggregate_type) == ARRAY_TYPE && expression->field() == "ptr") { - tree ptr_type = build_global_pointer_type(TREE_TYPE(aggregate_type)); + tree ptr_type = build_pointer_type(TREE_TYPE(aggregate_type)); this->current_expression = build1(ADDR_EXPR, build_qualified_type(ptr_type, TYPE_QUAL_CONST), this->current_expression); } @@ -984,8 +976,8 @@ namespace elna::gcc if (POINTER_TYPE_P(expression_type)) { - this->current_expression = build1_loc(expression_location, INDIRECT_REF, - TREE_TYPE(expression_type), this->current_expression); + this->current_expression = build_simple_mem_ref_loc(expression_location, + this->current_expression); } else { @@ -1026,28 +1018,31 @@ namespace elna::gcc void generic_visitor::visit(boot::if_statement *statement) { - tree endif_label_decl = create_artificial_label(UNKNOWN_LOCATION); - tree goto_endif = build1(GOTO_EXPR, void_type_node, endif_label_decl); + tree result = NULL_TREE; - make_if_branch(statement->branch(), goto_endif); - - for (const auto branch : statement->branches) - { - make_if_branch(*branch, goto_endif); - } if (statement->alternative != nullptr) { enter_scope(); visit_statements(*statement->alternative); - tree mapping = leave_scope(); - append_statement(mapping); + result = leave_scope(); + } + + auto& branches = statement->branches; + for (auto it = branches.rbegin(); it != branches.rend(); ++it) + { + result = make_if_branch(**it, result); + } + result = make_if_branch(statement->branch(), result); + + if (result != error_mark_node) + { + append_statement(result); } - tree endif_label_expr = build1(LABEL_EXPR, void_type_node, endif_label_decl); - append_statement(endif_label_expr); this->current_expression = NULL_TREE; } - void generic_visitor::make_if_branch(boot::conditional_statements& branch, tree goto_endif) + tree generic_visitor::make_if_branch(boot::conditional_statements& branch, tree next, + tree goto_append) { branch.prerequisite().accept(this); @@ -1057,28 +1052,19 @@ namespace elna::gcc "Expected expression of boolean type but its type is %s", print_type(TREE_TYPE(this->current_expression)).c_str()); this->current_expression = error_mark_node; - return; + return error_mark_node; } - tree then_label_decl = build_label_decl("then", UNKNOWN_LOCATION); - tree goto_then = build1(GOTO_EXPR, void_type_node, then_label_decl); + tree condition = this->current_expression; - tree else_label_decl = build_label_decl("else", UNKNOWN_LOCATION); - tree goto_else = build1(GOTO_EXPR, void_type_node, else_label_decl); - - auto cond_expr = build3(COND_EXPR, void_type_node, this->current_expression, goto_then, goto_else); - append_statement(cond_expr); - - tree then_label_expr = build1(LABEL_EXPR, void_type_node, then_label_decl); - append_statement(then_label_expr); enter_scope(); - visit_statements(branch.statements); - tree mapping = leave_scope(); - append_statement(mapping); - append_statement(goto_endif); + if (goto_append != NULL_TREE) + { + append_statement(goto_append); + } + tree then_body = leave_scope(); - tree else_label_expr = build1(LABEL_EXPR, void_type_node, else_label_decl); - append_statement(else_label_expr); + return build3(COND_EXPR, void_type_node, condition, then_body, next); } void generic_visitor::visit(boot::import_declaration *) @@ -1088,21 +1074,29 @@ namespace elna::gcc void generic_visitor::visit(boot::while_statement *statement) { location_t prerequisite_location = get_location(&statement->branch().prerequisite().position()); - tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location); - auto prerequisite_label_expr = build1_loc(prerequisite_location, LABEL_EXPR, - void_type_node, prerequisite_label_decl); - auto goto_check = build1(GOTO_EXPR, void_type_node, prerequisite_label_decl); - tree branch_end_declaration = build_label_decl("while_end", UNKNOWN_LOCATION); - tree branch_end_expression = build1_loc(UNKNOWN_LOCATION, LABEL_EXPR, void_type_node, branch_end_declaration); + tree while_check_label = build_label_decl("while_do", prerequisite_location); + tree while_end_label = build_label_decl("while_end", UNKNOWN_LOCATION); + tree goto_check = build1(GOTO_EXPR, void_type_node, while_check_label); - append_statement(prerequisite_label_expr); - make_if_branch(statement->branch(), goto_check); + tree result = NULL_TREE; - for (const auto branch : statement->branches) + auto& branches = statement->branches; + for (auto it = branches.rbegin(); it != branches.rend(); ++it) { - make_if_branch(*branch, goto_check); + result = make_if_branch(**it, result, goto_check); + } + result = make_if_branch(statement->branch(), result, goto_check); + + if (result != error_mark_node) + { + tree check_label_expr = build1_loc(prerequisite_location, LABEL_EXPR, + void_type_node, while_check_label); + tree end_label_expr = build1(LABEL_EXPR, void_type_node, while_end_label); + + append_statement(check_label_expr); + append_statement(result); + append_statement(end_label_expr); } - append_statement(branch_end_expression); this->current_expression = NULL_TREE; } diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index ebe6a56..0227433 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -66,7 +66,7 @@ namespace elna::gcc { if (DECL_P(rvalue) && TREE_CODE(TREE_TYPE(rvalue)) == FUNCTION_TYPE) { - return build1(ADDR_EXPR, build_pointer_type_for_mode(TREE_TYPE(rvalue), VOIDmode, true), rvalue); + return build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(rvalue)), rvalue); } else { @@ -241,11 +241,6 @@ namespace elna::gcc return field_declaration; } - tree build_global_pointer_type(tree type) - { - return build_pointer_type_for_mode(type, VOIDmode, true); - } - tree build_static_array_type(tree type, const std::uint64_t size) { tree upper_bound = build_int_cst_type(integer_type_node, size); |
