aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy29
-rw-r--r--boot/ast.cc137
-rw-r--r--boot/dependency.cc6
-rw-r--r--boot/driver.cc4
-rw-r--r--boot/evaluator.cc85
-rw-r--r--boot/name_analysis.cc57
-rw-r--r--boot/result.cc36
-rw-r--r--boot/symbol.cc109
-rw-r--r--boot/type_check.cc94
-rw-r--r--gcc/Make-lang.in2
-rw-r--r--gcc/gcc/elna-generic.cc55
-rw-r--r--include/elna/boot/ast.h180
-rw-r--r--include/elna/boot/dependency.h8
-rw-r--r--include/elna/boot/driver.h2
-rw-r--r--include/elna/boot/evaluator.h2
-rw-r--r--include/elna/boot/name_analysis.h4
-rw-r--r--include/elna/boot/result.h29
-rw-r--r--include/elna/boot/symbol.h43
-rw-r--r--include/elna/boot/type_check.h21
-rw-r--r--rakelib/gcc.rake11
20 files changed, 485 insertions, 429 deletions
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000..2e01fb3
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,29 @@
+---
+HeaderFilterRegex: '^.*/include/elna/.*\.h$'
+Checks: |
+ bugprone-*,
+ performance-*,
+ misc-*,
+ readability-*,
+ modernize-*,
+ concurrency-*,
+ cert-*,
+ -bugprone-easily-swappable-parameters,
+ -misc-include-cleaner,
+ -misc-multiple-inheritance,
+ -misc-non-private-member-variables-in-classes,
+ -misc-no-recursion,
+ -misc-use-anonymous-namespace,
+ -readability-avoid-const-params-in-decls,
+ -readability-else-after-return,
+ -readability-function-cognitive-complexity,
+ -readability-named-parameter,
+ -bugprone-unchecked-optional-access,
+ -performance-enum-size,
+ -modernize-use-trailing-return-type,
+ -modernize-use-nodiscard,
+ -modernize-pass-by-value,
+ -modernize-use-auto,
+ -modernize-return-braced-init-list,
+ # False positives: does not see delete inside loop bodies of destructors.
+ -modernize-use-equals-default,
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 <utility>
+
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_definition>&& identifier, std::shared_ptr<type_expression> 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_definition>&& identifier, std::shared_ptr<type_expression> 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<procedure_body>(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 <fstream>
#include <sstream>
-#include <string.h>
+#include <cstring>
#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<unit>& tree, symbol_bag bag,
+ error_list analyze_semantics(std::unique_ptr<unit>& 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<char>(std::stoi(current_position, &processed, 16));
+ char const character = static_cast<char>(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<constant_value> 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<constant_value> {
- using T = std::decay_t<decltype(v)>;
+ return std::visit([](auto value) -> std::optional<constant_value> {
+ using T = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<T, bool>)
{
- return constant_value{ !v };
+ return constant_value{ !value };
}
else if constexpr (std::is_integral_v<T>)
{
- return constant_value{ ~v };
+ return constant_value{ ~value };
}
return std::nullopt;
}, operand.value());
@@ -232,16 +232,17 @@ namespace elna::boot
}
template<typename T>
- static std::optional<constant_value> evaluate_operation(binary_operator op, T lhs, T rhs)
+ static std::optional<constant_value> evaluate_operation(binary_operator operation, T lhs, T rhs)
{
if constexpr (std::is_same_v<T, std::nullptr_t>
|| std::is_same_v<T, compound_constant>)
{
- 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<T> && !std::is_same_v<T, bool>)
{
- 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<T> && !std::is_same_v<T, bool>)
{
- 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<T> && !std::is_same_v<T, bool>)
{
- 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<T> && !std::is_same_v<T, bool>)
{
if (rhs != static_cast<T>(0))
@@ -287,7 +289,7 @@ namespace elna::boot
}
}
return std::nullopt;
- case binary_operator::remainder:
+ case remainder:
if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
{
if (rhs != static_cast<T>(0))
@@ -296,25 +298,25 @@ namespace elna::boot
}
}
return std::nullopt;
- case binary_operator::disjunction:
+ case disjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs | rhs };
}
return std::nullopt;
- case binary_operator::conjunction:
+ case conjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs & rhs };
}
return std::nullopt;
- case binary_operator::exclusive_disjunction:
+ case exclusive_disjunction:
if constexpr (std::is_integral_v<T>)
{
return constant_value{ lhs ^ rhs };
}
return std::nullopt;
- case binary_operator::shift_left:
+ case shift_left:
if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>)
{
if (rhs < 0 || static_cast<std::make_unsigned_t<T>>(rhs) >= std::numeric_limits<T>::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<T>)
{
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<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs < rhs };
}
return std::nullopt;
- case binary_operator::greater:
+ case greater:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs > rhs };
}
return std::nullopt;
- case binary_operator::less_equal:
+ case less_equal:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
return constant_value{ lhs <= rhs };
}
return std::nullopt;
- case binary_operator::greater_equal:
+ case greater_equal:
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
{
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<decltype(lhs_value)>;
auto rhs_value = std::get<T>(rhs.value());
@@ -395,7 +397,7 @@ namespace elna::boot
std::optional<std::size_t> 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<pointer_type>() != nullptr)
+ else if (is_primitive_type(resolved, "Pointer")
+ || resolved.get<pointer_type>() != nullptr)
{
return target.pointer_size;
}
@@ -433,7 +432,7 @@ namespace elna::boot
std::optional<std::size_t> 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<unsigned char>(255) };
+ return constant_value{ std::numeric_limits<unsigned char>::max() };
}
if (auto enumeration = resolved.get<enumeration_type>())
{
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 <algorithm>
+#include <utility>
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<procedure_type, std::vector<std::string>> result_type{
procedure_type(result_return), std::vector<std::string>()
};
- 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<record_type>())
{
@@ -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<type_field> name_analysis_visitor::build_composite_type(
const std::vector<field_declaration>& fields,
std::map<std::string, field_origin>& field_names,
- type aggregate)
+ const type& aggregate)
{
std::vector<type_field> 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<procedure_type> result_type =
+ std::shared_ptr<procedure_type> const result_type =
std::make_shared<procedure_type>(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<std::string> 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<enumeration_type> result_type = std::make_shared<enumeration_type>(
+ std::shared_ptr<enumeration_type> const result_type = std::make_shared<enumeration_type>(
member_names);
std::map<std::string, source_position> 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<enumeration_type>() != nullptr;
+ type const resolved = resolve_underlying_type(trait->type_decoration);
+ bool const is_enum = resolved.get<enumeration_type>() != 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<pointer_type>()
&& expression->rhs().type_decoration.get<pointer_type>())
{
@@ -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<elna::boot::identifier>::operator()(
- const elna::boot::identifier& key) const
+ const elna::boot::identifier& key) const noexcept
{
return std::hash<std::string>{}(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 <utility>
+
namespace elna::boot
{
type::type(std::shared_ptr<alias_type> alias)
@@ -64,14 +66,16 @@ namespace elna::boot
{
if constexpr (std::is_same_v<T, alias_type>)
{
- if (auto *wp = std::get_if<std::weak_ptr<alias_type>>(&payload))
- return wp->lock();
+ if (const auto *weak_pointer = std::get_if<std::weak_ptr<alias_type>>(&payload)) {
+ return weak_pointer->lock();
+}
return nullptr;
}
else
{
- if (auto *sp = std::get_if<std::shared_ptr<T>>(&payload))
- return *sp;
+ if (auto *shared_pointer = std::get_if<std::shared_ptr<T>>(&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<record_type>())
{
@@ -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<decltype(p)>;
+ return std::visit([](const auto& payload) -> std::string {
+ using T = std::decay_t<decltype(payload)>;
if constexpr (std::is_same_v<T, std::monostate>)
+ {
return "<empty>";
+ }
else if constexpr (std::is_same_v<T, std::weak_ptr<alias_type>>)
- return p.lock()->name;
+ {
+ return payload.lock()->name;
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<primitive_type>>)
- return p->identifier;
+ {
+ return payload->identifier;
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<pointer_type>>)
- return "^" + p->base.to_string();
+ {
+ return "^" + payload->base.to_string();
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<constant_type>>)
- return "const " + p->unqualified.to_string();
+ {
+ return "const " + payload->unqualified.to_string();
+ }
else if constexpr (std::is_same_v<T, std::shared_ptr<array_type>>)
- 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<T, std::shared_ptr<record_type>>)
{
- 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<T, std::shared_ptr<procedure_type>>)
{
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<T, std::shared_ptr<enumeration_type>>)
+ {
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<type_info> 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<type_info>(shared_from_this());
}
- procedure_info::procedure_info(const procedure_type symbol, const std::vector<std::string> names,
+ procedure_info::procedure_info(const procedure_type& symbol, const std::vector<std::string>& names,
std::shared_ptr<symbol_table> 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_info>(type(std::make_shared<primitive_type>("Float"))));
result->enter("String", std::make_shared<type_info>(type(std::make_shared<primitive_type>("String"))));
- type boolean = type(std::make_shared<primitive_type>("Bool"));
+ type const boolean = type(std::make_shared<primitive_type>("Bool"));
result->enter("Bool", std::make_shared<type_info>(boolean));
procedure_type assert_symbol{ procedure_type::return_t() };
assert_symbol.parameters.push_back(boolean);
- std::shared_ptr<procedure_info> assert_info = std::make_shared<procedure_info>(assert_symbol,
+ std::shared_ptr<procedure_info> const assert_info = std::make_shared<procedure_info>(assert_symbol,
std::vector<std::string>{ "condition" });
result->enter("assert", assert_info);
return result;
}
- symbol_bag::symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table)
+ symbol_bag::symbol_bag(forward_table&& unresolved, const std::shared_ptr<symbol_table>& global_table)
: unresolved(unresolved)
{
this->symbols = std::make_shared<symbol_table>(global_table);
@@ -313,7 +330,7 @@ namespace elna::boot
std::shared_ptr<info> 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<info> entry)
+ bool symbol_bag::enter(const std::string& name, const std::shared_ptr<info>& entry)
{
return this->symbols->enter(name, entry);
}
@@ -336,7 +353,7 @@ namespace elna::boot
void symbol_bag::enter(std::shared_ptr<symbol_table> child)
{
- this->symbols = child;
+ this->symbols = std::move(child);
}
std::shared_ptr<symbol_table> symbol_bag::leave()
@@ -383,7 +400,7 @@ namespace elna::boot
return m_exported;
}
- type resolve_underlying_type(std::shared_ptr<alias_type> alias)
+ type resolve_underlying_type(const std::shared_ptr<alias_type>& 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 <algorithm>
+#include <utility>
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<enumeration_type>() != nullptr;
- bool is_record = resolved.get<record_type>() != nullptr;
+ type const resolved = resolve_underlying_type(composite_type);
+ bool const is_enum = resolved.get<enumeration_type>() != nullptr;
+ bool const is_record = resolved.get<record_type>() != 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<source_position> original,
std::optional<std::string> 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<enumeration_type>() != nullptr;
- std::string kind = is_enum ? "member" : "field";
+ type const resolved = resolve_underlying_type(aggregate);
+ bool const is_enum = resolved.get<enumeration_type>() != nullptr;
+ std::string const kind = is_enum ? "member" : "field";
std::string message = is_enum ? "Enumeration" : "Record";
if (auto alias = aggregate.get<alias_type>())
@@ -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_type> alias,
+ bool type_analysis_visitor::check_unresolved_symbol(const std::shared_ptr<alias_type>& alias,
std::vector<std::string>& 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<pointer_type>();
auto assignment_ptr = ctx.resolved_assignment.get<pointer_type>();
@@ -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<constant_type>() != 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<record_type>() == nullptr)
{
add_error<base_type_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<unary_operation_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<unary_operation_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<unary_operation_error>(expression->position(),
- expression->operand().type_decoration, op);
+ expression->operand().type_decoration, operation);
}
}
}
diff --git a/gcc/Make-lang.in b/gcc/Make-lang.in
index ecb0141..5b8b6a8 100644
--- a/gcc/Make-lang.in
+++ b/gcc/Make-lang.in
@@ -155,7 +155,7 @@ elna.stagefeedback: stagefeedback-start
-mv elna/*$(objext) stagefeedback/elna
ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated
-ELNA_CXXFLAGS = -std=c++17
+ELNA_CXXFLAGS = -std=c++20
elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index b13fd2f..79207cc 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see
#include <array>
#include <cstring>
+#include <ranges>
#include "elna/boot/evaluator.h"
#include "elna/gcc/elna-diagnostic.h"
@@ -29,9 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "gimplify.h"
#include "stringpool.h"
-#include "diagnostic.h"
#include "realmpfr.h"
-#include "varasm.h"
#include "fold-const.h"
#include "langhooks.h"
@@ -407,7 +406,7 @@ namespace elna::gcc
this->current_expression = build_int_cstu(elna_char_type_node, character->value);
}
- void generic_visitor::visit(boot::literal<nullptr_t> *)
+ void generic_visitor::visit(boot::literal<std::nullptr_t> *)
{
this->current_expression = elna_pointer_nil_node;
}
@@ -580,54 +579,55 @@ namespace elna::gcc
}
switch (expression->operation())
{
- case boot::binary_operator::sum:
+ using enum boot::binary_operator;
+ case sum:
this->current_expression = build_arithmetic_operation(expression, PLUS_EXPR, left, right);
break;
- case boot::binary_operator::subtraction:
+ case subtraction:
this->current_expression = build_arithmetic_operation(expression, MINUS_EXPR, left, right);
break;
- case boot::binary_operator::division:
+ case division:
this->current_expression = build_arithmetic_operation(expression, TRUNC_DIV_EXPR, left, right);
break;
- case boot::binary_operator::remainder:
+ case remainder:
this->current_expression = build_arithmetic_operation(expression, TRUNC_MOD_EXPR, left, right);
break;
- case boot::binary_operator::multiplication:
+ case multiplication:
this->current_expression = build_arithmetic_operation(expression, MULT_EXPR, left, right);
break;
- case boot::binary_operator::less:
+ case less:
this->current_expression = build_comparison_operation(expression, LT_EXPR, left, right);
break;
- case boot::binary_operator::greater:
+ case greater:
this->current_expression = build_comparison_operation(expression, GT_EXPR, left, right);
break;
- case boot::binary_operator::less_equal:
+ case less_equal:
this->current_expression = build_comparison_operation(expression, LE_EXPR, left, right);
break;
- case boot::binary_operator::greater_equal:
+ case greater_equal:
this->current_expression = build_comparison_operation(expression, GE_EXPR, left, right);
break;
- case boot::binary_operator::conjunction:
+ case conjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::disjunction:
+ case disjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::exclusive_disjunction:
+ case exclusive_disjunction:
this->current_expression = build_bit_logic_operation(expression, left, right);
break;
- case boot::binary_operator::equals:
+ case equals:
this->current_expression = build_equality_operation(expression, left, right);
break;
- case boot::binary_operator::not_equals:
+ case not_equals:
this->current_expression = build_equality_operation(expression, left, right);
break;
- case boot::binary_operator::shift_left:
+ case 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 boot::binary_operator::shift_right:
+ case 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);
@@ -642,7 +642,8 @@ namespace elna::gcc
switch (expression->operation())
{
- case boot::unary_operator::reference:
+ using enum boot::unary_operator;
+ case 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,
@@ -650,7 +651,7 @@ namespace elna::gcc
build_pointer_type(TREE_TYPE(this->current_expression)));
TREE_NO_TRAMPOLINE(this->current_expression) = 1;
break;
- case boot::unary_operator::negation:
+ case negation:
{
tree operand_type = TREE_TYPE(this->current_expression);
@@ -666,7 +667,7 @@ namespace elna::gcc
}
break;
}
- case boot::unary_operator::minus:
+ case minus:
{
tree operand_type = TREE_TYPE(this->current_expression);
@@ -674,7 +675,7 @@ namespace elna::gcc
operand_type, this->current_expression);
break;
}
- case boot::unary_operator::plus:
+ case plus:
// Identity: operand already in current_expression.
break;
}
@@ -1034,9 +1035,9 @@ namespace elna::gcc
}
auto& branches = statement->branches;
- for (auto it = branches.rbegin(); it != branches.rend(); ++it)
+ for (auto& branch : branches | std::views::reverse)
{
- result = make_if_branch(**it, result);
+ result = make_if_branch(*branch, result);
}
result = make_if_branch(statement->branch(), result);
@@ -1087,9 +1088,9 @@ namespace elna::gcc
tree result = NULL_TREE;
auto& branches = statement->branches;
- for (auto it = branches.rbegin(); it != branches.rend(); ++it)
+ for (auto& branch : branches | std::views::reverse)
{
- result = make_if_branch(**it, result, goto_check);
+ result = make_if_branch(*branch, result, goto_check);
}
result = make_if_branch(statement->branch(), result, goto_check);
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h
index 30bc7c3..4e35f02 100644
--- a/include/elna/boot/ast.h
+++ b/include/elna/boot/ast.h
@@ -137,42 +137,42 @@ namespace elna::boot
class empty_visitor : public parser_visitor
{
public:
- [[noreturn]] virtual void visit(array_type_expression *) override;
- [[noreturn]] virtual void visit(pointer_type_expression *) override;
- [[noreturn]] virtual void visit(constant_type_expression *) override;
- [[noreturn]] virtual void visit(type_declaration *) override;
- [[noreturn]] virtual void visit(record_type_expression *) override;
- [[noreturn]] virtual void visit(procedure_type_expression *) override;
- [[noreturn]] virtual void visit(enumeration_type_expression *) override;
-
- [[noreturn]] virtual void visit(variable_declaration *) override;
- [[noreturn]] virtual void visit(procedure_declaration *) override;
- [[noreturn]] virtual void visit(assign_statement *) override;
- [[noreturn]] virtual void visit(if_statement *) override;
- [[noreturn]] virtual void visit(import_declaration *) override;
- [[noreturn]] virtual void visit(while_statement *) override;
- [[noreturn]] virtual void visit(defer_statement *) override;
- [[noreturn]] virtual void visit(empty_statement *) override;
- [[noreturn]] virtual void visit(case_statement *) override;
- [[noreturn]] virtual void visit(procedure_call *) override;
- [[noreturn]] virtual void visit(unit *) override;
- [[noreturn]] virtual void visit(cast_expression *) override;
- [[noreturn]] virtual void visit(record_constructor_expression *) override;
- [[noreturn]] virtual void visit(array_constructor_expression *) override;
- [[noreturn]] virtual void visit(traits_expression *) override;
- [[noreturn]] virtual void visit(binary_expression *) override;
- [[noreturn]] virtual void visit(unary_expression *) override;
- [[noreturn]] virtual void visit(named_expression *) override;
- [[noreturn]] virtual void visit(array_access_expression *) override;
- [[noreturn]] virtual void visit(field_access_expression *) override;
- [[noreturn]] virtual void visit(dereference_expression *) override;
- [[noreturn]] virtual void visit(literal<std::int32_t> *) override;
- [[noreturn]] virtual void visit(literal<std::uint32_t> *) override;
- [[noreturn]] virtual void visit(literal<double> *) override;
- [[noreturn]] virtual void visit(literal<bool> *) override;
- [[noreturn]] virtual void visit(literal<unsigned char> *) override;
- [[noreturn]] virtual void visit(literal<std::nullptr_t> *) override;
- [[noreturn]] virtual void visit(literal<std::string> *) override;
+ [[noreturn]] void visit(array_type_expression *) override;
+ [[noreturn]] void visit(pointer_type_expression *) override;
+ [[noreturn]] void visit(constant_type_expression *) override;
+ [[noreturn]] void visit(type_declaration *) override;
+ [[noreturn]] void visit(record_type_expression *) override;
+ [[noreturn]] void visit(procedure_type_expression *) override;
+ [[noreturn]] void visit(enumeration_type_expression *) override;
+
+ [[noreturn]] void visit(variable_declaration *) override;
+ [[noreturn]] void visit(procedure_declaration *) override;
+ [[noreturn]] void visit(assign_statement *) override;
+ [[noreturn]] void visit(if_statement *) override;
+ [[noreturn]] void visit(import_declaration *) override;
+ [[noreturn]] void visit(while_statement *) override;
+ [[noreturn]] void visit(defer_statement *) override;
+ [[noreturn]] void visit(empty_statement *) override;
+ [[noreturn]] void visit(case_statement *) override;
+ [[noreturn]] void visit(procedure_call *) override;
+ [[noreturn]] void visit(unit *) override;
+ [[noreturn]] void visit(cast_expression *) override;
+ [[noreturn]] void visit(record_constructor_expression *) override;
+ [[noreturn]] void visit(array_constructor_expression *) override;
+ [[noreturn]] void visit(traits_expression *) override;
+ [[noreturn]] void visit(binary_expression *) override;
+ [[noreturn]] void visit(unary_expression *) override;
+ [[noreturn]] void visit(named_expression *) override;
+ [[noreturn]] void visit(array_access_expression *) override;
+ [[noreturn]] void visit(field_access_expression *) override;
+ [[noreturn]] void visit(dereference_expression *) override;
+ [[noreturn]] void visit(literal<std::int32_t> *) override;
+ [[noreturn]] void visit(literal<std::uint32_t> *) override;
+ [[noreturn]] void visit(literal<double> *) override;
+ [[noreturn]] void visit(literal<bool> *) override;
+ [[noreturn]] void visit(literal<unsigned char> *) override;
+ [[noreturn]] void visit(literal<std::nullptr_t> *) override;
+ [[noreturn]] void visit(literal<std::string> *) override;
};
/**
@@ -181,42 +181,42 @@ namespace elna::boot
class walking_visitor : public parser_visitor
{
public:
- virtual void visit(array_type_expression *) override;
- virtual void visit(pointer_type_expression *) override;
- virtual void visit(constant_type_expression *) override;
- virtual void visit(type_declaration *) override;
- virtual void visit(record_type_expression *) override;
- virtual void visit(procedure_type_expression *) override;
- virtual void visit(enumeration_type_expression *) override;
-
- virtual void visit(variable_declaration *) override;
- virtual void visit(procedure_declaration *) override;
- virtual void visit(assign_statement *) override;
- virtual void visit(if_statement *) override;
- virtual void visit(import_declaration *) override;
- virtual void visit(while_statement *statement) override;
- virtual void visit(defer_statement *statement) override;
- virtual void visit(empty_statement *) override;
- virtual void visit(case_statement *statement) override;
- virtual void visit(procedure_call *call) override;
- virtual void visit(unit *unit) override;
- virtual void visit(cast_expression *expression) override;
- virtual void visit(record_constructor_expression *expression) override;
- virtual void visit(array_constructor_expression *expression) override;
- virtual void visit(traits_expression *trait) override;
- virtual void visit(binary_expression *expression) override;
- virtual void visit(unary_expression *expression) override;
- virtual void visit(named_expression *) override;
- virtual void visit(array_access_expression *expression) override;
- virtual void visit(field_access_expression *expression) override;
- virtual void visit(dereference_expression *expression) override;
- virtual void visit(literal<std::int32_t> *) override;
- virtual void visit(literal<std::uint32_t> *) override;
- virtual void visit(literal<double> *) override;
- virtual void visit(literal<bool> *) override;
- virtual void visit(literal<unsigned char> *) override;
- virtual void visit(literal<std::nullptr_t> *) override;
- virtual void visit(literal<std::string> *) override;
+ void visit(array_type_expression *) override;
+ void visit(pointer_type_expression *) override;
+ void visit(constant_type_expression *) override;
+ void visit(type_declaration *) override;
+ void visit(record_type_expression *) override;
+ void visit(procedure_type_expression *) override;
+ void visit(enumeration_type_expression *) override;
+
+ void visit(variable_declaration *) override;
+ void visit(procedure_declaration *) override;
+ void visit(assign_statement *) override;
+ void visit(if_statement *) override;
+ void visit(import_declaration *) override;
+ void visit(while_statement *statement) override;
+ void visit(defer_statement *statement) override;
+ void visit(empty_statement *) override;
+ void visit(case_statement *statement) override;
+ void visit(procedure_call *call) override;
+ void visit(unit *unit) override;
+ void visit(cast_expression *expression) override;
+ void visit(record_constructor_expression *expression) override;
+ void visit(array_constructor_expression *expression) override;
+ void visit(traits_expression *trait) override;
+ void visit(binary_expression *expression) override;
+ void visit(unary_expression *expression) override;
+ void visit(named_expression *) override;
+ void visit(array_access_expression *expression) override;
+ void visit(field_access_expression *expression) override;
+ void visit(dereference_expression *expression) override;
+ void visit(literal<std::int32_t> *) override;
+ void visit(literal<std::uint32_t> *) override;
+ void visit(literal<double> *) override;
+ void visit(literal<bool> *) override;
+ void visit(literal<unsigned char> *) override;
+ void visit(literal<std::nullptr_t> *) override;
+ void visit(literal<std::string> *) override;
};
/**
@@ -397,7 +397,7 @@ namespace elna::boot
void accept(parser_visitor *visitor) override;
array_constructor_expression *is_array_constructor() override;
- virtual ~array_constructor_expression() override;
+ ~array_constructor_expression() override;
};
/**
@@ -462,7 +462,7 @@ namespace elna::boot
procedure_type_expression(const source_position position,
std::vector<field_declaration>&& parameters, return_t return_type = return_t());
- ~procedure_type_expression();
+ ~procedure_type_expression() override;
void accept(parser_visitor *visitor) override;
procedure_type_expression *is_procedure() override;
@@ -503,7 +503,7 @@ namespace elna::boot
procedure_type_expression& heading();
- virtual ~procedure_declaration() override;
+ ~procedure_declaration() override;
};
/**
@@ -515,7 +515,7 @@ namespace elna::boot
public:
type_declaration(const source_position position, identifier_definition identifier,
- type_expression *expression);
+ type_expression *underlying_type);
~type_declaration() override;
void accept(parser_visitor *visitor) override;
@@ -539,7 +539,7 @@ namespace elna::boot
type_expression& target();
expression& value();
- virtual ~cast_expression() override;
+ ~cast_expression() override;
};
class traits_expression : public expression
@@ -551,7 +551,7 @@ namespace elna::boot
traits_expression(const source_position position, identifier&& name,
std::vector<type_expression *>&& arguments);
- ~traits_expression();
+ ~traits_expression() override;
void accept(parser_visitor *visitor) override;
traits_expression *is_traits() override;
@@ -603,8 +603,8 @@ namespace elna::boot
virtual dereference_expression *is_dereference();
designator_expression *is_designator() override;
- void accept(parser_visitor *visitor);
- ~designator_expression() = 0;
+ void accept(parser_visitor *visitor) override;
+ ~designator_expression() override = 0;
};
/**
@@ -684,11 +684,11 @@ namespace elna::boot
procedure_call(const source_position position, designator_expression *callable,
std::vector<expression *>&& arguments);
void accept(parser_visitor *visitor) override;
- virtual procedure_call *is_call_expression() override;
+ procedure_call *is_call_expression() override;
designator_expression& callable();
- virtual ~procedure_call() override;
+ ~procedure_call() override;
};
class assign_statement : public statement
@@ -709,7 +709,7 @@ namespace elna::boot
designator_expression& lvalue();
expression& rvalue();
- virtual ~assign_statement() override;
+ ~assign_statement() override;
};
/**
@@ -730,7 +730,7 @@ namespace elna::boot
conditional_statements& branch();
- virtual ~if_statement() override;
+ ~if_statement() override;
};
/**
@@ -761,7 +761,7 @@ namespace elna::boot
conditional_statements& branch();
- virtual ~while_statement() override;
+ ~while_statement() override;
};
class unit : public node, public procedure_body
@@ -779,9 +779,9 @@ namespace elna::boot
std::vector<procedure_declaration *>&& procedures,
std::vector<statement *>&& entry_point);
bool has_body() const;
- virtual void accept(parser_visitor *visitor) override;
+ void accept(parser_visitor *visitor) override;
- virtual ~unit() override;
+ ~unit() override;
};
template<typename T>
@@ -809,7 +809,7 @@ namespace elna::boot
defer_statement(const source_position position, std::vector<statement *>&& statements);
void accept(parser_visitor *visitor) override;
- virtual ~defer_statement() override;
+ ~defer_statement() override;
};
class empty_statement : public statement
@@ -836,7 +836,7 @@ namespace elna::boot
expression& rhs();
binary_operator operation() const;
- virtual ~binary_expression() override;
+ ~binary_expression() override;
};
class unary_expression : public expression
@@ -854,7 +854,7 @@ namespace elna::boot
expression& operand();
unary_operator operation() const;
- virtual ~unary_expression() override;
+ ~unary_expression() override;
};
const char *print_binary_operator(const binary_operator operation);
diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h
index 829b669..24ded26 100644
--- a/include/elna/boot/dependency.h
+++ b/include/elna/boot/dependency.h
@@ -39,7 +39,7 @@ namespace elna::boot
dependency read_source(std::istream& entry_point);
std::filesystem::path build_path(const std::vector<std::string>& segments);
- error_list analyze_semantics(std::unique_ptr<unit>& tree, symbol_bag bag,
+ error_list analyze_semantics(std::unique_ptr<unit>& tree, const symbol_bag& bag,
const target_info& target);
template<typename T>
@@ -51,8 +51,8 @@ namespace elna::boot
const std::shared_ptr<symbol_table> globals;
T custom;
- using iterator = typename std::unordered_map<std::filesystem::path, symbol_bag>::iterator;
- using const_iterator = typename std::unordered_map<std::filesystem::path, symbol_bag>::const_iterator;
+ using iterator = std::unordered_map<std::filesystem::path, symbol_bag>::iterator;
+ using const_iterator = std::unordered_map<std::filesystem::path, symbol_bag>::const_iterator;
explicit dependency_state(T custom)
: globals(builtin_symbol_table()), custom(custom)
@@ -64,7 +64,7 @@ namespace elna::boot
return cache.find(key);
}
- void insert(const std::filesystem::path& key, symbol_bag value)
+ void insert(const std::filesystem::path& key, const symbol_bag& value)
{
cache.insert({ key, value });
}
diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h
index 8f93dbd..ef5be81 100644
--- a/include/elna/boot/driver.h
+++ b/include/elna/boot/driver.h
@@ -32,7 +32,7 @@ namespace elna::boot
public:
syntax_error(const std::string& message, const yy::location& location);
- virtual std::string what() const override;
+ std::string what() const override;
};
class driver : public error_container
diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h
index 6e82777..f1a5437 100644
--- a/include/elna/boot/evaluator.h
+++ b/include/elna/boot/evaluator.h
@@ -75,7 +75,7 @@ namespace elna::boot
const target_info& target;
const std::map<std::string, expression*>& evaluated_initializers;
- std::optional<constant_value> evaluate_literal(literal_expression& subject);
+ static std::optional<constant_value> evaluate_literal(literal_expression& subject);
std::optional<constant_value> evaluate_named(named_expression& subject);
std::optional<constant_value> evaluate_unary(unary_expression& subject);
std::optional<constant_value> evaluate_binary(binary_expression& subject);
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index 40bdf16..6f40bec 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -113,8 +113,8 @@ namespace elna::boot
std::pair<procedure_type, std::vector<std::string>> build_procedure(
procedure_type_expression& expression);
std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields,
- std::map<std::string, field_origin>& known_names,
- type aggregate);
+ std::map<std::string, field_origin>& field_names,
+ const type& aggregate);
std::shared_ptr<variable_info> register_variable(const std::string& name,
const bool is_extern, const source_position position);
diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h
index 953f701..328e44e 100644
--- a/include/elna/boot/result.h
+++ b/include/elna/boot/result.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include <deque>
#include <memory>
#include <optional>
+#include <utility>
#include <variant>
namespace elna::boot
@@ -42,8 +43,7 @@ namespace elna::boot
bool available() const;
- bool operator==(const location& that) const;
- bool operator!=(const location& that) const;
+ auto operator<=>(const location&) const = default;
private:
std::size_t m_line{ 0 };
@@ -80,6 +80,7 @@ namespace elna::boot
error(const source_position position);
public:
+ virtual ~error() = default;
/// Error position.
const source_position position;
@@ -98,7 +99,7 @@ namespace elna::boot
}
};
- using error_list = typename std::deque<std::unique_ptr<error>>;
+ using error_list = std::deque<std::unique_ptr<error>>;
class error_container
{
@@ -111,7 +112,7 @@ namespace elna::boot
error_list& errors();
template<typename T, typename... Args>
- void add_error(Args... arguments)
+ void add_error(Args&&... arguments)
{
auto new_error = std::make_unique<T>(arguments...);
m_errors.emplace_back(std::move(new_error));
@@ -129,7 +130,7 @@ namespace elna::boot
return_declaration() = default;
explicit return_declaration(T type)
- : proper_type(type)
+ : proper_type(std::move(type))
{
}
@@ -138,15 +139,7 @@ namespace elna::boot
{
}
- bool operator==(const return_declaration& that) const
- {
- return this->proper_type == that.proper_type && this->no_return == that.no_return;
- }
-
- bool operator!=(const return_declaration& that) const
- {
- return !(*this == that);
- }
+ auto operator<=>(const return_declaration&) const = default;
T proper_type{};
bool no_return{ false };
@@ -159,11 +152,9 @@ namespace elna::boot
const std::string& name() const;
const source_position& position() const;
- bool operator==(const identifier& that) const;
- bool operator!=(const identifier& that) const;
-
- bool operator==(const std::string& that) const;
- bool operator!=(const std::string& that) const;
+ std::strong_ordering operator<=>(const identifier& that) const;
+ bool operator==(std::string_view that) const;
+ bool operator!=(std::string_view that) const;
private:
std::string m_name;
diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h
index 194c1cd..9505e5a 100644
--- a/include/elna/boot/symbol.h
+++ b/include/elna/boot/symbol.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include <memory>
#include <string>
#include <unordered_map>
+#include <utility>
#include <variant>
#include <vector>
@@ -29,14 +30,14 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
- class alias_type;
- class primitive_type;
- class record_type;
- class pointer_type;
- class constant_type;
- class array_type;
- class procedure_type;
- class enumeration_type;
+ struct alias_type;
+ struct primitive_type;
+ struct record_type;
+ struct pointer_type;
+ struct constant_type;
+ struct array_type;
+ struct procedure_type;
+ struct enumeration_type;
class type
{
@@ -167,12 +168,12 @@ namespace elna::boot
class symbol_map
{
public:
- using symbol_ptr = typename std::enable_if<
- std::is_convertible<U, T>::value || std::is_assignable<T, U>::value,
+ using symbol_ptr = std::enable_if_t<
+ std::is_convertible_v<U, T> || std::is_assignable_v<T, U>,
T
- >::type;
- using iterator = typename std::unordered_map<std::string, symbol_ptr>::iterator;
- using const_iterator = typename std::unordered_map<std::string, symbol_ptr>::const_iterator;
+ >;
+ using iterator = std::unordered_map<std::string, symbol_ptr>::iterator;
+ using const_iterator = std::unordered_map<std::string, symbol_ptr>::const_iterator;
private:
std::unordered_map<std::string, symbol_ptr> entries;
@@ -185,7 +186,7 @@ namespace elna::boot
* \param scope Outer scope.
*/
explicit symbol_map(std::shared_ptr<symbol_map> scope = nullptr)
- : outer_scope(scope)
+ : outer_scope(std::move(scope))
{
}
@@ -258,7 +259,7 @@ namespace elna::boot
*
* \return Whether the insertion took place.
*/
- bool enter(const std::string& name, symbol_ptr entry)
+ bool enter(const std::string& name, const symbol_ptr& entry)
{
return lookup(name) == nothing && entries.insert({ name, entry }).second;
}
@@ -282,7 +283,7 @@ namespace elna::boot
public:
const type symbol;
- explicit type_info(const type symbol);
+ explicit type_info(const type& symbol);
std::shared_ptr<type_info> is_type() override;
};
@@ -308,7 +309,7 @@ namespace elna::boot
* \param names Parameter names.
* \param scope Local definition (is `nullptr` for extern symbols).
*/
- procedure_info(const procedure_type symbol, const std::vector<std::string> names,
+ procedure_info(const procedure_type& symbol, const std::vector<std::string>& names,
std::shared_ptr<symbol_table> scope = nullptr);
std::shared_ptr<procedure_info> is_procedure() override;
@@ -337,7 +338,7 @@ namespace elna::boot
* \param symbol Variable type.
* \param is_extern Whether this is an extern symbol.
*/
- variable_info(const type symbol, bool is_extern);
+ variable_info(const type& symbol, bool is_extern);
std::shared_ptr<variable_info> is_variable() override;
};
@@ -363,7 +364,7 @@ namespace elna::boot
* \param unresolved Forward declarations collected in the previous step.
* \param global_table Global symbols.
*/
- symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table);
+ symbol_bag(forward_table&& unresolved, const std::shared_ptr<symbol_table>& global_table);
/**
* Looks up a symbol in the current and imported modules.
@@ -382,7 +383,7 @@ namespace elna::boot
*
* \return Whether the insertion took place.
*/
- bool enter(const std::string& name, std::shared_ptr<info> entry);
+ bool enter(const std::string& name, const std::shared_ptr<info>& entry);
/**
* Enters a new scope.
@@ -454,7 +455,7 @@ namespace elna::boot
/**
* \overload
*/
- type resolve_underlying_type(std::shared_ptr<alias_type> alias);
+ type resolve_underlying_type(const std::shared_ptr<alias_type>& alias);
/**
* Resolves an alias chain until the underlying type or a qualified type is
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h
index 8c7dd80..51aa04d 100644
--- a/include/elna/boot/type_check.h
+++ b/include/elna/boot/type_check.h
@@ -182,11 +182,11 @@ namespace elna::boot
type actual;
unary_operator op;
- static char unary_operator_symbol(unary_operator op);
+ static char unary_operator_symbol(unary_operator operation);
public:
unary_operation_error(const source_position position, type actual,
- unary_operator op);
+ unary_operator operation);
std::string what() const override;
};
@@ -200,7 +200,12 @@ namespace elna::boot
*/
struct assign_check
{
- enum class verdict { pass, accept, reject };
+ enum class verdict
+ {
+ pass,
+ accept,
+ reject
+ };
struct context
{
@@ -211,10 +216,10 @@ namespace elna::boot
};
context ctx;
- verdict guard_const_laundering();
- verdict check_exact_match();
- verdict check_pointer_hatch();
- verdict check_pointer_conversion();
+ verdict guard_const_laundering() const;
+ verdict check_exact_match() const;
+ verdict check_pointer_hatch() const;
+ verdict check_pointer_conversion() const;
bool run();
};
@@ -238,7 +243,7 @@ namespace elna::boot
* of type assignee.
*/
static bool is_assignable_from(const type& assignee, const type& assignment);
- static bool check_unresolved_symbol(std::shared_ptr<alias_type> alias,
+ static bool check_unresolved_symbol(const std::shared_ptr<alias_type>& alias,
std::vector<std::string>& path);
public:
diff --git a/rakelib/gcc.rake b/rakelib/gcc.rake
index b1f8c18..ce02bb6 100644
--- a/rakelib/gcc.rake
+++ b/rakelib/gcc.rake
@@ -150,6 +150,17 @@ namespace :gcc do
sh 'make', 'check-elna', chdir: File.join(HOST_GCC, 'gcc')
end
+ desc 'Run clang-tidy'
+ task :tidy do
+ compile_db = Pathname.new 'compile_commands.json'
+
+ raise "#{compile_db} is missing. Run: bear -- rake gcc:make" unless compile_db.exist?
+ sources = FileList['boot/*.cc', 'include/elna/boot/*.h'].exclude do |f|
+ f.include?('generated/')
+ end
+ sh 'clang-tidy', '-p', compile_db.to_path, '--extra-arg=-w', '--warnings-as-errors=*', *sources
+ end
+
desc 'Build documentation'
task :doc do
sh 'make', 'html', chdir: File.join(HOST_GCC, 'gcc')