aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorBrendan Punsky <bpunsky@gmail.com>2019-03-18 17:22:57 -0400
committerGitHub <noreply@github.com>2019-03-18 17:22:57 -0400
commite3d1d1d85c68b6ebc999cae648e55c692e1258d2 (patch)
tree728eddb83aef26c892bf21f53f937cd6094fdd2d /src/checker.cpp
parentb6ea7b741831f7cceaf43eaf116995d6ff386fb5 (diff)
parent290c111206b9386e7feb3023cda13b0e01483647 (diff)
Merge branch 'master' into master
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp88
1 files changed, 53 insertions, 35 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 0253bc86b..130c4aee5 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -388,8 +388,7 @@ Entity *scope_lookup(Scope *s, String name) {
-Entity *scope_insert(Scope *s, Entity *entity) {
- String name = entity->token.string;
+Entity *scope_insert_with_name(Scope *s, String name, Entity *entity) {
if (name == "") {
return nullptr;
}
@@ -406,6 +405,11 @@ Entity *scope_insert(Scope *s, Entity *entity) {
return nullptr;
}
+Entity *scope_insert(Scope *s, Entity *entity) {
+ String name = entity->token.string;
+ return scope_insert_with_name(s, name, entity);
+}
+
GB_COMPARE_PROC(entity_variable_pos_cmp) {
Entity *x = *cast(Entity **)a;
@@ -1023,39 +1027,41 @@ void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) {
array_add(&i->definitions, entity);
}
-bool add_entity(Checker *c, Scope *scope, Ast *identifier, Entity *entity) {
+bool redeclaration_error(String name, Entity *prev, Entity *found) {
+ TokenPos pos = found->token.pos;
+ Entity *up = found->using_parent;
+ if (up != nullptr) {
+ if (pos == up->token.pos) {
+ // NOTE(bill): Error should have been handled already
+ return false;
+ }
+ error(prev->token,
+ "Redeclaration of '%.*s' in this scope through 'using'\n"
+ "\tat %.*s(%td:%td)",
+ LIT(name),
+ LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column);
+ } else {
+ if (pos == prev->token.pos) {
+ // NOTE(bill): Error should have been handled already
+ return false;
+ }
+ error(prev->token,
+ "Redeclaration of '%.*s' in this scope\n"
+ "\tat %.*s(%td:%td)",
+ LIT(name),
+ LIT(pos.file), pos.line, pos.column);
+ }
+ return false;
+}
+
+bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *entity, String name) {
if (scope == nullptr) {
return false;
}
- String name = entity->token.string;
if (!is_blank_ident(name)) {
Entity *ie = scope_insert(scope, entity);
if (ie != nullptr) {
- TokenPos pos = ie->token.pos;
- Entity *up = ie->using_parent;
- if (up != nullptr) {
- if (pos == up->token.pos) {
- // NOTE(bill): Error should have been handled already
- return false;
- }
- error(entity->token,
- "Redeclaration of '%.*s' in this scope through 'using'\n"
- "\tat %.*s(%td:%td)",
- LIT(name),
- LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column);
- return false;
- } else {
- if (pos == entity->token.pos) {
- // NOTE(bill): Error should have been handled already
- return false;
- }
- error(entity->token,
- "Redeclaration of '%.*s' in this scope\n"
- "\tat %.*s(%td:%td)",
- LIT(name),
- LIT(pos.file), pos.line, pos.column);
- return false;
- }
+ return redeclaration_error(name, entity, ie);
}
}
if (identifier != nullptr) {
@@ -1063,6 +1069,9 @@ bool add_entity(Checker *c, Scope *scope, Ast *identifier, Entity *entity) {
}
return true;
}
+bool add_entity(Checker *c, Scope *scope, Ast *identifier, Entity *entity) {
+ return add_entity_with_name(c, scope, identifier, entity, entity->token.string);
+}
void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) {
if (entity == nullptr) {
@@ -2005,7 +2014,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
if (value != nullptr) {
Operand o = {};
check_expr(c, &o, value);
- Entity *e = entity_of_ident(o.expr);
+ Entity *e = entity_of_node(o.expr);
if (e != nullptr && e->kind == Entity_Procedure) {
warning(elem, "'%.*s' is deprecated, please use one of the following instead: 'deferred_none', 'deferred_in', 'deferred_out'", LIT(name));
if (ac->deferred_procedure.entity != nullptr) {
@@ -2022,7 +2031,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
if (value != nullptr) {
Operand o = {};
check_expr(c, &o, value);
- Entity *e = entity_of_ident(o.expr);
+ Entity *e = entity_of_node(o.expr);
if (e != nullptr && e->kind == Entity_Procedure) {
ac->deferred_procedure.kind = DeferredProcedure_none;
ac->deferred_procedure.entity = e;
@@ -2035,7 +2044,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
if (value != nullptr) {
Operand o = {};
check_expr(c, &o, value);
- Entity *e = entity_of_ident(o.expr);
+ Entity *e = entity_of_node(o.expr);
if (e != nullptr && e->kind == Entity_Procedure) {
if (ac->deferred_procedure.entity != nullptr) {
error(elem, "Previous usage of a 'deferred_*' attribute");
@@ -2051,7 +2060,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
if (value != nullptr) {
Operand o = {};
check_expr(c, &o, value);
- Entity *e = entity_of_ident(o.expr);
+ Entity *e = entity_of_node(o.expr);
if (e != nullptr && e->kind == Entity_Procedure) {
if (ac->deferred_procedure.entity != nullptr) {
error(elem, "Previous usage of a 'deferred_*' attribute");
@@ -3050,12 +3059,21 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
// NOTE(bill): Add imported entities to this file's scope
for_array(elem_index, scope->elements.entries) {
+ String name = scope->elements.entries[elem_index].key.string;
Entity *e = scope->elements.entries[elem_index].value;
if (e->scope == parent_scope) continue;
if (is_entity_exported(e)) {
- Entity *prev = scope_lookup(parent_scope, e->token.string);
- add_entity(ctx->checker, parent_scope, e->identifier, e);
+ Entity *found = scope_lookup_current(parent_scope, name);
+ if (found != nullptr) {
+ // NOTE(bill):
+ // Date: 2019-03-17
+ // The order has to be the other way around as `using` adds the entity into the that
+ // file scope otherwise the error would be the wrong way around
+ redeclaration_error(name, found, e);
+ } else {
+ add_entity_with_name(ctx->checker, parent_scope, e->identifier, e, name);
+ }
}
}
}