From dea1c177cd3592cc24fd15ad446a676da2e4da28 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 25 Jul 2026 23:33:22 +0200 Subject: Support #offset trait at compile time --- gcc/gcc/elna-builtins.cc | 82 ++++++++---- gcc/gcc/elna-diagnostic.cc | 6 +- gcc/gcc/elna-generic.cc | 321 +++++++++++++++++++++++---------------------- gcc/gcc/elna-tree.cc | 41 ++++-- gcc/gcc/elna1.cc | 27 +--- 5 files changed, 257 insertions(+), 220 deletions(-) (limited to 'gcc') diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc index 6ea8874..226de4a 100644 --- a/gcc/gcc/elna-builtins.cc +++ b/gcc/gcc/elna-builtins.cc @@ -15,8 +15,6 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ -#include - #include "elna/gcc/elna-builtins.h" #include "elna/gcc/elna1.h" #include "stor-layout.h" @@ -41,7 +39,7 @@ namespace elna::gcc } static - tree declare_builtin_type(std::shared_ptr symbol_table, const char *name, tree type) + tree declare_builtin_type(const std::shared_ptr& symbol_table, const char *name, tree type) { tree identifier = get_identifier(name); tree type_declaration = build_decl(UNKNOWN_LOCATION, TYPE_DECL, identifier, type); @@ -65,21 +63,44 @@ namespace elna::gcc return builtin_table; } - tree build_composite_type(const boot::ordered_map& fields, - tree composite_type_node, std::shared_ptr symbols) + static tree build_composite_type(const boot::ordered_map& fields, + tree composite_type_node, const std::shared_ptr& symbols) { - for (auto& field : fields) + for (const auto& field : fields) { tree rewritten_field = get_inner_alias(field.second, symbols); tree field_declaration = build_field(UNKNOWN_LOCATION, composite_type_node, field.first, rewritten_field); TYPE_FIELDS(composite_type_node) = chainon(TYPE_FIELDS(composite_type_node), field_declaration); } - layout_type(composite_type_node); return composite_type_node; } - tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr symbols) + static bool layout_record_type(tree record_type, const std::shared_ptr& subject) + { + layout_type(record_type); + const auto& target = get_host_target(); + auto record_layout = boot::layout_record(subject, target); + + if (!record_layout.has_value()) + { + return false; + } + for (tree field = TYPE_FIELDS(record_type); field != NULL_TREE; field = TREE_CHAIN(field)) + { + std::string field_name(IDENTIFIER_POINTER(DECL_NAME(field))); + + DECL_FIELD_OFFSET(field) = size_int(record_layout.value().offset_map.find(field_name)->second); + DECL_FIELD_BIT_OFFSET(field) = bitsize_zero_node; + } + TYPE_SIZE_UNIT(record_type) = size_int(record_layout.value().size); + TYPE_SIZE(record_type) = bitsize_int(record_layout.value().size * BITS_PER_UNIT); + + return true; + } + + static tree build_procedure_type(const boot::procedure_type& procedure, + const std::shared_ptr& symbols) { std::vector parameter_types(procedure.parameters.size()); @@ -93,14 +114,15 @@ namespace elna::gcc { return_type = get_inner_alias(procedure.return_type.proper_type, symbols); } - return build_function_type_array(return_type, procedure.parameters.size(), parameter_types.data()); + return build_function_type_array(return_type, + static_cast(procedure.parameters.size()), parameter_types.data()); } - tree get_inner_alias(const boot::type& type, std::shared_ptr symbols) + tree get_inner_alias(const boot::type& type, const std::shared_ptr& symbols) { if (auto reference = type.get()) { - auto looked_up = symbols->lookup(reference->identifier); + tree looked_up = symbols->lookup(reference->identifier); gcc_assert(looked_up != NULL_TREE); return TREE_TYPE(looked_up); @@ -122,7 +144,10 @@ namespace elna::gcc } } build_composite_type(reference->fields, composite_type_node, symbols); - + if (!layout_record_type(composite_type_node, reference)) + { + return error_mark_node; + } return composite_type_node; } else if (auto reference = type.get()) @@ -154,7 +179,7 @@ namespace elna::gcc } else if (auto reference = type.get()) { - auto procedure = build_procedure_type(*reference, symbols); + tree procedure = build_procedure_type(*reference, symbols); return build_pointer_type(procedure); } @@ -170,14 +195,19 @@ namespace elna::gcc return error_mark_node; } - tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference, - std::shared_ptr symbols) + tree handle_symbol(const std::string& symbol_name, + const std::shared_ptr& reference, + const std::shared_ptr& symbols) { tree looked_up = symbols->lookup(symbol_name); if (looked_up == NULL_TREE) { tree type_tree = get_inner_alias(reference->referent, symbols); + if (type_tree == error_mark_node) + { + return error_mark_node; + } looked_up = build_decl(UNKNOWN_LOCATION, TYPE_DECL, get_identifier(symbol_name.c_str()), type_tree); @@ -197,7 +227,7 @@ namespace elna::gcc } void declare_procedure(const std::string& name, const boot::procedure_info& info, - std::shared_ptr symbols) + const std::shared_ptr& symbols) { tree declaration_type = gcc::build_procedure_type(info.symbol, symbols); tree fndecl = build_fn_decl(name.c_str(), declaration_type); @@ -230,37 +260,39 @@ namespace elna::gcc } DECL_ARGUMENTS(fndecl) = argument_chain; TREE_ADDRESSABLE(fndecl) = 1; - DECL_EXTERNAL(fndecl) = info.is_extern(); - TREE_PUBLIC(fndecl) = info.exported; + DECL_EXTERNAL(fndecl) = static_cast(info.is_extern()); + TREE_PUBLIC(fndecl) = static_cast(info.exported); } tree declare_variable(const std::string& name, const boot::variable_info& info, - std::shared_ptr symbols) + const std::shared_ptr& symbols) { - auto *variable_type = get_inner_alias(info.symbol, symbols); + tree variable_type = get_inner_alias(info.symbol, symbols); tree declaration_tree = build_decl(UNKNOWN_LOCATION, VAR_DECL, get_identifier(name.c_str()), variable_type); TREE_ADDRESSABLE(declaration_tree) = 1; - DECL_EXTERNAL(declaration_tree) = info.is_extern; - TREE_PUBLIC(declaration_tree) = info.exported; + DECL_EXTERNAL(declaration_tree) = static_cast(info.is_extern); + TREE_PUBLIC(declaration_tree) = static_cast(info.exported); symbols->enter(name, declaration_tree); return declaration_tree; } - void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr symbols) + static void declare_type(const std::string& name, + const boot::type_info& info, const std::shared_ptr& symbols) { // The top level symbol table has basic (builtin) types in it which are not aliases. if (auto alias_type = info.symbol.get()) { tree type_declaration = handle_symbol(name, alias_type, symbols); - TREE_PUBLIC(type_declaration) = info.exported; + TREE_PUBLIC(type_declaration) = static_cast(info.exported); } } - void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols) + void rewrite_symbol_table(const std::shared_ptr& info_table, + const std::shared_ptr& symbols) { for (auto& [symbol_name, symbol_info] : *info_table) { diff --git a/gcc/gcc/elna-diagnostic.cc b/gcc/gcc/elna-diagnostic.cc index 630db0c..3dcdb98 100644 --- a/gcc/gcc/elna-diagnostic.cc +++ b/gcc/gcc/elna-diagnostic.cc @@ -26,7 +26,7 @@ namespace elna::gcc linemap_add(line_table, LC_ENTER, 0, filename, 1); } - linemap_guard::linemap_guard(const std::filesystem::path filename) + linemap_guard::linemap_guard(const std::filesystem::path& filename) { const char *filename_pointer = ggc_strdup(filename.native().c_str()); @@ -35,7 +35,7 @@ namespace elna::gcc linemap_guard::~linemap_guard() { - linemap_add(line_table, LC_LEAVE, 0, NULL, 0); + linemap_add(line_table, LC_LEAVE, 0, nullptr, 0); } location_t get_location(const boot::source_position *position) @@ -65,7 +65,7 @@ namespace elna::gcc return make_location(caret, start, end); } - std::string print_aggregate_name(tree type, const std::string& kind_name) + static std::string print_aggregate_name(tree type, const std::string& kind_name) { if (TYPE_IDENTIFIER(type) == NULL_TREE) { diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index 43739fb..7491372 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -36,9 +36,9 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { - generic_visitor::generic_visitor(std::shared_ptr symbol_table, + generic_visitor::generic_visitor(const std::shared_ptr& symbol_table, boot::symbol_bag bag, const boot::target_info& target) - : bag(bag), symbols(symbol_table), target(target) + : bag(std::move(bag)), symbols(symbol_table), target(target) , const_evaluator(std::make_unique(this->bag, this->target, this->evaluated_initializers)) { @@ -58,7 +58,8 @@ namespace elna::gcc argument_trees->quick_push(this->current_expression); } 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)); + procedure_address, static_cast(vec_safe_length(argument_trees)), + vec_safe_address(argument_trees)); } void generic_visitor::build_assert_builtin(location_t call_location, @@ -343,6 +344,94 @@ namespace elna::gcc finish_function(fndecl); } + tree generic_visitor::build_equality(boot::binary_expression *expression, tree left, tree right) + { + tree_code equality_code; + + if (expression->operation() == boot::binary_operator::equals) + { + equality_code = EQ_EXPR; + } + else if (expression->operation() == boot::binary_operator::not_equals) + { + equality_code = NE_EXPR; + } + else + { + gcc_unreachable(); + } + return build_equality_comparison(get_location(&expression->position()), left, right, + expression->lhs().type_decoration, equality_code); + } + + tree generic_visitor::build_equality_comparison(location_t loc, tree left, tree right, + const boot::type& left_type, tree_code equality_code) + { + tree_code combination_code = equality_code == EQ_EXPR + ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; + + if (left_type.get() != nullptr) + { + tree lhs_ptr_field = TYPE_FIELDS(TREE_TYPE(left)); + tree lhs_length_field = TREE_CHAIN(lhs_ptr_field); + + tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(lhs_length_field), + left, lhs_length_field, NULL_TREE); + tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(lhs_ptr_field), + left, lhs_ptr_field, NULL_TREE); + + tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(lhs_length_field), + right, lhs_length_field, NULL_TREE); + tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(lhs_ptr_field), + right, lhs_ptr_field, NULL_TREE); + + tree element_size = fold_convert(elna_word_type_node, + size_in_bytes(TREE_TYPE(TREE_TYPE(lhs_ptr_field)))); + tree byte_length = build2(MULT_EXPR, elna_word_type_node, lhs_length, element_size); + + tree length_equality = build2(equality_code, elna_bool_type_node, lhs_length, rhs_length); + tree memcmp_call = call_built_in(UNKNOWN_LOCATION, "__builtin_memcmp", integer_type_node, + lhs_ptr, rhs_ptr, byte_length); + tree equals_zero = build2(equality_code, elna_bool_type_node, memcmp_call, integer_zero_node); + + return build2(combination_code, elna_bool_type_node, length_equality, equals_zero); + } + else if (left_type.get() != nullptr + || left_type.get() != nullptr) + { + tree size = fold_convert(elna_word_type_node, + size_in_bytes(TREE_TYPE(left))); + tree lhs_addr = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(left)), left); + tree rhs_addr = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(right)), right); + tree memcmp_call = call_built_in(UNKNOWN_LOCATION, "__builtin_memcmp", + integer_type_node, lhs_addr, rhs_addr, size); + return build2(equality_code, elna_bool_type_node, memcmp_call, integer_zero_node); + } + else + { + return build2_loc(loc, equality_code, elna_bool_type_node, left, right); + } + } + + std::pair generic_visitor::build_loop_head(tree control_variable_declaration, + tree limit, tree_code comparison, location_t check_location) + { + // Put a label in front of the loop condition. + tree check_label = create_artificial_label(check_location); + tree check_statement = build1_loc(check_location, LABEL_EXPR, void_type_node, check_label); + append_statement(check_statement); + + // Build the condition and jump if the condition isn't met. + tree condition = fold_build2(comparison, elna_bool_type_node, control_variable_declaration, limit); + tree end_label = create_artificial_label(UNKNOWN_LOCATION); + tree goto_end = build1(GOTO_EXPR, void_type_node, end_label); + tree condition_statement = build3_loc(check_location, COND_EXPR, void_type_node, + condition, NULL_TREE, goto_end); + append_statement(condition_statement); + + return { check_label, end_label }; + } + void generic_visitor::enter_scope() { this->symbols = std::make_shared(this->symbols); @@ -396,7 +485,7 @@ namespace elna::gcc cgraph_node::finalize_function(fndecl, true); } - static tree constant_to_tree(const boot::constant_value& constant_value) + static tree constant_to_tree(const boot::constant_value& constant_value, tree type = NULL_TREE) { if (std::holds_alternative(constant_value)) { @@ -411,10 +500,12 @@ namespace elna::gcc { auto real_value = std::get(constant_value); REAL_VALUE_TYPE real; - HOST_WIDE_INT target_bits[(sizeof(double) + sizeof(HOST_WIDE_INT) - 1) - / sizeof(HOST_WIDE_INT)]; - std::memcpy(target_bits, &real_value, sizeof(real_value)); - real_from_target(&real, target_bits, REAL_MODE_FORMAT(TYPE_MODE(elna_float_type_node))); + constexpr std::size_t bits_size = (sizeof(double) + sizeof(HOST_WIDE_INT) - 1) / sizeof(HOST_WIDE_INT); + std::array target_bits; + + std::memcpy(target_bits.data(), &real_value, sizeof(real_value)); + real_from_target(&real, target_bits.data(), REAL_MODE_FORMAT(TYPE_MODE(elna_float_type_node))); + return build_real(elna_float_type_node, real); } else if (std::holds_alternative(constant_value)) @@ -431,11 +522,55 @@ namespace elna::gcc } else if (std::holds_alternative>(constant_value)) { - return NULL_TREE; // Compound constants are not lowered to trees yet. + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + if (type == NULL_TREE || !RECORD_OR_UNION_TYPE_P(type)) + { + return NULL_TREE; + } + const auto& aggregate = std::get>(constant_value); + const auto& fields = *aggregate; + vec *tree_arguments = nullptr; + + for (const auto& [field_name, field_value] : fields) + { + tree field_decl = find_field_by_name(UNKNOWN_LOCATION, type, field_name); + if (field_decl == error_mark_node) + { + return NULL_TREE; + } + tree value_tree = constant_to_tree(field_value, TREE_TYPE(field_decl)); + if (value_tree == NULL_TREE) + { + return NULL_TREE; + } + CONSTRUCTOR_APPEND_ELT(tree_arguments, field_decl, value_tree); + } + return build_constructor(type, tree_arguments); } else if (std::holds_alternative>(constant_value)) { - return NULL_TREE; // Compound constants are not lowered to trees yet. + if (type == NULL_TREE || TREE_CODE(type) != ARRAY_TYPE) + { + return NULL_TREE; + } + const auto& aggregate = std::get>(constant_value); + const auto& elements = *aggregate; + tree domain = TYPE_DOMAIN(type); + tree index = TYPE_MIN_VALUE(domain); + tree element_type = TREE_TYPE(type); + vec *tree_arguments = nullptr; + + for (const auto& element : elements) + { + tree element_tree = constant_to_tree(element, element_type); + if (element_tree == NULL_TREE) + { + return NULL_TREE; + } + CONSTRUCTOR_APPEND_ELT(tree_arguments, index, element_tree); + index = int_const_binop(PLUS_EXPR, index, elna_word_one_node); + } + return build_constructor(type, tree_arguments); } return NULL_TREE; } @@ -506,75 +641,6 @@ namespace elna::gcc this->current_expression = build_constructor(slice_type, elms); } - tree generic_visitor::build_equality(boot::binary_expression *expression, tree left, tree right) - { - tree_code equality_code; - - if (expression->operation() == boot::binary_operator::equals) - { - equality_code = EQ_EXPR; - } - else if (expression->operation() == boot::binary_operator::not_equals) - { - equality_code = NE_EXPR; - } - else - { - gcc_unreachable(); - } - return build_equality_comparison(get_location(&expression->position()), left, right, - expression->lhs().type_decoration, equality_code); - } - - tree generic_visitor::build_equality_comparison(location_t loc, tree left, tree right, - const boot::type& left_type, tree_code equality_code) - { - tree_code combination_code = equality_code == EQ_EXPR - ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; - - if (left_type.get() != nullptr) - { - tree lhs_ptr_field = TYPE_FIELDS(TREE_TYPE(left)); - tree lhs_length_field = TREE_CHAIN(lhs_ptr_field); - - tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(lhs_length_field), - left, lhs_length_field, NULL_TREE); - tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(lhs_ptr_field), - left, lhs_ptr_field, NULL_TREE); - - tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(lhs_length_field), - right, lhs_length_field, NULL_TREE); - tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(lhs_ptr_field), - right, lhs_ptr_field, NULL_TREE); - - tree element_size = fold_convert(elna_word_type_node, - size_in_bytes(TREE_TYPE(TREE_TYPE(lhs_ptr_field)))); - tree byte_length = build2(MULT_EXPR, elna_word_type_node, lhs_length, element_size); - - tree length_equality = build2(equality_code, elna_bool_type_node, lhs_length, rhs_length); - tree memcmp_call = call_built_in(UNKNOWN_LOCATION, "__builtin_memcmp", integer_type_node, - lhs_ptr, rhs_ptr, byte_length); - tree equals_zero = build2(equality_code, elna_bool_type_node, memcmp_call, integer_zero_node); - - return build2(combination_code, elna_bool_type_node, length_equality, equals_zero); - } - else if (left_type.get() != nullptr - || left_type.get() != nullptr) - { - tree size = fold_convert(elna_word_type_node, - size_in_bytes(TREE_TYPE(left))); - tree lhs_addr = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(left)), left); - tree rhs_addr = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(right)), right); - tree memcmp_call = call_built_in(UNKNOWN_LOCATION, "__builtin_memcmp", - integer_type_node, lhs_addr, rhs_addr, size); - return build2(equality_code, elna_bool_type_node, memcmp_call, integer_zero_node); - } - else - { - return build2_loc(loc, equality_code, elna_bool_type_node, left, right); - } - } - void generic_visitor::visit(boot::binary_expression *expression) { expression->lhs().accept(this); @@ -746,7 +812,7 @@ namespace elna::gcc boot::evaluator constant_evaluator(this->bag, this->target, evaluated_initializers); if (auto constant_value = constant_evaluator.evaluate(*declaration->initializer)) { - tree folded = constant_to_tree(constant_value.value()); + tree folded = constant_to_tree(constant_value.value(), TREE_TYPE(declaration_tree)); if (folded != NULL_TREE) { initializer_tree = folded; @@ -779,7 +845,8 @@ namespace elna::gcc if (lang_hooks.decls.global_bindings_p()) { - TREE_STATIC(declaration_tree) = !variable_identifier.exported() && !declaration->is_extern; + TREE_STATIC(declaration_tree) = + static_cast(!variable_identifier.exported() && !declaration->is_extern); varpool_node::get_create(declaration_tree); varpool_node::finalize_decl(declaration_tree); } @@ -788,7 +855,7 @@ namespace elna::gcc DECL_CONTEXT(declaration_tree) = current_function_decl; f_binding_level->names = chainon(f_binding_level->names, declaration_tree); - auto *declaration_statement = build1_loc(declaration_location, DECL_EXPR, + tree declaration_statement = build1_loc(declaration_location, DECL_EXPR, void_type_node, declaration_tree); append_statement(declaration_statement); } @@ -797,7 +864,7 @@ namespace elna::gcc void generic_visitor::visit(boot::named_expression *expression) { - auto symbol = this->symbols->lookup(expression->name); + tree symbol = this->symbols->lookup(expression->name); if (symbol == NULL_TREE) { @@ -851,66 +918,27 @@ namespace elna::gcc } } - bool generic_visitor::expect_trait_type_only(boot::traits_expression *trait) - { - if (trait->arguments.size() != 1) - { - error_at(get_location(&trait->position()), "Trait '%s' expects 1 argument, got %lu", - trait->name.name().c_str(), trait->arguments.size()); - this->current_expression = error_mark_node; - return false; - } - this->current_expression = get_inner_alias(trait->types.front(), this->symbols); - - return this->current_expression != error_mark_node; - } - void generic_visitor::visit(boot::traits_expression *trait) { location_t trait_location = get_location(&trait->position()); - if (trait->name == "size") + if (trait->name == "size" || trait->name == "alignment" + || trait->name == "min" || trait->name == "max") { - if (expect_trait_type_only(trait)) + if (trait->arguments.size() != 1) { - if (auto value = this->const_evaluator->evaluate_traits(*trait)) - { - this->current_expression = constant_to_tree(*value); - } - else - { - this->current_expression = fold_convert_loc(trait_location, - elna_word_type_node, size_in_bytes(this->current_expression)); - } + error_at(trait_location, "Trait '%s' expects 1 argument, got %lu", + trait->name.name().c_str(), trait->arguments.size()); + this->current_expression = error_mark_node; + return; } - } - else if (trait->name == "alignment") - { - if (expect_trait_type_only(trait)) + if (auto value = this->const_evaluator->evaluate_traits(*trait)) { - if (auto value = this->const_evaluator->evaluate_traits(*trait)) - { - this->current_expression = constant_to_tree(*value); - } - else - { - this->current_expression = build_int_cstu(elna_word_type_node, - TYPE_ALIGN_UNIT(this->current_expression)); - } + this->current_expression = constant_to_tree(*value); } - } - else if (trait->name == "min" || trait->name == "max") - { - if (expect_trait_type_only(trait)) + else { - if (auto value = this->const_evaluator->evaluate_traits(*trait)) - { - this->current_expression = constant_to_tree(*value); - } - else - { - this->current_expression = error_mark_node; - } + this->current_expression = error_mark_node; } } else if (trait->name == "offset") @@ -922,7 +950,6 @@ namespace elna::gcc this->current_expression = error_mark_node; return; } - this->current_expression = get_inner_alias(trait->types.front(), this->symbols); auto *field_type = trait->arguments.at(1)->is_named(); if (field_type == nullptr) @@ -933,12 +960,9 @@ namespace elna::gcc this->current_expression = error_mark_node; return; } - tree field_declaration = find_field_by_name(trait_location, this->current_expression, field_type->name); - - if (field_declaration != error_mark_node) + if (auto value = this->const_evaluator->evaluate_traits(*trait)) { - this->current_expression = fold_convert_loc(trait_location, elna_word_type_node, - byte_position(field_declaration)); + this->current_expression = constant_to_tree(*value); } else { @@ -1099,25 +1123,6 @@ namespace elna::gcc return decl; } - std::pair generic_visitor::build_loop_head(tree control_variable_declaration, tree limit, - tree_code comparison, location_t check_location) - { - // Put a label in front of the loop condition. - tree check_label = create_artificial_label(check_location); - tree check_statement = build1_loc(check_location, LABEL_EXPR, void_type_node, check_label); - append_statement(check_statement); - - // Build the condition and jump if the condition isn't met. - tree condition = fold_build2(comparison, elna_bool_type_node, control_variable_declaration, limit); - tree end_label = create_artificial_label(UNKNOWN_LOCATION); - tree goto_end = build1(GOTO_EXPR, void_type_node, end_label); - tree condition_statement = build3_loc(check_location, COND_EXPR, void_type_node, - condition, NULL_TREE, goto_end); - append_statement(condition_statement); - - return { check_label, end_label }; - } - void generic_visitor::visit(boot::repeat_statement *statement) { enter_scope(); diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index c47bb94..e8a7daa 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -25,6 +25,29 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { + const elna::boot::target_info& get_host_target() + { + static const elna::boot::target_info info = []{ + elna::boot::target_info target_info; + + target_info.int_properties.size = TYPE_PRECISION(elna_int_type_node) / BITS_PER_UNIT; + target_info.int_properties.alignment = TYPE_ALIGN_UNIT(elna_int_type_node); + target_info.word_properties.size = TYPE_PRECISION(elna_word_type_node) / BITS_PER_UNIT; + target_info.word_properties.alignment = TYPE_ALIGN_UNIT(elna_word_type_node); + target_info.pointer_properties.size = TYPE_PRECISION(ptr_type_node) / BITS_PER_UNIT; + target_info.pointer_properties.alignment = TYPE_ALIGN_UNIT(ptr_type_node); + target_info.char_properties.size = TYPE_PRECISION(elna_char_type_node) / BITS_PER_UNIT; + target_info.char_properties.alignment = TYPE_ALIGN_UNIT(elna_char_type_node); + target_info.float_properties.size = TYPE_PRECISION(elna_float_type_node) / BITS_PER_UNIT; + target_info.float_properties.alignment = TYPE_ALIGN_UNIT(elna_float_type_node); + target_info.bool_properties.size = (TYPE_PRECISION(elna_bool_type_node) + BITS_PER_UNIT - 1) / BITS_PER_UNIT; + target_info.bool_properties.alignment = TYPE_ALIGN_UNIT(elna_bool_type_node); + + return target_info; + }(); + return info; + } + bool is_integral_type(tree type) { gcc_assert(TYPE_P(type)); @@ -74,7 +97,7 @@ namespace elna::gcc void defer(tree statement_tree) { - defer_scope new_defer{ statement_tree, alloc_stmt_list() }; + defer_scope new_defer{ .defer_block = statement_tree, .try_statements = alloc_stmt_list() }; vec_safe_insert(f_binding_level->defers, 0, new_defer); } @@ -87,9 +110,9 @@ namespace elna::gcc defer_scope *defer_iterator = f_binding_level->defers->begin(); tree defer_tree = build2(TRY_FINALLY_EXPR, void_type_node, defer_iterator->try_statements, defer_iterator->defer_block); - int i; + int index; - FOR_EACH_VEC_ELT_FROM(*f_binding_level->defers, i, defer_iterator, 1) + FOR_EACH_VEC_ELT_FROM(*f_binding_level->defers, index, defer_iterator, 1) { append_to_statement_list(defer_tree, &defer_iterator->try_statements); defer_tree = build2(TRY_FINALLY_EXPR, void_type_node, @@ -98,7 +121,7 @@ namespace elna::gcc return build2(COMPOUND_EXPR, TREE_TYPE(defer_tree), f_binding_level->statement_list, defer_tree); } - tree build_field(location_t location, tree record_type, const std::string name, tree type) + tree build_field(location_t location, tree record_type, const std::string& name, tree type) { tree field_declaration = build_decl(location, FIELD_DECL, get_identifier(name.c_str()), type); @@ -174,7 +197,7 @@ namespace elna::gcc return type; } tree field_declaration = TYPE_FIELDS(type); - + // NOLINTNEXTLINE(readability-simplify-boolean-expr) if (!RECORD_OR_UNION_TYPE_P(type)) { error_at(expression_location, "Type '%s' does not have a field named '%s'", @@ -211,12 +234,12 @@ namespace elna::gcc tree build_enumeration_type(const std::vector& members) { tree composite_type_node = make_node(ENUMERAL_TYPE); - const tree base_type = integer_type_node; + tree base_type = integer_type_node; TREE_TYPE(composite_type_node) = base_type; ENUM_IS_SCOPED(composite_type_node) = 1; - tree *pp = &TYPE_VALUES(composite_type_node); + tree *members_pointer = &TYPE_VALUES(composite_type_node); std::size_t order{ 1 }; for (const std::string& member : members) @@ -231,8 +254,8 @@ namespace elna::gcc TYPE_MAX_VALUE(composite_type_node) = DECL_INITIAL(member_declaration); - *pp = build_tree_list(member_name, member_declaration); - pp = &TREE_CHAIN(*pp); + *members_pointer = build_tree_list(member_name, member_declaration); + members_pointer = &TREE_CHAIN(*members_pointer); } TYPE_MIN_VALUE(composite_type_node) = DECL_INITIAL(TREE_VALUE(TYPE_VALUES(composite_type_node))); TYPE_UNSIGNED(composite_type_node) = TYPE_UNSIGNED(base_type); diff --git a/gcc/gcc/elna1.cc b/gcc/gcc/elna1.cc index fde2adc..8eb103b 100644 --- a/gcc/gcc/elna1.cc +++ b/gcc/gcc/elna1.cc @@ -52,29 +52,6 @@ union GTY ((desc("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), /* Language hooks. */ -static const elna::boot::target_info& get_host_target() -{ - static const elna::boot::target_info info = []{ - elna::boot::target_info target_info; - - target_info.int_size = TYPE_PRECISION(elna_int_type_node) / BITS_PER_UNIT; - target_info.int_alignment = TYPE_ALIGN_UNIT(elna_int_type_node); - target_info.word_size = TYPE_PRECISION(elna_word_type_node) / BITS_PER_UNIT; - target_info.word_alignment = TYPE_ALIGN_UNIT(elna_word_type_node); - target_info.pointer_size = TYPE_PRECISION(ptr_type_node) / BITS_PER_UNIT; - target_info.pointer_alignment = TYPE_ALIGN_UNIT(ptr_type_node); - target_info.char_size = TYPE_PRECISION(elna_char_type_node) / BITS_PER_UNIT; - target_info.char_alignment = TYPE_ALIGN_UNIT(elna_char_type_node); - target_info.float_size = TYPE_PRECISION(elna_float_type_node) / BITS_PER_UNIT; - target_info.float_alignment = TYPE_ALIGN_UNIT(elna_float_type_node); - target_info.bool_size = TYPE_PRECISION(elna_bool_type_node) / BITS_PER_UNIT; - target_info.bool_alignment = TYPE_ALIGN_UNIT(elna_bool_type_node); - - return target_info; - }(); - return info; -} - static bool elna_langhook_init(void) { build_common_tree_nodes(false); @@ -148,7 +125,7 @@ static elna::boot::dependency elna_parse_file(dependency_state& state, const cha outcome_bag.add_import(cached_import->second); } } - outcome.errors() = analyze_semantics(outcome.tree, outcome_bag, get_host_target()); + outcome.errors() = analyze_semantics(outcome.tree, outcome_bag, elna::gcc::get_host_target()); } if (outcome.has_errors()) { @@ -172,7 +149,7 @@ static void elna_langhook_parse_file(void) { linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1); elna::gcc::generic_visitor generic_visitor{ state.custom, - state.find(in_fnames[i])->second, get_host_target() }; + state.find(in_fnames[i])->second, elna::gcc::get_host_target() }; outcome.tree->accept(&generic_visitor); linemap_add(line_table, LC_LEAVE, 0, NULL, 0); } -- cgit v1.2.3