From d09cd98bd3df9920f0ecab97615048c0594e8f7f Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 19 Jul 2026 23:23:22 +0200 Subject: Add clang-tidy support --- boot/ast.cc | 137 +++++++++++++++++++++++++------------------------- boot/dependency.cc | 6 +-- boot/driver.cc | 4 +- boot/evaluator.cc | 85 ++++++++++++++++--------------- boot/name_analysis.cc | 57 +++++++++++---------- boot/result.cc | 36 +++++++------ boot/symbol.cc | 109 ++++++++++++++++++++++----------------- boot/type_check.cc | 94 +++++++++++++++++----------------- 8 files changed, 273 insertions(+), 255 deletions(-) (limited to 'boot') diff --git a/boot/ast.cc b/boot/ast.cc index 0931a2c..9b3fbe4 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/ast.h" +#include + namespace elna::boot { void empty_visitor::visit(array_type_expression *) @@ -210,11 +212,11 @@ namespace elna::boot } if (declaration->body.has_value()) { - for (variable_declaration *const variable : declaration->body.value().variables) + for (variable_declaration *variable : declaration->body.value().variables) { variable->accept(this); } - for (statement *const statement : declaration->body.value().entry_point) + for (auto *statement : declaration->body.value().entry_point) { statement->accept(this); } @@ -234,22 +236,22 @@ namespace elna::boot void walking_visitor::visit(if_statement *statement) { statement->branch().prerequisite().accept(this); - for (struct statement *const branch_statement : statement->branch().statements) + for (auto *branch_statement : statement->branch().statements) { branch_statement->accept(this); } - for (conditional_statements *const branch : statement->branches) + for (conditional_statements *branch : statement->branches) { branch->prerequisite().accept(this); - for (struct statement *const branch_statement : branch->statements) + for (auto *branch_statement : branch->statements) { branch_statement->accept(this); } } if (statement->alternative != nullptr) { - for (struct statement *const branch_statement : *statement->alternative) + for (auto *branch_statement : *statement->alternative) { branch_statement->accept(this); } @@ -259,15 +261,15 @@ namespace elna::boot void walking_visitor::visit(while_statement *statement) { statement->branch().prerequisite().accept(this); - for (struct statement *const branch_statement : statement->branch().statements) + for (auto *branch_statement : statement->branch().statements) { branch_statement->accept(this); } - for (conditional_statements *const branch : statement->branches) + for (conditional_statements *branch : statement->branches) { branch->prerequisite().accept(this); - for (struct statement *const branch_statement : branch->statements) + for (auto *branch_statement : branch->statements) { branch_statement->accept(this); } @@ -276,7 +278,7 @@ namespace elna::boot void walking_visitor::visit(defer_statement *statement) { - for (struct statement *const block_statement : statement->statements) + for (auto *block_statement : statement->statements) { block_statement->accept(this); } @@ -291,18 +293,18 @@ namespace elna::boot statement->condition().accept(this); for (const switch_case& case_block : statement->cases) { - for (expression *const case_label : case_block.labels) + for (expression *case_label : case_block.labels) { case_label->accept(this); } - for (struct statement *const block_statement : case_block.statements) + for (auto *block_statement : case_block.statements) { block_statement->accept(this); } } if (statement->alternative != nullptr) { - for (struct statement *const block_statement : *statement->alternative) + for (auto *block_statement : *statement->alternative) { block_statement->accept(this); } @@ -312,7 +314,7 @@ namespace elna::boot void walking_visitor::visit(procedure_call *call) { call->callable().accept(this); - for (expression *const argument : call->arguments) + for (expression *argument : call->arguments) { argument->accept(this); } @@ -320,23 +322,23 @@ namespace elna::boot void walking_visitor::visit(unit *unit) { - for (import_declaration *const _import : unit->imports) + for (import_declaration *_import : unit->imports) { _import->accept(this); } - for (type_declaration *const type : unit->types) + for (type_declaration *type : unit->types) { type->accept(this); } - for (variable_declaration *const variable : unit->variables) + for (variable_declaration *variable : unit->variables) { variable->accept(this); } - for (procedure_declaration *const procedure : unit->procedures) + for (procedure_declaration *procedure : unit->procedures) { procedure->accept(this); } - for (statement *const entry_statement : unit->entry_point) + for (auto *entry_statement : unit->entry_point) { entry_statement->accept(this); } @@ -412,7 +414,7 @@ namespace elna::boot void walking_visitor::visit(array_constructor_expression *expression) { expression->m_element_type->accept(this); - for (auto element : expression->elements) + for (auto *element : expression->elements) { element->accept(this); } @@ -490,9 +492,7 @@ namespace elna::boot { } - node::~node() - { - } + node::~node() = default; const source_position& node::position() const { @@ -756,7 +756,7 @@ namespace elna::boot array_constructor_expression::~array_constructor_expression() { delete m_element_type; - for (expression *const element : elements) + for (const expression *element : elements) { delete element; } @@ -765,14 +765,14 @@ namespace elna::boot variable_declaration::variable_declaration(const source_position position, std::vector&& identifier, std::shared_ptr variable_type, expression *initializer) - : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), initializer(initializer) + : node(position), m_variable_type(std::move(variable_type)), identifiers(std::move(identifier)), initializer(initializer) { } variable_declaration::variable_declaration(const source_position position, std::vector&& identifier, std::shared_ptr variable_type, std::monostate) - : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), is_extern(true) + : node(position), m_variable_type(std::move(variable_type)), identifiers(std::move(identifier)), is_extern(true) { } @@ -792,7 +792,7 @@ namespace elna::boot } declaration::declaration(const source_position position, identifier_definition identifier) - : node(position), identifier(identifier) + : node(position), identifier(std::move(identifier)) { } @@ -804,10 +804,7 @@ namespace elna::boot procedure_type_expression::~procedure_type_expression() { - if (return_type.proper_type != nullptr) - { - delete return_type.proper_type; - } + delete return_type.proper_type; } void procedure_type_expression::accept(parser_visitor *visitor) @@ -838,14 +835,14 @@ namespace elna::boot procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier, procedure_type_expression *heading, procedure_body&& body) - : declaration(position, identifier), m_heading(heading), + : declaration(position, std::move(identifier)), m_heading(heading), body(std::make_optional(std::move(body))) { } procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier, procedure_type_expression *heading) - : declaration(position, identifier), m_heading(heading) + : declaration(position, std::move(identifier)), m_heading(heading) { } @@ -866,7 +863,7 @@ namespace elna::boot type_declaration::type_declaration(const source_position position, identifier_definition identifier, type_expression *underlying_type) - : declaration(position, identifier), m_underlying_type(underlying_type) + : declaration(position, std::move(identifier)), m_underlying_type(underlying_type) { } @@ -901,11 +898,11 @@ namespace elna::boot procedure_body::~procedure_body() { - for (statement *body_statement : this->entry_point) + for (const statement *body_statement : this->entry_point) { delete body_statement; } - for (variable_declaration *variable : this->variables) + for (const variable_declaration *variable : this->variables) { delete variable; } @@ -941,15 +938,15 @@ namespace elna::boot unit::~unit() { - for (procedure_declaration *procedure : this->procedures) + for (const procedure_declaration *procedure : this->procedures) { delete procedure; } - for (type_declaration *type : this->types) + for (const type_declaration *type : this->types) { delete type; } - for (import_declaration *declaration : this->imports) + for (const import_declaration *declaration : this->imports) { delete declaration; } @@ -972,7 +969,7 @@ namespace elna::boot defer_statement::~defer_statement() { - for (statement *body_statement : statements) + for (const statement *body_statement : statements) { delete body_statement; } @@ -988,9 +985,7 @@ namespace elna::boot { } - designator_expression::~designator_expression() - { - } + designator_expression::~designator_expression() = default; designator_expression *designator_expression::is_designator() { @@ -1001,21 +996,24 @@ namespace elna::boot { if (named_expression *node = is_named()) { - return visitor->visit(node); + visitor->visit(node); } else if (array_access_expression *node = is_array_access()) { - return visitor->visit(node); + visitor->visit(node); } else if (field_access_expression *node = is_field_access()) { - return visitor->visit(node); + visitor->visit(node); } else if (dereference_expression *node = is_dereference()) { - return visitor->visit(node); + visitor->visit(node); + } + else + { + __builtin_unreachable(); } - __builtin_unreachable(); } named_expression::named_expression(const source_position position, const std::string& name) @@ -1161,7 +1159,7 @@ namespace elna::boot unary_expression::unary_expression(const source_position position, expression *operand, const unary_operator operation) - : node(position), m_operand(std::move(operand)), m_operator(operation) + : node(position), m_operand(operand), m_operator(operation) { } @@ -1213,7 +1211,7 @@ namespace elna::boot procedure_call::~procedure_call() { - for (expression *const argument : arguments) + for (const expression *argument : arguments) { delete argument; } @@ -1288,7 +1286,7 @@ namespace elna::boot conditional_statements::~conditional_statements() { delete m_prerequisite; - for (auto statement : statements) + for (auto *statement : statements) { delete statement; } @@ -1376,7 +1374,7 @@ namespace elna::boot if_statement::~if_statement() { delete m_branch; - for (conditional_statements *const branch : branches) + for (const conditional_statements *branch : branches) { delete branch; } @@ -1412,7 +1410,7 @@ namespace elna::boot while_statement::~while_statement() { delete m_branch; - for (conditional_statements *const branch : branches) + for (const conditional_statements *branch : branches) { delete branch; } @@ -1422,37 +1420,38 @@ namespace elna::boot { switch (operation) { - case binary_operator::sum: + using enum binary_operator; + case sum: return "+"; - case binary_operator::subtraction: + case subtraction: return "-"; - case binary_operator::multiplication: + case multiplication: return "*"; - case binary_operator::division: + case division: return "/"; - case binary_operator::remainder: + case remainder: return "%"; - case binary_operator::equals: + case equals: return "="; - case binary_operator::not_equals: + case not_equals: return "<>"; - case binary_operator::less: + case less: return "<"; - case binary_operator::less_equal: + case less_equal: return "<="; - case binary_operator::greater: + case greater: return ">"; - case binary_operator::greater_equal: + case greater_equal: return ">="; - case binary_operator::conjunction: + case conjunction: return "and"; - case binary_operator::disjunction: + case disjunction: return "or"; - case binary_operator::exclusive_disjunction: + case exclusive_disjunction: return "xor"; - case binary_operator::shift_left: + case shift_left: return "<<"; - case binary_operator::shift_right: + case shift_right: return ">>"; } __builtin_unreachable(); diff --git a/boot/dependency.cc b/boot/dependency.cc index 7bd86fb..dc827fa 100644 --- a/boot/dependency.cc +++ b/boot/dependency.cc @@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see #include #include -#include +#include #include "elna/boot/driver.h" #include "elna/boot/name_analysis.h" @@ -35,7 +35,7 @@ namespace elna::boot yy::parser parser(tokenizer, parse_driver); dependency outcome; - if (parser()) + if (parser() != 0) { std::swap(outcome.errors(), parse_driver.errors()); return outcome; @@ -56,7 +56,7 @@ namespace elna::boot return outcome; } - error_list analyze_semantics(std::unique_ptr& tree, symbol_bag bag, + error_list analyze_semantics(std::unique_ptr& tree, const symbol_bag& bag, const target_info& target) { name_analysis_visitor name_analyser(bag); diff --git a/boot/driver.cc b/boot/driver.cc index 8dc95f8..374bcc9 100644 --- a/boot/driver.cc +++ b/boot/driver.cc @@ -78,7 +78,7 @@ namespace elna::boot current_position += 2; std::size_t processed; - char character = static_cast(std::stoi(current_position, &processed, 16)); + char const character = static_cast(std::stoi(current_position, &processed, 16)); if (processed == 0) { return std::nullopt; @@ -93,7 +93,7 @@ namespace elna::boot { ++current_position; - char escape = escape_char(*current_position); + char const escape = escape_char(*current_position); if (escape == escape_invalid_char) { return std::nullopt; diff --git a/boot/evaluator.cc b/boot/evaluator.cc index 1acadd3..b7edd3a 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -86,7 +86,7 @@ namespace elna::boot std::optional evaluator::evaluate_literal(literal_expression& subject) { - type decoration = subject.type_decoration; + type const decoration = subject.type_decoration; if (is_primitive_type(decoration, "Int")) { @@ -171,16 +171,16 @@ namespace elna::boot } if (subject.operation() == unary_operator::negation) { - return std::visit([](auto v) -> std::optional { - using T = std::decay_t; + return std::visit([](auto value) -> std::optional { + using T = std::decay_t; if constexpr (std::is_same_v) { - return constant_value{ !v }; + return constant_value{ !value }; } else if constexpr (std::is_integral_v) { - return constant_value{ ~v }; + return constant_value{ ~value }; } return std::nullopt; }, operand.value()); @@ -232,16 +232,17 @@ namespace elna::boot } template - static std::optional evaluate_operation(binary_operator op, T lhs, T rhs) + static std::optional evaluate_operation(binary_operator operation, T lhs, T rhs) { if constexpr (std::is_same_v || std::is_same_v) { - switch (op) + switch (operation) { - case binary_operator::equals: + using enum binary_operator; + case equals: return constant_value{ true }; - case binary_operator::not_equals: + case not_equals: return constant_value{ false }; default: return std::nullopt; @@ -249,36 +250,37 @@ namespace elna::boot } else { - switch (op) + switch (operation) { - case binary_operator::sum: + using enum binary_operator; + case sum: if constexpr (std::is_arithmetic_v && !std::is_same_v) { - if (auto r = add_overflow(lhs, rhs)) + if (auto result = add_overflow(lhs, rhs)) { - return constant_value{ *r }; + return constant_value{ *result }; } } return std::nullopt; - case binary_operator::subtraction: + case subtraction: if constexpr (std::is_arithmetic_v && !std::is_same_v) { - if (auto r = sub_overflow(lhs, rhs)) + if (auto result = sub_overflow(lhs, rhs)) { - return constant_value{ *r }; + return constant_value{ *result }; } } return std::nullopt; - case binary_operator::multiplication: + case multiplication: if constexpr (std::is_arithmetic_v && !std::is_same_v) { - if (auto r = mul_overflow(lhs, rhs)) + if (auto result = mul_overflow(lhs, rhs)) { - return constant_value{ *r }; + return constant_value{ *result }; } } return std::nullopt; - case binary_operator::division: + case division: if constexpr (std::is_arithmetic_v && !std::is_same_v) { if (rhs != static_cast(0)) @@ -287,7 +289,7 @@ namespace elna::boot } } return std::nullopt; - case binary_operator::remainder: + case remainder: if constexpr (std::is_integral_v && !std::is_same_v) { if (rhs != static_cast(0)) @@ -296,25 +298,25 @@ namespace elna::boot } } return std::nullopt; - case binary_operator::disjunction: + case disjunction: if constexpr (std::is_integral_v) { return constant_value{ lhs | rhs }; } return std::nullopt; - case binary_operator::conjunction: + case conjunction: if constexpr (std::is_integral_v) { return constant_value{ lhs & rhs }; } return std::nullopt; - case binary_operator::exclusive_disjunction: + case exclusive_disjunction: if constexpr (std::is_integral_v) { return constant_value{ lhs ^ rhs }; } return std::nullopt; - case binary_operator::shift_left: + case shift_left: if constexpr (std::is_integral_v && !std::is_same_v) { if (rhs < 0 || static_cast>(rhs) >= std::numeric_limits::digits) @@ -324,35 +326,35 @@ namespace elna::boot return constant_value{ lhs << rhs }; } return std::nullopt; - case binary_operator::shift_right: + case shift_right: if constexpr (std::is_integral_v) { return constant_value{ lhs >> rhs }; } return std::nullopt; - case binary_operator::equals: + case equals: return constant_value{ lhs == rhs }; - case binary_operator::not_equals: + case not_equals: return constant_value{ lhs != rhs }; - case binary_operator::less: + case less: if constexpr (std::is_arithmetic_v && !std::is_same_v) { return constant_value{ lhs < rhs }; } return std::nullopt; - case binary_operator::greater: + case greater: if constexpr (std::is_arithmetic_v && !std::is_same_v) { return constant_value{ lhs > rhs }; } return std::nullopt; - case binary_operator::less_equal: + case less_equal: if constexpr (std::is_arithmetic_v && !std::is_same_v) { return constant_value{ lhs <= rhs }; } return std::nullopt; - case binary_operator::greater_equal: + case greater_equal: if constexpr (std::is_arithmetic_v && !std::is_same_v) { return constant_value{ lhs >= rhs }; @@ -373,7 +375,7 @@ namespace elna::boot { return std::nullopt; } - return std::visit([this, &rhs, operation = subject.operation()](auto&& lhs_value) { + return std::visit([&rhs, operation = subject.operation()](auto&& lhs_value) { using T = std::decay_t; auto rhs_value = std::get(rhs.value()); @@ -395,7 +397,7 @@ namespace elna::boot std::optional evaluator::evaluate_traits_size(const type& subject) { - type resolved = resolve_underlying_type(subject); + type const resolved = resolve_underlying_type(subject); if (is_primitive_type(resolved, "Int")) { @@ -413,11 +415,8 @@ namespace elna::boot { return target.float_size; } - else if (is_primitive_type(resolved, "Pointer")) - { - return target.pointer_size; - } - else if (resolved.get() != nullptr) + else if (is_primitive_type(resolved, "Pointer") + || resolved.get() != nullptr) { return target.pointer_size; } @@ -433,7 +432,7 @@ namespace elna::boot std::optional evaluator::evaluate_traits_alignment(const type& subject) { - type resolved = resolve_underlying_type(subject); + type const resolved = resolve_underlying_type(subject); if (is_primitive_type(resolved, "Int")) { @@ -521,7 +520,7 @@ namespace elna::boot } else if (subject.name.name() == "min") { - type resolved = resolve_underlying_type(subject.types.front()); + type const resolved = resolve_underlying_type(subject.types.front()); if (is_primitive_type(resolved, "Int")) { @@ -542,7 +541,7 @@ namespace elna::boot } else if (subject.name.name() == "max") { - type resolved = resolve_underlying_type(subject.types.front()); + type const resolved = resolve_underlying_type(subject.types.front()); if (is_primitive_type(resolved, "Int")) { @@ -554,7 +553,7 @@ namespace elna::boot } if (is_primitive_type(resolved, "Char")) { - return constant_value{ static_cast(255) }; + return constant_value{ std::numeric_limits::max() }; } if (auto enumeration = resolved.get()) { diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index b13c043..22b7814 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/name_analysis.h" #include +#include namespace elna::boot { @@ -95,7 +96,7 @@ namespace elna::boot } name_analysis_visitor::name_analysis_visitor(symbol_bag bag) - : error_container(), bag(bag) + : bag(std::move(bag)) { } @@ -120,10 +121,10 @@ namespace elna::boot std::pair> result_type{ procedure_type(result_return), std::vector() }; - for (auto& [parameter_names, parameters_type] : expression.parameters) + for (const auto& [parameter_names, parameters_type] : expression.parameters) { parameters_type->accept(this); - for (auto& parameter_name : parameter_names) + for (const auto& parameter_name : parameter_names) { result_type.first.parameters.push_back(this->current_type); result_type.second.push_back(parameter_name.name()); @@ -139,7 +140,7 @@ namespace elna::boot type name_analysis_visitor::lookup_field(const type& composite_type, const std::string& field_name) { - type resolved_type = resolve_underlying_type(composite_type); + type const resolved_type = resolve_underlying_type(composite_type); if (auto record = resolved_type.get()) { @@ -225,21 +226,21 @@ namespace elna::boot } for (auto& field : record->fields) { - names.insert({ field.first, field_origin{ std::nullopt, composite_type } }); + names.insert({ field.first, field_origin{ .declaration = std::nullopt, .base_type = composite_type } }); } } std::vector name_analysis_visitor::build_composite_type( const std::vector& fields, std::map& field_names, - type aggregate) + const type& aggregate) { std::vector result; - for (auto& field : fields) + for (const auto& field : fields) { field.second->accept(this); - for (auto& field_name : field.first) + for (const auto& field_name : field.first) { auto existing = field_names.find(field_name.name()); if (existing != field_names.end()) @@ -260,8 +261,8 @@ namespace elna::boot else { field_names.insert({ field_name.name(), - field_origin{ field.second->position(), type() } }); - result.push_back(std::make_pair(field_name.name(), this->current_type)); + field_origin{ .declaration = field.second->position(), .base_type = type() } }); + result.emplace_back(field_name.name(), this->current_type); } } } @@ -350,7 +351,7 @@ namespace elna::boot { expression->m_element_type->accept(this); auto element_type = this->current_type; - for (auto element : expression->elements) + for (auto *element : expression->elements) { element->accept(this); } @@ -359,7 +360,7 @@ namespace elna::boot void name_analysis_visitor::visit(procedure_type_expression *expression) { - std::shared_ptr result_type = + std::shared_ptr const result_type = std::make_shared(std::move(build_procedure(*expression).first)); this->current_type = type(result_type); @@ -368,16 +369,17 @@ namespace elna::boot void name_analysis_visitor::visit(enumeration_type_expression *expression) { std::vector member_names; - for (auto& member : expression->members) + member_names.reserve(expression->members.size()); +for (const auto& member : expression->members) { member_names.emplace_back(member.name()); } - std::shared_ptr result_type = std::make_shared( + std::shared_ptr const result_type = std::make_shared( member_names); std::map seen; - type aggregate(result_type); + type const aggregate(result_type); - for (auto& member : expression->members) + for (const auto& member : expression->members) { auto existing = seen.find(member.name()); if (existing != seen.end()) @@ -536,8 +538,8 @@ namespace elna::boot if (!trait->type_decoration.empty()) { - type resolved = resolve_underlying_type(trait->type_decoration); - bool is_enum = resolved.get() != nullptr; + type const resolved = resolve_underlying_type(trait->type_decoration); + bool const is_enum = resolved.get() != nullptr; if (!is_enum && !is_discrete_type(resolved)) { @@ -560,15 +562,16 @@ namespace elna::boot switch (expression->operation()) { - case binary_operator::equals: - case binary_operator::not_equals: - case binary_operator::less: - case binary_operator::greater: - case binary_operator::less_equal: - case binary_operator::greater_equal: + using enum binary_operator; + case equals: + case not_equals: + case less: + case greater: + case less_equal: + case greater_equal: expression->type_decoration = lookup_primitive_type("Bool"); break; - case binary_operator::subtraction: + case subtraction: if (expression->lhs().type_decoration.get() && expression->rhs().type_decoration.get()) { @@ -626,7 +629,7 @@ namespace elna::boot { walking_visitor::visit(expression); expression->type_decoration = lookup_field(expression->base().type_decoration, expression->field().name()); - auto is_designator = expression->base().is_designator(); + auto *is_designator = expression->base().is_designator(); if (expression->type_decoration.empty() && is_designator != nullptr && is_designator->is_named() != nullptr) { @@ -725,7 +728,7 @@ namespace elna::boot } declaration_visitor::declaration_visitor() - : error_container() + { } diff --git a/boot/result.cc b/boot/result.cc index 5f3c516..86b0e7a 100644 --- a/boot/result.cc +++ b/boot/result.cc @@ -39,16 +39,6 @@ namespace elna::boot return this->m_line != 0 || this->m_column != 0; } - bool location::operator==(const location& that) const - { - return this->m_line == that.m_line && this->m_column == that.m_column; - } - - bool location::operator!=(const location& that) const - { - return !(*this == that); - } - source_position::source_position(location start, location end) : m_start(start), m_end(end) { @@ -99,22 +89,30 @@ namespace elna::boot return this->m_position; } - bool identifier::operator==(const identifier& that) const + std::strong_ordering identifier::operator<=>(const identifier& that) const { - return this->m_name == that.m_name; - } + auto comparison = this->m_name.compare(that.name()); - bool identifier::operator!=(const identifier& that) const - { - return !(*this == that); + if (comparison < 0) + { + return std::strong_ordering::less; + } + else if (comparison > 0) + { + return std::strong_ordering::greater; + } + else + { + return std::strong_ordering::equal; + } } - bool identifier::operator==(const std::string& that) const + bool identifier::operator==(std::string_view that) const { return this->m_name == that; } - bool identifier::operator!=(const std::string& that) const + bool identifier::operator!=(std::string_view that) const { return !(*this == that); } @@ -142,7 +140,7 @@ namespace elna::boot } std::size_t std::hash::operator()( - const elna::boot::identifier& key) const + const elna::boot::identifier& key) const noexcept { return std::hash{}(key.name()); } diff --git a/boot/symbol.cc b/boot/symbol.cc index 7b45612..d7a1cae 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/symbol.h" +#include + namespace elna::boot { type::type(std::shared_ptr alias) @@ -64,14 +66,16 @@ namespace elna::boot { if constexpr (std::is_same_v) { - if (auto *wp = std::get_if>(&payload)) - return wp->lock(); + if (const auto *weak_pointer = std::get_if>(&payload)) { + return weak_pointer->lock(); +} return nullptr; } else { - if (auto *sp = std::get_if>(&payload)) - return *sp; + if (auto *shared_pointer = std::get_if>(&payload)) { + return *shared_pointer; +} return nullptr; } } @@ -93,8 +97,8 @@ namespace elna::boot bool type::operator==(const type& other) const { - type resolved_this = resolve_aliases(*this); - type resolved_that = resolve_aliases(other); + type const resolved_this = resolve_aliases(*this); + type const resolved_that = resolve_aliases(other); if (auto left_record = resolved_this.get()) { @@ -146,64 +150,79 @@ namespace elna::boot std::string type::to_string() const { - return std::visit([](const auto& p) -> std::string { - using T = std::decay_t; + return std::visit([](const auto& payload) -> std::string { + using T = std::decay_t; if constexpr (std::is_same_v) + { return ""; + } else if constexpr (std::is_same_v>) - return p.lock()->name; + { + return payload.lock()->name; + } else if constexpr (std::is_same_v>) - return p->identifier; + { + return payload->identifier; + } else if constexpr (std::is_same_v>) - return "^" + p->base.to_string(); + { + return "^" + payload->base.to_string(); + } else if constexpr (std::is_same_v>) - return "const " + p->unqualified.to_string(); + { + return "const " + payload->unqualified.to_string(); + } else if constexpr (std::is_same_v>) - return "[" + std::to_string(p->size) + "]" + p->base.to_string(); + { + return "[" + std::to_string(payload->size) + "]" + payload->base.to_string(); + } else if constexpr (std::is_same_v>) { - if (p->base.empty()) - return "record ... end"; - else - return "record(" + p->base.to_string() + ") ... end"; + return payload->base.empty() + ? "record ... end" + : "record(" + payload->base.to_string() + ") ... end"; } else if constexpr (std::is_same_v>) { std::string result = "proc("; - for (std::size_t i = 0; i < p->parameters.size(); ++i) + for (std::size_t i = 0; i < payload->parameters.size(); ++i) { - if (i > 0) result += ", "; - result += p->parameters[i].to_string(); + if (i > 0) { result += ", "; +} + result += payload->parameters[i].to_string(); } result += ")"; - if (p->return_type.no_return) + if (payload->return_type.no_return) { result += ": !"; - else if (!p->return_type.proper_type.empty()) - result += ": " + p->return_type.proper_type.to_string(); + } else if (!payload->return_type.proper_type.empty()) { + result += ": " + payload->return_type.proper_type.to_string(); +} return result; } else if constexpr (std::is_same_v>) + { return "(enumeration)"; + } }, payload); } alias_type::alias_type(const std::string& name) - : name(name), referent() + : name(name) { } pointer_type::pointer_type(type base) - : base(base) + : base(std::move(base)) { } constant_type::constant_type(type unqualified) - : unqualified(unqualified) + : unqualified(std::move(unqualified)) { } array_type::array_type(type base, std::uint64_t size) - : base(base), size(size) + : base(std::move(base)), size(size) { } @@ -213,12 +232,12 @@ namespace elna::boot } record_type::record_type(type base) - : base(base) + : base(std::move(base)) { } procedure_type::procedure_type(return_t return_type) - : return_type(return_type) + : return_type(std::move(return_type)) { } @@ -227,9 +246,7 @@ namespace elna::boot { } - info::~info() - { - } + info::~info() = default; std::shared_ptr info::is_type() { @@ -246,7 +263,7 @@ namespace elna::boot return nullptr; } - type_info::type_info(const type symbol) + type_info::type_info(const type& symbol) : symbol(symbol) { } @@ -256,9 +273,9 @@ namespace elna::boot return std::static_pointer_cast(shared_from_this()); } - procedure_info::procedure_info(const procedure_type symbol, const std::vector names, + procedure_info::procedure_info(const procedure_type& symbol, const std::vector& names, std::shared_ptr scope) - : symbol(symbol), names(names), scope(scope) + : symbol(symbol), names(names), scope(std::move(scope)) { } @@ -272,7 +289,7 @@ namespace elna::boot return this->scope == nullptr; } - variable_info::variable_info(const type symbol, bool is_extern) + variable_info::variable_info(const type& symbol, bool is_extern) : symbol(symbol), is_extern(is_extern) { } @@ -293,19 +310,19 @@ namespace elna::boot result->enter("Float", std::make_shared(type(std::make_shared("Float")))); result->enter("String", std::make_shared(type(std::make_shared("String")))); - type boolean = type(std::make_shared("Bool")); + type const boolean = type(std::make_shared("Bool")); result->enter("Bool", std::make_shared(boolean)); procedure_type assert_symbol{ procedure_type::return_t() }; assert_symbol.parameters.push_back(boolean); - std::shared_ptr assert_info = std::make_shared(assert_symbol, + std::shared_ptr const assert_info = std::make_shared(assert_symbol, std::vector{ "condition" }); result->enter("assert", assert_info); return result; } - symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr global_table) + symbol_bag::symbol_bag(forward_table&& unresolved, const std::shared_ptr& global_table) : unresolved(unresolved) { this->symbols = std::make_shared(global_table); @@ -313,7 +330,7 @@ namespace elna::boot std::shared_ptr symbol_bag::lookup(const std::string& name) { - for (auto import_bag : this->imports) + for (const auto& import_bag : this->imports) { if (auto result = import_bag->lookup(name)) { @@ -323,7 +340,7 @@ namespace elna::boot return this->symbols->lookup(name); } - bool symbol_bag::enter(const std::string& name, std::shared_ptr entry) + bool symbol_bag::enter(const std::string& name, const std::shared_ptr& entry) { return this->symbols->enter(name, entry); } @@ -336,7 +353,7 @@ namespace elna::boot void symbol_bag::enter(std::shared_ptr child) { - this->symbols = child; + this->symbols = std::move(child); } std::shared_ptr symbol_bag::leave() @@ -383,7 +400,7 @@ namespace elna::boot return m_exported; } - type resolve_underlying_type(std::shared_ptr alias) + type resolve_underlying_type(const std::shared_ptr& alias) { return resolve_underlying_type(alias->referent); } @@ -422,7 +439,7 @@ namespace elna::boot bool is_numeric_type(const type& checked) { - type resolved = resolve_underlying_type(checked); + type const resolved = resolve_underlying_type(checked); return is_primitive_type(resolved, "Int") || is_primitive_type(resolved, "Word") @@ -431,7 +448,7 @@ namespace elna::boot bool is_integral_type(const type& checked) { - type resolved = resolve_underlying_type(checked); + type const resolved = resolve_underlying_type(checked); return is_primitive_type(resolved, "Int") || is_primitive_type(resolved, "Word"); @@ -439,7 +456,7 @@ namespace elna::boot bool is_discrete_type(const type& checked) { - type resolved = resolve_underlying_type(checked); + type const resolved = resolve_underlying_type(checked); return is_primitive_type(resolved, "Int") || is_primitive_type(resolved, "Word") diff --git a/boot/type_check.cc b/boot/type_check.cc index d9f3071..c5fb062 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/type_check.h" #include +#include namespace elna::boot { @@ -33,7 +34,7 @@ namespace elna::boot type_mismatch_error::type_mismatch_error(const source_position position, type expected, type actual) - : error(position), expected(expected), actual(actual) + : error(position), expected(std::move(expected)), actual(std::move(actual)) { } @@ -45,7 +46,7 @@ namespace elna::boot constant_assignment_error::constant_assignment_error(const source_position position, type assignee) - : error(position), assignee(assignee) + : error(position), assignee(std::move(assignee)) { } @@ -57,15 +58,15 @@ namespace elna::boot field_not_found_error::field_not_found_error(const identifier& field_name, type composite_type) - : error(field_name.position()), field_name(field_name.name()), composite_type(composite_type) + : error(field_name.position()), field_name(field_name.name()), composite_type(std::move(composite_type)) { } std::string field_not_found_error::what() const { - type resolved = resolve_underlying_type(composite_type); - bool is_enum = resolved.get() != nullptr; - bool is_record = resolved.get() != nullptr; + type const resolved = resolve_underlying_type(composite_type); + bool const is_enum = resolved.get() != nullptr; + bool const is_record = resolved.get() != nullptr; if (is_enum || is_record) { @@ -87,16 +88,16 @@ namespace elna::boot duplicate_member_error::duplicate_member_error(const boot::identifier& member_name, type aggregate, std::optional original, std::optional base_name) - : error(member_name.position()), member_name(member_name.name()), aggregate(aggregate), - original(original), base_name(base_name) + : error(member_name.position()), member_name(member_name.name()), aggregate(std::move(aggregate)), + original(original), base_name(std::move(base_name)) { } std::string duplicate_member_error::what() const { - type resolved = resolve_underlying_type(aggregate); - bool is_enum = resolved.get() != nullptr; - std::string kind = is_enum ? "member" : "field"; + type const resolved = resolve_underlying_type(aggregate); + bool const is_enum = resolved.get() != nullptr; + std::string const kind = is_enum ? "member" : "field"; std::string message = is_enum ? "Enumeration" : "Record"; if (auto alias = aggregate.get()) @@ -142,7 +143,7 @@ namespace elna::boot return_error::return_error(const std::string& identifier, const source_position position, type return_type) - : error(position), identifier(identifier), return_type(return_type) + : error(position), identifier(identifier), return_type(std::move(return_type)) { } @@ -159,7 +160,7 @@ namespace elna::boot } base_type_error::base_type_error(type actual, const source_position position) - : error(position), actual(actual) + : error(position), actual(std::move(actual)) { } @@ -190,7 +191,7 @@ namespace elna::boot unsupported_trait_type_error::unsupported_trait_type_error(const identifier& trait, type actual) - : error(trait.position()), actual(actual), trait_name(trait.name()) + : error(trait.position()), actual(std::move(actual)), trait_name(trait.name()) { } @@ -201,22 +202,23 @@ namespace elna::boot } unary_operation_error::unary_operation_error(const source_position position, - type actual, unary_operator op) - : error(position), actual(actual), op(op) + type actual, unary_operator operation) + : error(position), actual(std::move(actual)), op(operation) { } - char unary_operation_error::unary_operator_symbol(unary_operator op) + char unary_operation_error::unary_operator_symbol(unary_operator operation) { - switch (op) + switch (operation) { - case unary_operator::reference: + using enum unary_operator; + case reference: return '@'; - case unary_operator::negation: + case negation: return '~'; - case unary_operator::minus: + case minus: return '-'; - case unary_operator::plus: + case plus: return '+'; } __builtin_unreachable(); @@ -261,10 +263,10 @@ namespace elna::boot return false; } - bool type_analysis_visitor::check_unresolved_symbol(std::shared_ptr alias, + bool type_analysis_visitor::check_unresolved_symbol(const std::shared_ptr& alias, std::vector& alias_path) { - if (std::find(std::cbegin(alias_path), std::cend(alias_path), alias->name) != std::cend(alias_path)) + if (std::ranges::find(alias_path, alias->name) != std::cend(alias_path)) { return false; } @@ -295,7 +297,7 @@ namespace elna::boot return false; } - assign_check::verdict assign_check::guard_const_laundering() + assign_check::verdict assign_check::guard_const_laundering() const { if (!is_primitive_type(ctx.aliased_assignee, "Pointer")) { @@ -314,12 +316,12 @@ namespace elna::boot return verdict::pass; } - assign_check::verdict assign_check::check_exact_match() + assign_check::verdict assign_check::check_exact_match() const { return ctx.resolved_assignee == ctx.resolved_assignment ? verdict::accept : verdict::pass; } - assign_check::verdict assign_check::check_pointer_hatch() + assign_check::verdict assign_check::check_pointer_hatch() const { if (is_primitive_type(ctx.resolved_assignee, "Pointer") && is_any_pointer_type(ctx.resolved_assignment)) @@ -334,7 +336,7 @@ namespace elna::boot return verdict::pass; } - assign_check::verdict assign_check::check_pointer_conversion() + assign_check::verdict assign_check::check_pointer_conversion() const { auto assignee_ptr = ctx.resolved_assignee.get(); auto assignment_ptr = ctx.resolved_assignment.get(); @@ -394,7 +396,7 @@ namespace elna::boot } type_analysis_visitor::type_analysis_visitor(symbol_bag bag, const target_info& target) - : error_container(), bag(bag), target(target) + : bag(std::move(bag)), target(target) { } @@ -412,8 +414,8 @@ namespace elna::boot { if (declaration->body.value().return_expression != nullptr) { - expression *return_expr = declaration->body.value().return_expression; - type return_type = this->current_procedure->symbol.return_type.proper_type; + const expression *return_expr = declaration->body.value().return_expression; + type const return_type = this->current_procedure->symbol.return_type.proper_type; if (!return_type.empty()) { @@ -475,12 +477,12 @@ namespace elna::boot } // Record const variable initializers so later declarations // can chain through them. - for (const auto& id : declaration->identifiers) + for (const auto& identifier : declaration->identifiers) { - if (auto var = this->bag.lookup(id.name())->is_variable(); + if (auto var = this->bag.lookup(identifier.name())->is_variable(); resolve_aliases(var->symbol).get() != nullptr) { - this->evaluated_initializers[id.name()] = declaration->initializer; + this->evaluated_initializers[identifier.name()] = declaration->initializer; } } for (const identifier_definition& variable_identifier : declaration->identifiers) @@ -498,11 +500,11 @@ namespace elna::boot void type_analysis_visitor::visit(case_statement *statement) { walking_visitor::visit(statement); - type condition_type = resolve_underlying_type(statement->condition().type_decoration); + type const condition_type = resolve_underlying_type(statement->condition().type_decoration); for (const switch_case& case_block : statement->cases) { - for (expression *const case_label : case_block.labels) + for (const expression *case_label : case_block.labels) { if (!is_assignable_from(condition_type, case_label->type_decoration)) { @@ -532,7 +534,7 @@ namespace elna::boot { if (expression->base.has_value()) { - type base_type = resolve_underlying_type(this->bag.lookup(expression->base.value().name())->is_type()->symbol); + type const base_type = resolve_underlying_type(this->bag.lookup(expression->base.value().name())->is_type()->symbol); if (base_type.get() == nullptr) { add_error(base_type, expression->position()); @@ -617,7 +619,7 @@ namespace elna::boot expression->position()); return; } - for (auto element : expression->elements) + for (auto *element : expression->elements) { if (!is_assignable_from(array->base, element->type_decoration)) { @@ -631,33 +633,33 @@ namespace elna::boot { walking_visitor::visit(expression); - auto op = expression->operation(); - type resolved = resolve_underlying_type(expression->operand().type_decoration); + auto operation = expression->operation(); + type const resolved = resolve_underlying_type(expression->operand().type_decoration); - if (op == unary_operator::plus) + if (operation == unary_operator::plus) { if (!is_numeric_type(resolved)) { add_error(expression->position(), - expression->operand().type_decoration, op); + expression->operand().type_decoration, operation); } } - else if (op == unary_operator::minus) + else if (operation == unary_operator::minus) { if (!is_primitive_type(resolved, "Int") && !is_primitive_type(resolved, "Float")) { add_error(expression->position(), - expression->operand().type_decoration, op); + expression->operand().type_decoration, operation); } } - else if (op == unary_operator::negation) + else if (operation == unary_operator::negation) { if (!is_primitive_type(resolved, "Bool") && !is_integral_type(resolved)) { add_error(expression->position(), - expression->operand().type_decoration, op); + expression->operand().type_decoration, operation); } } } -- cgit v1.2.3