Check for duplicate fields in the declaration visitor

This commit is contained in:
Eugen Wissner 2025-03-15 23:01:05 +01:00
parent fa73f14070
commit 978dd44a25
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
5 changed files with 131 additions and 47 deletions

View File

@ -66,8 +66,23 @@ namespace boot
}
for (auto& unresolved : this->unresolved)
{
auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
this->symbols->enter(std::move(unresolved.first), info);
if (!unresolved.second->reference.empty())
{
auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
this->symbols->enter(std::move(unresolved.first), info);
}
}
for (boot::variable_declaration *const variable : program->variables)
{
variable->accept(this);
}
for (boot::procedure_definition *const procedure : program->procedures)
{
procedure->accept(this);
}
for (statement *const body_statement : program->body)
{
body_statement->accept(this);
}
}
@ -123,6 +138,7 @@ namespace boot
this->current_type = type();
return false;
}
field_names.insert(field.first);
field.second->accept(this);
if (!this->current_type.empty())
{
@ -140,10 +156,6 @@ namespace boot
{
this->current_type = type(type_definition);
}
else
{
this->current_type = type();
}
}
void declaration_visitor::visit(union_type_expression *type_expression)
@ -154,13 +166,99 @@ namespace boot
{
this->current_type = type(type_definition);
}
else
{
this->current_type = type();
}
}
void declaration_visitor::visit(procedure_type_expression *type_expression)
{
for (variable_declaration *const parameter : type_expression->parameters)
{
parameter->accept(this);
}
if (type_expression->return_type != nullptr)
{
type_expression->return_type->accept(this);
}
}
void declaration_visitor::visit(variable_declaration *declaration)
{
declaration->variable_type().accept(this);
}
void declaration_visitor::visit(procedure_definition *definition)
{
definition->heading().accept(this);
if (definition->body != nullptr)
{
definition->body->accept(this);
}
}
void declaration_visitor::visit(block *block)
{
for (variable_declaration *const variable : block->variables)
{
variable->accept(this);
}
for (statement *const body_statement : block->body)
{
body_statement->accept(this);
}
}
void declaration_visitor::visit(assign_statement *statement)
{
}
void declaration_visitor::visit(if_statement *statement)
{
}
void declaration_visitor::visit(while_statement *statement)
{
}
void declaration_visitor::visit(return_statement *statement)
{
}
void declaration_visitor::visit(defer_statement *statement)
{
}
void declaration_visitor::visit(procedure_call *call)
{
}
void declaration_visitor::visit(cast_expression *expression)
{
}
void declaration_visitor::visit(traits_expression *expression)
{
}
void declaration_visitor::visit(binary_expression *expression)
{
}
void declaration_visitor::visit(unary_expression *expression)
{
}
void declaration_visitor::visit(variable_expression *)
{
}
void declaration_visitor::visit(array_access_expression *)
{
}
void declaration_visitor::visit(field_access_expression *)
{
}
void declaration_visitor::visit(dereference_expression *)
{
}
}

View File

@ -22,7 +22,6 @@ namespace elna
namespace boot
{
type::type()
: tag(type_tag::alias)
{
}
@ -145,6 +144,7 @@ namespace boot
case type_tag::empty:
break;
case type_tag::alias:
this->alias.~weak_ptr<alias_type>();
break;
case type_tag::primitive:
this->primitive.~shared_ptr<primitive_type>();

View File

@ -32,15 +32,11 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "fold-const.h"
#include "langhooks.h"
#include <set>
namespace elna
{
namespace gcc
{
tree handle_symbol(const std::string& symbol_name, const boot::type& type,
std::shared_ptr<boot::symbol_table> from, std::shared_ptr<symbol_table> to);
tree get_inner_alias(const boot::type& type,
std::shared_ptr<boot::symbol_table> from, std::shared_ptr<symbol_table> to)
{
@ -102,10 +98,6 @@ namespace gcc
{
handle_symbol(symbol_name, symbol_info->is_type()->symbol, info_table, symbols);
}
for (auto& [symbol_name, symbol_info] : *info_table)
{
// printf("%s\n", symbol_name.c_str());
}
}
return std::move(declaration_visitor.errors());
}
@ -418,11 +410,6 @@ namespace gcc
return bind_expr;
}
tree generic_visitor::lookup(const std::string& name)
{
return this->symbols->lookup(name);
}
void generic_visitor::visit(boot::number_literal<std::int32_t> *literal)
{
this->current_expression = build_int_cst(elna_int_type_node, literal->value);
@ -775,7 +762,7 @@ namespace gcc
void generic_visitor::visit(boot::type_definition *definition)
{
location_t definition_location = get_location(&definition->position());
this->current_expression = lookup(definition->identifier);
this->current_expression = this->symbols->lookup(definition->identifier);
definition->body().accept(this);
tree definition_tree = build_decl(definition_location, TYPE_DECL,
@ -847,7 +834,7 @@ namespace gcc
void generic_visitor::visit(boot::variable_expression *expression)
{
auto symbol = lookup(expression->name);
auto symbol = this->symbols->lookup(expression->name);
if (symbol == NULL_TREE)
{
@ -1140,7 +1127,7 @@ namespace gcc
void generic_visitor::visit(boot::primitive_type_expression *type)
{
tree symbol = lookup(type->name);
tree symbol = this->symbols->lookup(type->name);
if (symbol == NULL_TREE || !TYPE_P(symbol))
{
@ -1181,21 +1168,12 @@ namespace gcc
void generic_visitor::visit(boot::record_type_expression *type)
{
std::set<std::string> field_names;
tree composite_type_node = this->current_expression == NULL_TREE
? make_node(RECORD_TYPE)
: this->current_expression;
for (auto& field : type->fields)
{
if (field_names.find(field.first) != field_names.cend())
{
error_at(get_location(&field.second->position()), "repeated field name");
this->current_expression = error_mark_node;
return;
}
field_names.insert(field.first);
field.second->accept(this);
if (this->current_expression == NULL_TREE || this->current_expression == error_mark_node)
{
@ -1213,21 +1191,12 @@ namespace gcc
void generic_visitor::visit(boot::union_type_expression *type)
{
std::set<std::string> field_names;
tree composite_type_node = this->current_expression == NULL_TREE
? make_node(UNION_TYPE)
: this->current_expression;
for (auto& field : type->fields)
{
if (field_names.find(field.first) != field_names.cend())
{
error_at(get_location(&field.second->position()), "repeated field name");
this->current_expression = error_mark_node;
return;
}
field_names.insert(field.first);
field.second->accept(this);
if (this->current_expression == NULL_TREE || this->current_expression == error_mark_node)
{

View File

@ -68,6 +68,23 @@ namespace boot
void visit(record_type_expression *type_expression) override;
void visit(union_type_expression *type_expression) override;
void visit(procedure_type_expression *type_expression) override;
void visit(variable_declaration *declaration) override;
void visit(procedure_definition *definition) override;
void visit(block *block) override;
void visit(assign_statement *statement) override;
void visit(if_statement *statement) override;
void visit(while_statement *statement) override;
void visit(return_statement *statement) override;
void visit(defer_statement *statement) override;
void visit(procedure_call *call) override;
void visit(cast_expression *expression) override;
void visit(traits_expression *expression) override;
void visit(binary_expression *expression) override;
void visit(unary_expression *expression) override;
void visit(variable_expression *) override;
void visit(array_access_expression *) override;
void visit(field_access_expression *) override;
void visit(dereference_expression *) override;
};
}
}

View File

@ -36,6 +36,8 @@ namespace gcc
{
std::deque<std::unique_ptr<boot::error>> do_semantic_analysis(const char *path,
std::unique_ptr<boot::program>& ast, std::shared_ptr<symbol_table> symbols);
tree handle_symbol(const std::string& symbol_name, const boot::type& type,
std::shared_ptr<boot::symbol_table> from, std::shared_ptr<symbol_table> to);
class generic_visitor final : public boot::empty_visitor
{
@ -48,8 +50,6 @@ namespace gcc
void enter_scope();
tree leave_scope();
tree lookup(const std::string& name);
void make_if_branch(boot::conditional_statements& branch, tree goto_endif);
tree build_arithmetic_operation(boot::binary_expression *expression,