mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 13:00:28 +00:00
Fix using import behaviour - #352
This commit is contained in:
@@ -5,7 +5,6 @@ foreign import "system:kernel32.lib"
|
||||
|
||||
@(default_calling_convention = "std")
|
||||
foreign kernel32 {
|
||||
@(link_name="GetLastError") get_last_error :: proc() -> i32 ---;
|
||||
@(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: cstring,
|
||||
process_attributes, thread_attributes: ^Security_Attributes,
|
||||
inherit_handle: Bool, creation_flags: u32, environment: rawptr,
|
||||
@@ -119,6 +118,8 @@ foreign kernel32 {
|
||||
|
||||
@(default_calling_convention = "c")
|
||||
foreign kernel32 {
|
||||
@(link_name="GetLastError") get_last_error :: proc() -> i32 ---;
|
||||
|
||||
@(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: cstring) -> u32 ---;
|
||||
@(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: Wstring) -> u32 ---;
|
||||
@(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: cstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: ^File_Attribute_Data) -> Bool ---;
|
||||
|
||||
@@ -1027,6 +1027,33 @@ void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) {
|
||||
array_add(&i->definitions, 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;
|
||||
@@ -1034,31 +1061,7 @@ bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *ent
|
||||
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) {
|
||||
@@ -3061,8 +3064,16 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
if (e->scope == parent_scope) continue;
|
||||
|
||||
if (is_entity_exported(e)) {
|
||||
Entity *prev = scope_lookup(parent_scope, name);
|
||||
add_entity_with_name(ctx->checker, parent_scope, e->identifier, e, name);
|
||||
Entity *found = scope_lookup(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +212,8 @@ void warning_va(Token token, char *fmt, va_list va) {
|
||||
gb_mutex_unlock(&global_error_collector.mutex);
|
||||
}
|
||||
|
||||
#define MAX_ERROR_COLLECTOR_COUNT (36)
|
||||
|
||||
void error_va(Token token, char *fmt, va_list va) {
|
||||
gb_mutex_lock(&global_error_collector.mutex);
|
||||
global_error_collector.count++;
|
||||
@@ -225,7 +227,7 @@ void error_va(Token token, char *fmt, va_list va) {
|
||||
gb_bprintf_va(fmt, va));
|
||||
}
|
||||
gb_mutex_unlock(&global_error_collector.mutex);
|
||||
if (global_error_collector.count > 20) {
|
||||
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) {
|
||||
gb_exit(1);
|
||||
}
|
||||
}
|
||||
@@ -243,7 +245,7 @@ void error_no_newline_va(Token token, char *fmt, va_list va) {
|
||||
gb_bprintf_va(fmt, va));
|
||||
}
|
||||
gb_mutex_unlock(&global_error_collector.mutex);
|
||||
if (global_error_collector.count > 20) {
|
||||
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) {
|
||||
gb_exit(1);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +265,7 @@ void syntax_error_va(Token token, char *fmt, va_list va) {
|
||||
}
|
||||
|
||||
gb_mutex_unlock(&global_error_collector.mutex);
|
||||
if (global_error_collector.count > 20) {
|
||||
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) {
|
||||
gb_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user