diff --git a/boot/ast.cc b/boot/ast.cc index 7e11cfd..2ff5a00 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -71,35 +71,6 @@ namespace elna::boot return nullptr; } - void statement::accept(parser_visitor *visitor) - { - if (assign_statement *node = is_assign()) - { - return node->accept(visitor); - } - else if (if_statement *node = is_if()) - { - return node->accept(visitor); - } - else if (while_statement *node = is_while()) - { - return node->accept(visitor); - } - else if (return_statement *node = is_return()) - { - return node->accept(visitor); - } - else if (defer_statement *node = is_defer()) - { - return node->accept(visitor); - } - else if (procedure_call *node = is_call_statement()) - { - return node->accept(visitor); - } - __builtin_unreachable(); - } - expression::expression() { } diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index 0779da6..9d247c0 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -1071,9 +1071,20 @@ namespace elna::gcc void generic_visitor::visit(boot::dereference_expression *expression) { expression->base().accept(this); + location_t expression_location = get_location(&expression->position()); + tree expression_type = TREE_TYPE(this->current_expression); - this->current_expression = build1_loc(get_location(&expression->position()), INDIRECT_REF, - TREE_TYPE(TREE_TYPE(this->current_expression)), this->current_expression); + if (is_pointer_type(expression_type)) + { + this->current_expression = build1_loc(expression_location, INDIRECT_REF, + TREE_TYPE(expression_type), this->current_expression); + } + else + { + error_at(expression_location, "Type '%s' cannot be dereferenced, it is not a pointer", + print_type(expression_type).c_str()); + this->current_expression = error_mark_node; + } } void generic_visitor::visit(boot::assign_statement *statement) diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 9abfff4..9e4c4e7 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -156,7 +156,36 @@ namespace elna::boot virtual defer_statement *is_defer(); virtual procedure_call *is_call_statement(); - void accept(parser_visitor *visitor); + template + void accept(V *visitor) + { + if (assign_statement *node = is_assign()) + { + return visitor->visit(node); + } + else if (if_statement *node = is_if()) + { + return visitor->visit(node); + } + else if (while_statement *node = is_while()) + { + return visitor->visit(node); + } + else if (return_statement *node = is_return()) + { + return visitor->visit(node); + } + else if (defer_statement *node = is_defer()) + { + return visitor->visit(node); + } + else if (procedure_call *node = is_call_statement()) + { + return visitor->visit(node); + } + __builtin_unreachable(); + } + ~statement() = 0; protected: @@ -739,7 +768,8 @@ namespace elna::boot } } - void accept(parser_visitor *visitor) + template + void accept(V *visitor) { visitor->visit(this); }