diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/Make-lang.in | 11 | ||||
| -rw-r--r-- | gcc/config-lang.in | 2 | ||||
| -rw-r--r-- | gcc/dg.exp | 29 | ||||
| -rw-r--r-- | gcc/gcc/elna-builtins.cc (renamed from gcc/elna-builtins.cc) | 54 | ||||
| -rw-r--r-- | gcc/gcc/elna-diagnostic.cc (renamed from gcc/elna-diagnostic.cc) | 6 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc (renamed from gcc/elna-generic.cc) | 170 | ||||
| -rw-r--r-- | gcc/gcc/elna-spec.cc (renamed from gcc/elna-spec.cc) | 0 | ||||
| -rw-r--r-- | gcc/gcc/elna-tree.cc (renamed from gcc/elna-tree.cc) | 10 | ||||
| -rw-r--r-- | gcc/gcc/elna1.cc (renamed from gcc/elna1.cc) | 16 | ||||
| -rw-r--r-- | gcc/gcc/gelna.texi (renamed from gcc/gelna.texi) | 0 | ||||
| -rw-r--r-- | gcc/testlib/elna-dg.exp | 66 | ||||
| -rw-r--r-- | gcc/testlib/elna.exp | 155 |
12 files changed, 387 insertions, 132 deletions
diff --git a/gcc/Make-lang.in b/gcc/Make-lang.in index e25fc6d..cb57798 100644 --- a/gcc/Make-lang.in +++ b/gcc/Make-lang.in @@ -66,6 +66,11 @@ elna.all.cross: gelna-cross$(exeext) elna.start.encap: gelna$(exeext) elna.rest.encap: +lang_checks += check-elna +lang_checks_parallelized += check-elna +# For description see the check_$lang_parallelize comment in gcc/Makefile.in. +check_elna_parallelize = 10 + # No elna-specific selftests. selftest-elna: @@ -150,7 +155,7 @@ elna.stagefeedback: stagefeedback-start ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated ELNA_CXXFLAGS = -std=c++17 -elna/%.o: elna/frontend/%.cc elna/generated/parser.hh elna/generated/location.hh +elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh $(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $< $(POSTCOMPILE) @@ -162,13 +167,13 @@ elna/%.o: elna/gcc/%.cc elna/generated/parser.hh elna/generated/location.hh $(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $< $(POSTCOMPILE) -elna/generated/parser.cc: elna/frontend/parser.yy +elna/generated/parser.cc: elna/boot/parser.yy mkdir -p $(dir $@) $(BISON) -d -o $@ $< elna/generated/parser.hh elna/generated/location.hh: elna/generated/parser.cc @touch $@ -elna/generated/lexer.cc: elna/frontend/lexer.ll +elna/generated/lexer.cc: elna/boot/lexer.ll mkdir -p $(dir $@) $(FLEX) -o $@ $< diff --git a/gcc/config-lang.in b/gcc/config-lang.in index 0cbbe1f..a003be7 100644 --- a/gcc/config-lang.in +++ b/gcc/config-lang.in @@ -23,7 +23,7 @@ # compilers - value to add to $(COMPILERS) language="elna" -gcc_subdir="elna/gcc" +# gcc_subdir="elna/gcc" compilers="elna1\$(exeext)" diff --git a/gcc/dg.exp b/gcc/dg.exp new file mode 100644 index 0000000..ce424d9 --- /dev/null +++ b/gcc/dg.exp @@ -0,0 +1,29 @@ +# Copyright (C) 2004-2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib elna-dg.exp + +# Initialize dg. +dg-init + +# Main loop. +elna-dg-runtest [lsort [find $srcdir/$subdir *.elna]] "" "" + +# All done. +dg-finish diff --git a/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc index cf06df8..7c97027 100644 --- a/gcc/elna-builtins.cc +++ b/gcc/gcc/elna-builtins.cc @@ -64,23 +64,23 @@ namespace elna::gcc std::shared_ptr<symbol_table> builtin_symbol_table() { - std::shared_ptr<elna::gcc::symbol_table> symbol_table = std::make_shared<elna::gcc::symbol_table>(); + auto builtin_table = std::make_shared<symbol_table>(); - declare_builtin_type(symbol_table, "Int", elna_int_type_node); - declare_builtin_type(symbol_table, "Word", elna_word_type_node); - declare_builtin_type(symbol_table, "Char", elna_char_type_node); - declare_builtin_type(symbol_table, "Bool", elna_bool_type_node); - declare_builtin_type(symbol_table, "Pointer", elna_pointer_type_node); - declare_builtin_type(symbol_table, "Float", elna_float_type_node); + declare_builtin_type(builtin_table, "Int", elna_int_type_node); + declare_builtin_type(builtin_table, "Word", elna_word_type_node); + declare_builtin_type(builtin_table, "Char", elna_char_type_node); + declare_builtin_type(builtin_table, "Bool", elna_bool_type_node); + declare_builtin_type(builtin_table, "Pointer", elna_pointer_type_node); + declare_builtin_type(builtin_table, "Float", elna_float_type_node); - tree string_declaration = declare_builtin_type(symbol_table, "String", elna_string_type_node); + tree string_declaration = declare_builtin_type(builtin_table, "String", elna_string_type_node); TYPE_NAME(elna_string_type_node) = DECL_NAME(string_declaration); TYPE_STUB_DECL(elna_string_type_node) = string_declaration; - return symbol_table; + return builtin_table; } - tree build_composite_type(const std::vector<frontend::type_field>& fields, tree composite_type_node, + tree build_composite_type(const std::vector<boot::type_field>& fields, tree composite_type_node, std::shared_ptr<symbol_table> symbols) { for (auto& field : fields) @@ -94,7 +94,7 @@ namespace elna::gcc return composite_type_node; } - tree build_procedure_type(const frontend::procedure_type& procedure, std::shared_ptr<symbol_table> symbols) + tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr<symbol_table> symbols) { std::vector<tree> parameter_types(procedure.parameters.size()); @@ -111,16 +111,16 @@ namespace elna::gcc return build_function_type_array(return_type, procedure.parameters.size(), parameter_types.data()); } - tree get_inner_alias(const frontend::type& type, std::shared_ptr<symbol_table> symbols) + tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols) { - if (auto reference = type.get<frontend::primitive_type>()) + if (auto reference = type.get<boot::primitive_type>()) { auto looked_up = symbols->lookup(reference->identifier); gcc_assert(looked_up != NULL_TREE); return TREE_TYPE(looked_up); } - else if (auto reference = type.get<frontend::record_type>()) + else if (auto reference = type.get<boot::record_type>()) { tree composite_type_node = make_node(RECORD_TYPE); @@ -128,7 +128,7 @@ namespace elna::gcc return composite_type_node; } - else if (auto reference = type.get<frontend::union_type>()) + else if (auto reference = type.get<boot::union_type>()) { tree composite_type_node = make_node(UNION_TYPE); @@ -136,34 +136,34 @@ namespace elna::gcc return composite_type_node; } - else if (auto reference = type.get<frontend::enumeration_type>()) + else if (auto reference = type.get<boot::enumeration_type>()) { return build_enumeration_type(reference->members); } - else if (auto reference = type.get<frontend::pointer_type>()) + else if (auto reference = type.get<boot::pointer_type>()) { return build_global_pointer_type(get_inner_alias(reference->base, symbols)); } - else if (auto reference = type.get<frontend::array_type>()) + else if (auto reference = type.get<boot::array_type>()) { tree base = get_inner_alias(reference->base, symbols); return build_static_array_type(base, reference->size); } - else if (auto reference = type.get<frontend::procedure_type>()) + else if (auto reference = type.get<boot::procedure_type>()) { auto procedure = build_procedure_type(*reference, symbols); return build_global_pointer_type(procedure); } - else if (auto reference = type.get<frontend::alias_type>()) + else if (auto reference = type.get<boot::alias_type>()) { return TREE_TYPE(handle_symbol(reference->name, reference, symbols)); } return error_mark_node; } - tree handle_symbol(const std::string& symbol_name, std::shared_ptr<frontend::alias_type> reference, + tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference, std::shared_ptr<symbol_table> symbols) { tree looked_up = symbols->lookup(symbol_name); @@ -189,7 +189,7 @@ namespace elna::gcc return looked_up; } - void declare_procedure(const std::string& name, const frontend::procedure_info& info, + void declare_procedure(const std::string& name, const boot::procedure_info& info, std::shared_ptr<symbol_table> symbols) { tree declaration_type = gcc::build_procedure_type(info.symbol, symbols); @@ -210,7 +210,7 @@ namespace elna::gcc std::vector<std::string>::const_iterator parameter_name = info.names.cbegin(); - for (frontend::type parameter : info.symbol.parameters) + for (boot::type parameter : info.symbol.parameters) { tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL, get_identifier(parameter_name->c_str()), function_args_iter_cond(¶meter_type)); @@ -227,7 +227,7 @@ namespace elna::gcc TREE_PUBLIC(fndecl) = info.exported; } - tree declare_variable(const std::string& name, const frontend::variable_info& info, + tree declare_variable(const std::string& name, const boot::variable_info& info, std::shared_ptr<symbol_table> symbols) { auto variable_type = get_inner_alias(info.symbol, symbols); @@ -242,10 +242,10 @@ namespace elna::gcc return declaration_tree; } - void declare_type(const std::string& name, const frontend::type_info& info, std::shared_ptr<symbol_table> symbols) + void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr<symbol_table> symbols) { // The top level symbol table has basic (builtin) types in it which are not aliases. - if (auto alias_type = info.symbol.get<frontend::alias_type>()) + if (auto alias_type = info.symbol.get<boot::alias_type>()) { tree type_declaration = handle_symbol(name, alias_type, symbols); @@ -253,7 +253,7 @@ namespace elna::gcc } } - void rewrite_symbol_table(std::shared_ptr<frontend::symbol_table> info_table, std::shared_ptr<symbol_table> symbols) + void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols) { for (auto& [symbol_name, symbol_info] : *info_table) { diff --git a/gcc/elna-diagnostic.cc b/gcc/gcc/elna-diagnostic.cc index 162d6cb..fa32788 100644 --- a/gcc/elna-diagnostic.cc +++ b/gcc/gcc/elna-diagnostic.cc @@ -31,7 +31,7 @@ namespace elna::gcc linemap_add(line_table, LC_LEAVE, 0, NULL, 0); } - location_t get_location(const frontend::position *position) + location_t get_location(const boot::position *position) { linemap_line_start(line_table, position->line, 0); @@ -151,7 +151,7 @@ namespace elna::gcc gcc_unreachable(); } - void report_errors(const std::deque<std::unique_ptr<frontend::error>>& errors) + void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors) { for (const auto& error : errors) { @@ -159,7 +159,7 @@ namespace elna::gcc if (error->position.line != 0 || error->position.column != 0) { - gcc_location = elna::gcc::get_location(&error->position); + gcc_location = get_location(&error->position); } error_at(gcc_location, error->what().c_str()); } diff --git a/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index a5aa5f5..66bd9a2 100644 --- a/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -35,13 +35,13 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { - generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::frontend::symbol_bag bag) + generic_visitor::generic_visitor(std::shared_ptr<symbol_table> symbol_table, boot::symbol_bag bag) : bag(bag), symbols(symbol_table) { } void generic_visitor::build_procedure_call(location_t call_location, - tree procedure_address, const std::vector<frontend::expression *>& arguments) + tree procedure_address, const std::vector<boot::expression *>& arguments) { vec<tree, va_gc> *argument_trees = nullptr; tree symbol_type = TREE_TYPE(TREE_TYPE(procedure_address)); @@ -49,7 +49,7 @@ namespace elna::gcc tree current_parameter = TYPE_ARG_TYPES(symbol_type); vec_alloc(argument_trees, arguments.size()); - for (frontend::expression *const argument : arguments) + for (boot::expression *const argument : arguments) { location_t argument_location = get_location(&argument->position()); if (VOID_TYPE_P(TREE_VALUE(current_parameter))) @@ -88,11 +88,11 @@ namespace elna::gcc } void generic_visitor::build_record_call(location_t call_location, - tree symbol, const std::vector<frontend::expression *>& arguments) + tree symbol, const std::vector<boot::expression *>& arguments) { vec<constructor_elt, va_gc> *tree_arguments = nullptr; tree record_fields = TYPE_FIELDS(symbol); - for (frontend::expression *const argument : arguments) + for (boot::expression *const argument : arguments) { location_t argument_location = get_location(&argument->position()); @@ -129,7 +129,7 @@ namespace elna::gcc } void generic_visitor::build_assert_builtin(location_t call_location, - const std::vector<frontend::expression *>& arguments) + const std::vector<boot::expression *>& arguments) { if (arguments.size() != 1) { @@ -165,11 +165,11 @@ namespace elna::gcc } } - bool generic_visitor::build_builtin_procedures(frontend::procedure_call *call) + bool generic_visitor::build_builtin_procedures(boot::procedure_call *call) { location_t call_location = get_location(&call->position()); - if (frontend::named_expression *named_call = call->callable().is_named()) + if (boot::named_expression *named_call = call->callable().is_named()) { if (named_call->name == "assert") { @@ -180,7 +180,7 @@ namespace elna::gcc return false; } - void generic_visitor::visit(frontend::procedure_call *call) + void generic_visitor::visit(boot::procedure_call *call) { if (build_builtin_procedures(call)) { @@ -215,7 +215,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::cast_expression *expression) + void generic_visitor::visit(boot::cast_expression *expression) { tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope()); @@ -235,9 +235,9 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::program *program) + void generic_visitor::visit(boot::program *program) { - visit(static_cast<frontend::unit *>(program)); + visit(static_cast<boot::unit *>(program)); tree declaration_type = build_function_type_list(elna_int_type_node, elna_int_type_node, @@ -285,27 +285,27 @@ namespace elna::gcc cgraph_node::finalize_function(fndecl, true); } - void generic_visitor::visit(frontend::unit *unit) + void generic_visitor::visit(boot::unit *unit) { - for (frontend::import_declaration *const declaration : unit->imports) + for (boot::import_declaration *const declaration : unit->imports) { declaration->accept(this); } - for (frontend::constant_declaration *const constant : unit->constants) + for (boot::constant_declaration *const constant : unit->constants) { constant->accept(this); } - for (frontend::variable_declaration *const variable : unit->variables) + for (boot::variable_declaration *const variable : unit->variables) { variable->accept(this); } - for (frontend::procedure_declaration *const procedure : unit->procedures) + for (boot::procedure_declaration *const procedure : unit->procedures) { procedure->accept(this); } } - void generic_visitor::visit(frontend::procedure_declaration *definition) + void generic_visitor::visit(boot::procedure_declaration *definition) { tree fndecl = this->symbols->lookup(definition->identifier.name); @@ -324,11 +324,11 @@ namespace elna::gcc { this->symbols->enter(IDENTIFIER_POINTER(DECL_NAME(argument_chain)), argument_chain); } - for (frontend::constant_declaration *const constant : definition->body.value().constants()) + for (boot::constant_declaration *const constant : definition->body.value().constants()) { constant->accept(this); } - for (frontend::variable_declaration *const variable : definition->body.value().variables()) + for (boot::variable_declaration *const variable : definition->body.value().variables()) { variable->accept(this); } @@ -381,17 +381,17 @@ namespace elna::gcc return bind_expr; } - void generic_visitor::visit(frontend::literal<std::int32_t> *literal) + void generic_visitor::visit(boot::literal<std::int32_t> *literal) { this->current_expression = build_int_cst(elna_int_type_node, literal->value); } - void generic_visitor::visit(frontend::literal<std::uint32_t> *literal) + void generic_visitor::visit(boot::literal<std::uint32_t> *literal) { this->current_expression = build_int_cstu(elna_word_type_node, literal->value); } - void generic_visitor::visit(frontend::literal<double> *literal) + void generic_visitor::visit(boot::literal<double> *literal) { REAL_VALUE_TYPE real_value1; @@ -406,22 +406,22 @@ namespace elna::gcc mpfr_clear(number); } - void generic_visitor::visit(frontend::literal<bool> *boolean) + void generic_visitor::visit(boot::literal<bool> *boolean) { this->current_expression = boolean->value ? boolean_true_node : boolean_false_node; } - void generic_visitor::visit(frontend::literal<unsigned char> *character) + void generic_visitor::visit(boot::literal<unsigned char> *character) { this->current_expression = build_int_cstu(elna_char_type_node, character->value); } - void generic_visitor::visit(frontend::literal<nullptr_t> *) + void generic_visitor::visit(boot::literal<nullptr_t> *) { this->current_expression = elna_pointer_nil_node; } - void generic_visitor::visit(frontend::literal<std::string> *string) + void generic_visitor::visit(boot::literal<std::string> *string) { tree index_constant = build_int_cstu(elna_word_type_node, string->value.size()); tree string_type = build_array_type(elna_char_type_node, build_index_type(index_constant)); @@ -444,38 +444,38 @@ namespace elna::gcc this->current_expression = build_constructor(elna_string_type_node, elms); } - tree generic_visitor::build_arithmetic_operation(frontend::binary_expression *expression, + tree generic_visitor::build_arithmetic_operation(boot::binary_expression *expression, tree_code operator_code, tree left, tree right) { return build_binary_operation(is_numeric_type(TREE_TYPE(left)), expression, operator_code, left, right, TREE_TYPE(left)); } - tree generic_visitor::build_comparison_operation(frontend::binary_expression *expression, + tree generic_visitor::build_comparison_operation(boot::binary_expression *expression, tree_code operator_code, tree left, tree right) { return build_binary_operation(is_numeric_type(TREE_TYPE(left)) || POINTER_TYPE_P(TREE_TYPE(left)), expression, operator_code, left, right, elna_bool_type_node); } - tree generic_visitor::build_bit_logic_operation(frontend::binary_expression *expression, tree left, tree right) + tree generic_visitor::build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right) { location_t expression_location = get_location(&expression->position()); tree left_type = TREE_TYPE(left); tree right_type = TREE_TYPE(right); tree_code logical_code, bit_code; - if (expression->operation() == frontend::binary_operator::conjunction) + if (expression->operation() == boot::binary_operator::conjunction) { bit_code = BIT_AND_EXPR; logical_code = TRUTH_ANDIF_EXPR; } - else if (expression->operation() == frontend::binary_operator::disjunction) + else if (expression->operation() == boot::binary_operator::disjunction) { bit_code = BIT_IOR_EXPR; logical_code = TRUTH_ORIF_EXPR; } - else if (expression->operation() == frontend::binary_operator::exclusive_disjunction) + else if (expression->operation() == boot::binary_operator::exclusive_disjunction) { bit_code = BIT_XOR_EXPR; logical_code = TRUTH_XOR_EXPR; @@ -496,22 +496,22 @@ namespace elna::gcc { error_at(expression_location, "Invalid operands of type '%s' and '%s' for operator %s", print_type(left_type).c_str(), print_type(right_type).c_str(), - elna::frontend::print_binary_operator(expression->operation())); + boot::print_binary_operator(expression->operation())); return error_mark_node; } } - tree generic_visitor::build_equality_operation(frontend::binary_expression *expression, tree left, tree right) + tree generic_visitor::build_equality_operation(boot::binary_expression *expression, tree left, tree right) { location_t expression_location = get_location(&expression->position()); tree_code equality_code, combination_code; - if (expression->operation() == frontend::binary_operator::equals) + if (expression->operation() == boot::binary_operator::equals) { equality_code = EQ_EXPR; combination_code = TRUTH_ANDIF_EXPR; } - else if (expression->operation() == frontend::binary_operator::not_equals) + else if (expression->operation() == boot::binary_operator::not_equals) { equality_code = NE_EXPR; combination_code = TRUTH_ORIF_EXPR; @@ -545,7 +545,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::binary_expression *expression) + void generic_visitor::visit(boot::binary_expression *expression) { expression->lhs().accept(this); tree left = this->current_expression; @@ -558,8 +558,8 @@ namespace elna::gcc location_t expression_location = get_location(&expression->position()); if ((POINTER_TYPE_P(left_type) || POINTER_TYPE_P(right_type)) - && (expression->operation() == frontend::binary_operator::sum - || expression->operation() == frontend::binary_operator::subtraction)) + && (expression->operation() == boot::binary_operator::sum + || expression->operation() == boot::binary_operator::subtraction)) { this->current_expression = do_pointer_arithmetic(expression->operation(), left, right, expression_location); @@ -567,7 +567,7 @@ namespace elna::gcc { error_at(expression_location, "invalid operation %s on a pointer and an integral type", - frontend::print_binary_operator(expression->operation())); + boot::print_binary_operator(expression->operation())); } else if (TREE_TYPE(this->current_expression) == ssizetype) { @@ -583,60 +583,60 @@ namespace elna::gcc error_at(expression_location, "invalid operands of type '%s' and '%s' for operator %s", print_type(left_type).c_str(), print_type(right_type).c_str(), - frontend::print_binary_operator(expression->operation())); + boot::print_binary_operator(expression->operation())); this->current_expression = error_mark_node; return; } switch (expression->operation()) { - case frontend::binary_operator::sum: + case boot::binary_operator::sum: this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right); break; - case frontend::binary_operator::subtraction: + case boot::binary_operator::subtraction: this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right); break; - case frontend::binary_operator::division: + case boot::binary_operator::division: this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right); break; - case frontend::binary_operator::remainder: + case boot::binary_operator::remainder: this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right); break; - case frontend::binary_operator::multiplication: + case boot::binary_operator::multiplication: this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right); break; - case frontend::binary_operator::less: + case boot::binary_operator::less: this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right); break; - case frontend::binary_operator::greater: + case boot::binary_operator::greater: this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right); break; - case frontend::binary_operator::less_equal: + case boot::binary_operator::less_equal: this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right); break; - case frontend::binary_operator::greater_equal: + case boot::binary_operator::greater_equal: this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right); break; - case frontend::binary_operator::conjunction: + case boot::binary_operator::conjunction: this->current_expression = build_bit_logic_operation(expression, left, right); break; - case frontend::binary_operator::disjunction: + case boot::binary_operator::disjunction: this->current_expression = build_bit_logic_operation(expression, left, right); break; - case frontend::binary_operator::exclusive_disjunction: + case boot::binary_operator::exclusive_disjunction: this->current_expression = build_bit_logic_operation(expression, left, right); break; - case frontend::binary_operator::equals: + case boot::binary_operator::equals: this->current_expression = build_equality_operation(expression, left, right); break; - case frontend::binary_operator::not_equals: + case boot::binary_operator::not_equals: this->current_expression = build_equality_operation(expression, left, right); break; - case frontend::binary_operator::shift_left: + case boot::binary_operator::shift_left: this->current_expression = build_binary_operation( is_numeric_type(left_type) && right_type == elna_word_type_node, expression, LSHIFT_EXPR, left, right, left_type); break; - case frontend::binary_operator::shift_right: + case boot::binary_operator::shift_right: this->current_expression = build_binary_operation( is_numeric_type(left_type) && right_type == elna_word_type_node, expression, RSHIFT_EXPR, left, right, left_type); @@ -644,14 +644,14 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::unary_expression *expression) + void generic_visitor::visit(boot::unary_expression *expression) { expression->operand().accept(this); location_t location = get_location(&expression->position()); switch (expression->operation()) { - case frontend::unary_operator::reference: + case boot::unary_operator::reference: this->current_expression = prepare_rvalue(this->current_expression); TREE_ADDRESSABLE(this->current_expression) = 1; this->current_expression = build_fold_addr_expr_with_type_loc(location, @@ -659,7 +659,7 @@ namespace elna::gcc build_global_pointer_type(TREE_TYPE(this->current_expression))); TREE_NO_TRAMPOLINE(this->current_expression) = 1; break; - case frontend::unary_operator::negation: + case boot::unary_operator::negation: if (TREE_TYPE(this->current_expression) == elna_bool_type_node) { this->current_expression = build1_loc(location, TRUTH_NOT_EXPR, @@ -677,7 +677,7 @@ namespace elna::gcc this->current_expression = error_mark_node; } break; - case frontend::unary_operator::minus: + case boot::unary_operator::minus: if (is_integral_type(TREE_TYPE(this->current_expression))) { this->current_expression = fold_build1(NEGATE_EXPR, TREE_TYPE(this->current_expression), @@ -692,7 +692,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::constant_declaration *definition) + void generic_visitor::visit(boot::constant_declaration *definition) { location_t definition_location = get_location(&definition->position()); definition->body().accept(this); @@ -732,7 +732,7 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit(frontend::variable_declaration *declaration) + void generic_visitor::visit(boot::variable_declaration *declaration) { for (const auto& variable_identifier : declaration->identifiers) { @@ -784,7 +784,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::named_expression *expression) + void generic_visitor::visit(boot::named_expression *expression) { auto symbol = this->symbols->lookup(expression->name); @@ -800,7 +800,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::array_access_expression *expression) + void generic_visitor::visit(boot::array_access_expression *expression) { expression->base().accept(this); tree designator = this->current_expression; @@ -829,7 +829,7 @@ namespace elna::gcc tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node), designator, elna_string_ptr_field_node, NULL_TREE); - tree target_pointer = do_pointer_arithmetic(frontend::binary_operator::sum, string_ptr, offset, location); + 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); @@ -842,7 +842,7 @@ namespace elna::gcc } } - bool generic_visitor::expect_trait_type_only(frontend::traits_expression *trait) + bool generic_visitor::expect_trait_type_only(boot::traits_expression *trait) { if (trait->parameters.size() != 1) { @@ -856,7 +856,7 @@ namespace elna::gcc return this->current_expression != error_mark_node; } - bool generic_visitor::expect_trait_for_integral_type(frontend::traits_expression *trait) + bool generic_visitor::expect_trait_for_integral_type(boot::traits_expression *trait) { if (!expect_trait_type_only(trait)) { @@ -872,7 +872,7 @@ namespace elna::gcc return true; } - void generic_visitor::visit(frontend::traits_expression *trait) + void generic_visitor::visit(boot::traits_expression *trait) { location_t trait_location = get_location(&trait->position()); @@ -945,7 +945,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::field_access_expression *expression) + void generic_visitor::visit(boot::field_access_expression *expression) { expression->base().accept(this); location_t expression_location = get_location(&expression->position()); @@ -991,7 +991,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::dereference_expression *expression) + void generic_visitor::visit(boot::dereference_expression *expression) { expression->base().accept(this); location_t expression_location = get_location(&expression->position()); @@ -1010,7 +1010,7 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::assign_statement *statement) + void generic_visitor::visit(boot::assign_statement *statement) { statement->lvalue().accept(this); @@ -1045,7 +1045,7 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit(frontend::if_statement *statement) + 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); @@ -1068,7 +1068,7 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::make_if_branch(frontend::conditional_statements& branch, tree goto_endif) + void generic_visitor::make_if_branch(boot::conditional_statements& branch, tree goto_endif) { branch.prerequisite().accept(this); @@ -1102,11 +1102,11 @@ namespace elna::gcc append_statement(else_label_expr); } - void generic_visitor::visit(frontend::import_declaration *) + void generic_visitor::visit(boot::import_declaration *) { } - void generic_visitor::visit(frontend::while_statement *statement) + void generic_visitor::visit(boot::while_statement *statement) { location_t prerequisite_location = get_location(&statement->body().prerequisite().position()); tree prerequisite_label_decl = build_label_decl("while_do", prerequisite_location); @@ -1127,9 +1127,9 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit_statements(const std::vector<frontend::statement *>& statements) + void generic_visitor::visit_statements(const std::vector<boot::statement *>& statements) { - for (frontend::statement *const statement : statements) + for (boot::statement *const statement : statements) { statement->accept(this); @@ -1141,9 +1141,9 @@ namespace elna::gcc } } - void generic_visitor::visit(frontend::return_statement *statement) + void generic_visitor::visit(boot::return_statement *statement) { - frontend::expression *return_expression = &statement->return_expression(); + 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)); @@ -1183,14 +1183,14 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit(frontend::defer_statement *statement) + void generic_visitor::visit(boot::defer_statement *statement) { enter_scope(); visit_statements(statement->statements); defer(leave_scope()); } - void generic_visitor::visit(frontend::case_statement *statement) + void generic_visitor::visit(boot::case_statement *statement) { statement->condition().accept(this); tree condition_expression = this->current_expression; @@ -1207,9 +1207,9 @@ namespace elna::gcc tree end_label_declaration = create_artificial_label(get_location(&statement->position())); tree switch_statements = alloc_stmt_list(); - for (const frontend::switch_case& case_block : statement->cases) + for (const boot::switch_case& case_block : statement->cases) { - for (frontend::expression *const case_label : case_block.labels) + for (boot::expression *const case_label : case_block.labels) { case_label->accept(this); location_t case_location = get_location(&case_label->position()); diff --git a/gcc/elna-spec.cc b/gcc/gcc/elna-spec.cc index 5d1ace1..5d1ace1 100644 --- a/gcc/elna-spec.cc +++ b/gcc/gcc/elna-spec.cc diff --git a/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index 93f796b..de7f6b0 100644 --- a/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -128,12 +128,12 @@ namespace elna::gcc return field_declaration; } - tree do_pointer_arithmetic(frontend::binary_operator binary_operator, + tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right, location_t operation_location) { tree left_type = get_qualified_type(TREE_TYPE(left), TYPE_UNQUALIFIED); tree right_type = get_qualified_type(TREE_TYPE(right), TYPE_UNQUALIFIED); - if (binary_operator == frontend::binary_operator::sum) + if (binary_operator == boot::binary_operator::sum) { tree pointer{ NULL_TREE }; tree offset{ NULL_TREE }; @@ -164,7 +164,7 @@ namespace elna::gcc return fold_build2_loc(operation_location, POINTER_PLUS_EXPR, TREE_TYPE(pointer), pointer, offset); } - else if (binary_operator == frontend::binary_operator::subtraction) + else if (binary_operator == boot::binary_operator::subtraction) { if (POINTER_TYPE_P(left_type) && is_integral_type(right_type)) { @@ -186,7 +186,7 @@ namespace elna::gcc gcc_unreachable(); } - tree build_binary_operation(bool condition, frontend::binary_expression *expression, + tree build_binary_operation(bool condition, boot::binary_expression *expression, tree_code operator_code, tree left, tree right, tree target_type) { location_t expression_location = get_location(&expression->position()); @@ -202,7 +202,7 @@ namespace elna::gcc error_at(expression_location, "invalid operands of type '%s' and '%s' for operator %s", print_type(left_type).c_str(), print_type(right_type).c_str(), - elna::frontend::print_binary_operator(expression->operation())); + boot::print_binary_operator(expression->operation())); return error_mark_node; } } diff --git a/gcc/elna1.cc b/gcc/gcc/elna1.cc index 448a24c..0333f70 100644 --- a/gcc/elna1.cc +++ b/gcc/gcc/elna1.cc @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks-def.h" #include <fstream> -#include "elna/frontend/dependency.h" +#include "elna/boot/dependency.h" #include "elna/gcc/elna-tree.h" #include "elna/gcc/elna-generic.h" #include "elna/gcc/elna-diagnostic.h" @@ -62,9 +62,9 @@ static bool elna_langhook_init(void) return true; } -using dependency_state = elna::frontend::dependency_state<std::shared_ptr<elna::gcc::symbol_table>>; +using dependency_state = elna::boot::dependency_state<std::shared_ptr<elna::gcc::symbol_table>>; -static elna::frontend::dependency elna_parse_file(dependency_state& state, const char *filename) +static elna::boot::dependency elna_parse_file(dependency_state& state, const char *filename) { std::ifstream entry_point{ filename, std::ios::in }; @@ -73,19 +73,19 @@ static elna::frontend::dependency elna_parse_file(dependency_state& state, const fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename); } elna::gcc::linemap_guard{ filename }; - elna::frontend::dependency outcome = elna::frontend::read_source(entry_point, filename); + elna::boot::dependency outcome = elna::boot::read_source(entry_point, filename); if (outcome.has_errors()) { elna::gcc::report_errors(outcome.errors()); return outcome; } - elna::frontend::symbol_bag outcome_bag = elna::frontend::symbol_bag{ std::move(outcome.unresolved), state.globals }; + elna::boot::symbol_bag outcome_bag = elna::boot::symbol_bag{ std::move(outcome.unresolved), state.globals }; for (const auto& sub_tree : outcome.tree->imports) { - std::filesystem::path sub_path = "source" / elna::frontend::build_path(sub_tree->segments); - std::unordered_map<std::filesystem::path, elna::frontend::symbol_bag>::const_iterator cached_import = + std::filesystem::path sub_path = "source" / elna::boot::build_path(sub_tree->segments); + std::unordered_map<std::filesystem::path, elna::boot::symbol_bag>::const_iterator cached_import = state.cache.find(sub_path); if (cached_import == state.cache.end()) @@ -114,7 +114,7 @@ static void elna_langhook_parse_file(void) for (unsigned int i = 0; i < num_in_fnames; i++) { - elna::frontend::dependency outcome = elna_parse_file(state, in_fnames[i]); + elna::boot::dependency outcome = elna_parse_file(state, in_fnames[i]); linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1); elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second }; diff --git a/gcc/gelna.texi b/gcc/gcc/gelna.texi index e4bc6ce..e4bc6ce 100644 --- a/gcc/gelna.texi +++ b/gcc/gcc/gelna.texi diff --git a/gcc/testlib/elna-dg.exp b/gcc/testlib/elna-dg.exp new file mode 100644 index 0000000..baefe36 --- /dev/null +++ b/gcc/testlib/elna-dg.exp @@ -0,0 +1,66 @@ +# Copyright (C) 2004-2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +load_lib gcc-dg.exp + +# Define elna callbacks for dg.exp. + +proc elna-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 elna_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} + +proc elna-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +# + +proc elna-dg-runtest { testcases flags default-extra-flags } { + global runtests + global dg-do-what-default + global tool + + foreach testcase $testcases { + # If we're only testing specific files and this isn't one of them, skip it. + if {![runtest_file_p $runtests $testcase]} { + continue + } + # Check the test directory to detect the test type and set the expectation. + set type [file tail [file dirname $testcase]] + switch $type { + compilable { + set dg-do-what-default "compile" + } + default { + ${tool}_fail $testcase "Unknown test type \"$type\"" + return 0 + } + } + verbose "Testing $type/[file tail $testcase]" + dg-test $testcase $flags ${default-extra-flags} + } +} diff --git a/gcc/testlib/elna.exp b/gcc/testlib/elna.exp new file mode 100644 index 0000000..628a79f --- /dev/null +++ b/gcc/testlib/elna.exp @@ -0,0 +1,155 @@ +# Copyright (C) 2003-2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# +# elna support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# ELNA_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + + +# +# elna_version -- extract and print the version number of the compiler +# + +proc elna_version { } { + global ELNA_UNDER_TEST + + elna_init + + # ignore any arguments after the command + set compiler [lindex $ELNA_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# elna_init -- called at the start of each subdir of tests +# + +proc elna_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_ELNAFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global ELNA_UNDER_TEST + global TESTING_IN_BUILD_TREE + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists ELNA_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set ELNA_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set ELNA_UNDER_TEST [transform gelna] + } else { + set ELNA_UNDER_TEST [findfile $base_dir/../../gelna "$base_dir/../../gelna -B$base_dir/../../" [findfile $base_dir/gelna "$base_dir/gelna -B$base_dir/" [transform gelna]]] + } + } + } + + if ![is_remote host] { + if { [which $ELNA_UNDER_TEST] == 0 } then { + perror "ELNA_UNDER_TEST ($ELNA_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + elna_maybe_build_wrapper "${tmpdir}/elna-testglue.o" + + set ALWAYS_ELNAFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_ELNAFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_ELNAFLAGS "additional_flags=$TOOL_OPTIONS" + } + + verbose -log "ALWAYS_ELNAFLAGS set to $ALWAYS_ELNAFLAGS" + + verbose "elna is initialized" 3 +} + +# +# elna_target_compile -- compile a source file +# + +proc elna_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global ALWAYS_ELNAFLAGS + global ELNA_UNDER_TEST + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$ELNA_UNDER_TEST" + + set options [concat "$ALWAYS_ELNAFLAGS" $options] + set options [dg-additional-files-options $options $source $dest $type] + return [target_compile $source $dest $type $options] +} |
