mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 23:54:07 +00:00
#import and #load
#import - imported entities will not get exported #load - loaded entities will get exported
This commit is contained in:
@@ -1,19 +1,6 @@
|
||||
#import "punity.odin" as pn
|
||||
#import "fmt.odin" as fmt
|
||||
|
||||
test :: proc() {
|
||||
thing :: proc() {
|
||||
thing :: proc() {
|
||||
fmt.println("Hello1")
|
||||
}
|
||||
|
||||
fmt.println("Hello")
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
test()
|
||||
|
||||
init :: proc(c: ^pn.Core) {
|
||||
|
||||
}
|
||||
@@ -24,5 +11,5 @@ main :: proc() {
|
||||
}
|
||||
}
|
||||
|
||||
pn.run(init, step)
|
||||
// pn.run(init, step)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ SetWindowTextA :: proc(hwnd: HWND, c_string: ^u8) -> BOOL #foreign #dll_import
|
||||
QueryPerformanceFrequency :: proc(result: ^i64) -> i32 #foreign #dll_import
|
||||
QueryPerformanceCounter :: proc(result: ^i64) -> i32 #foreign #dll_import
|
||||
|
||||
Sleep :: proc(ms: i32) -> i32 #foreign
|
||||
Sleep :: proc(ms: i32) -> i32 #foreign #dll_import
|
||||
|
||||
OutputDebugStringA :: proc(c_str: ^u8) #foreign #dll_import
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ struct Scope {
|
||||
Scope *prev, *next;
|
||||
Scope *first_child, *last_child;
|
||||
Map<Entity *> elements; // Key: String
|
||||
Map<Entity *> implicit; // Key: String
|
||||
|
||||
gbArray(Scope *) shared;
|
||||
gbArray(Scope *) imported;
|
||||
@@ -216,6 +217,7 @@ struct CheckerInfo {
|
||||
Map<DeclInfo *> entities; // Key: Entity *
|
||||
Map<Entity *> foreign_procs; // Key: String
|
||||
Map<isize> type_info_map; // Key: Type *
|
||||
Map<AstFile *> files; // Key: String
|
||||
isize type_info_index;
|
||||
};
|
||||
|
||||
@@ -261,8 +263,10 @@ Scope *make_scope(Scope *parent, gbAllocator allocator) {
|
||||
Scope *s = gb_alloc_item(allocator, Scope);
|
||||
s->parent = parent;
|
||||
map_init(&s->elements, gb_heap_allocator());
|
||||
map_init(&s->implicit, gb_heap_allocator());
|
||||
gb_array_init(s->shared, gb_heap_allocator());
|
||||
gb_array_init(s->imported, gb_heap_allocator());
|
||||
|
||||
if (parent != NULL && parent != universal_scope) {
|
||||
DLIST_APPEND(parent->first_child, parent->last_child, s);
|
||||
}
|
||||
@@ -286,6 +290,7 @@ void destroy_scope(Scope *scope) {
|
||||
}
|
||||
|
||||
map_destroy(&scope->elements);
|
||||
map_destroy(&scope->implicit);
|
||||
gb_array_free(scope->shared);
|
||||
gb_array_free(scope->imported);
|
||||
|
||||
@@ -397,8 +402,9 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
||||
if (found)
|
||||
return *found;
|
||||
map_set(&s->elements, key, entity);
|
||||
if (entity->scope == NULL)
|
||||
if (entity->scope == NULL) {
|
||||
entity->scope = s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -506,6 +512,7 @@ void init_checker_info(CheckerInfo *i) {
|
||||
map_init(&i->untyped, a);
|
||||
map_init(&i->foreign_procs, a);
|
||||
map_init(&i->type_info_map, a);
|
||||
map_init(&i->files, a);
|
||||
i->type_info_index = 0;
|
||||
|
||||
}
|
||||
@@ -519,6 +526,8 @@ void destroy_checker_info(CheckerInfo *i) {
|
||||
map_destroy(&i->untyped);
|
||||
map_destroy(&i->foreign_procs);
|
||||
map_destroy(&i->type_info_map);
|
||||
map_destroy(&i->files);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -889,6 +898,7 @@ void check_parsed_files(Checker *c) {
|
||||
f->scope = scope;
|
||||
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||
map_set(&file_scopes, key, scope);
|
||||
map_set(&c->info.files, key, f);
|
||||
}
|
||||
|
||||
// Collect Entities
|
||||
@@ -1032,10 +1042,17 @@ void check_parsed_files(Checker *c) {
|
||||
// NOTE(bill): Add imported entities to this file's scope
|
||||
gb_for_array(elem_index, scope->elements.entries) {
|
||||
Entity *e = scope->elements.entries[elem_index].value;
|
||||
if (e->scope == file_scope) {
|
||||
continue;
|
||||
}
|
||||
// NOTE(bill): Do not add other imported entities
|
||||
if (e->scope == scope && e->kind != Entity_ImportName) {
|
||||
if (e->kind != Entity_ImportName) {
|
||||
if (is_entity_exported(e)) {
|
||||
add_entity(c, file_scope, NULL, e);
|
||||
if (!id->is_load) {
|
||||
HashKey key = hash_string(e->token.string);
|
||||
map_set(&file_scope->implicit, key, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2000,19 +2000,28 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
Entity *e = scope_lookup_entity(c->context.scope, name);
|
||||
add_entity_use(&c->info, op_expr, e);
|
||||
if (e != NULL && e->kind == Entity_ImportName) {
|
||||
String sel_name = selector->Ident.string;
|
||||
check_op_expr = false;
|
||||
entity = scope_lookup_entity(e->ImportName.scope, selector->Ident.string);
|
||||
entity = scope_lookup_entity(e->ImportName.scope, sel_name);
|
||||
if (entity == NULL) {
|
||||
gbString sel_str = expr_to_string(selector);
|
||||
defer (gb_string_free(sel_str));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%s` is not declared by `%.*s`", sel_str, LIT(name));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%.*s` is not declared by `%.*s`", LIT(sel_name), LIT(name));
|
||||
goto error;
|
||||
}
|
||||
if (entity->type == NULL) { // Not setup yet
|
||||
check_entity_decl(c, entity, NULL, NULL);
|
||||
}
|
||||
GB_ASSERT(entity->type != NULL);
|
||||
if (!is_entity_exported(entity)) {
|
||||
// if (!is_entity_exported(entity)) {
|
||||
b32 is_not_exported = !((e->ImportName.scope == entity->scope) && (entity->kind != Entity_ImportName));
|
||||
|
||||
if (is_not_exported) {
|
||||
auto found = map_get(&e->ImportName.scope->implicit, hash_string(sel_name));
|
||||
if (!found) {
|
||||
is_not_exported = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_not_exported) {
|
||||
gbString sel_str = expr_to_string(selector);
|
||||
defer (gb_string_free(sel_str));
|
||||
error(&c->error_collector, ast_node_token(op_expr), "`%s` is not exported by `%.*s`", sel_str, LIT(name));
|
||||
@@ -3044,8 +3053,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
|
||||
case_ast_node(pl, ProcLit, node);
|
||||
check_open_scope(c, pl->type);
|
||||
c->context.decl = make_declaration_info(c->allocator, c->context.scope);
|
||||
defer (check_close_scope(c));
|
||||
c->context.decl = make_declaration_info(c->allocator, c->context.scope);
|
||||
Type *proc_type = check_type(c, pl->type);
|
||||
if (proc_type != NULL) {
|
||||
check_proc_body(c, empty_token, c->context.decl, proc_type, pl->body);
|
||||
|
||||
@@ -150,7 +150,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
name = pd->foreign_name;
|
||||
}
|
||||
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name);
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name);
|
||||
p->Proc.tags = pd->tags;
|
||||
|
||||
map_set(&m->values, hash_pointer(e), p);
|
||||
@@ -169,6 +169,22 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
ssa_build_proc(v, NULL);
|
||||
}
|
||||
|
||||
ssaDebugInfo *compile_unit = m->debug_info.entries[0].value;
|
||||
GB_ASSERT(compile_unit->kind == ssaDebugInfo_CompileUnit);
|
||||
ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs);
|
||||
gb_array_init(all_procs->AllProcs.procs, gb_heap_allocator());
|
||||
map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
|
||||
compile_unit->CompileUnit.all_procs = all_procs;
|
||||
|
||||
|
||||
gb_for_array(i, m->debug_info.entries) {
|
||||
auto *entry = &m->debug_info.entries[i];
|
||||
ssaDebugInfo *di = entry->value;
|
||||
di->id = i;
|
||||
if (di->kind == ssaDebugInfo_Proc) {
|
||||
gb_array_append(all_procs->AllProcs.procs, di);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{ // Startup Runtime
|
||||
@@ -178,7 +194,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
NULL, 0,
|
||||
NULL, 0, false);
|
||||
AstNode *body = gb_alloc_item(a, AstNode);
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, proc_type, NULL, body, name);
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, NULL, proc_type, NULL, body, name);
|
||||
Token token = {};
|
||||
token.string = name;
|
||||
Entity *e = make_entity_procedure(a, NULL, token, proc_type);
|
||||
@@ -523,6 +539,8 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// m->layout = make_string("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
|
||||
|
||||
|
||||
|
||||
@@ -766,8 +766,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
|
||||
if (proc->tags & ProcTag_stdcall) {
|
||||
ssa_fprintf(f, "cc 64 ");
|
||||
}
|
||||
if (proc->tags & ProcTag_fastcall) {
|
||||
} else if (proc->tags & ProcTag_fastcall) {
|
||||
ssa_fprintf(f, "cc 65 ");
|
||||
}
|
||||
|
||||
@@ -803,28 +802,34 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
|
||||
ssa_fprintf(f, ") ");
|
||||
|
||||
if (proc->tags != 0) {
|
||||
if (proc->tags & ProcTag_inline) {
|
||||
ssa_fprintf(f, "alwaysinline ");
|
||||
}
|
||||
if (proc->tags & ProcTag_no_inline) {
|
||||
ssa_fprintf(f, "noinline ");
|
||||
}
|
||||
if (proc->tags & ProcTag_inline) {
|
||||
ssa_fprintf(f, "alwaysinline ");
|
||||
}
|
||||
if (proc->tags & ProcTag_no_inline) {
|
||||
ssa_fprintf(f, "noinline ");
|
||||
}
|
||||
|
||||
// if (proc->tags & ProcTag_stdcall) {
|
||||
// ssa_fprintf(f, "\"cc\"=\"64\" ");
|
||||
// }
|
||||
// if (proc->tags & ProcTag_fastcall) {
|
||||
// ssa_fprintf(f, "\"cc\"=\"65\" ");
|
||||
// }
|
||||
// if (proc->tags & ProcTag_stdcall) {
|
||||
// ssa_fprintf(f, "\"cc\"=\"64\" ");
|
||||
// }
|
||||
// if (proc->tags & ProcTag_fastcall) {
|
||||
// ssa_fprintf(f, "\"cc\"=\"65\" ");
|
||||
// }
|
||||
|
||||
if (proc->tags & ProcTag_foreign) {
|
||||
ssa_fprintf(f, "; foreign\n");
|
||||
}
|
||||
if (proc->module->generate_debug_info && proc->entity != NULL) {
|
||||
ssaDebugInfo *di = *map_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||
GB_ASSERT(di->kind == ssaDebugInfo_Proc);
|
||||
ssa_fprintf(f, "!dbg !%d ", di->id);
|
||||
}
|
||||
|
||||
|
||||
if (proc->tags & ProcTag_foreign) {
|
||||
ssa_fprintf(f, "; foreign\n");
|
||||
}
|
||||
|
||||
if (proc->body != NULL) {
|
||||
// ssa_fprintf(f, "nounwind uwtable {\n");
|
||||
|
||||
ssa_fprintf(f, "{\n");
|
||||
gb_for_array(i, proc->blocks) {
|
||||
ssaBlock *block = proc->blocks[i];
|
||||
@@ -934,4 +939,67 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) {
|
||||
}
|
||||
ssa_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
|
||||
if (m->generate_debug_info) {
|
||||
ssa_fprintf(f, "\n");
|
||||
ssa_fprintf(f, "!llvm.dbg.cu = !{!0}\n");
|
||||
|
||||
gb_for_array(di_index, m->debug_info.entries) {
|
||||
auto *entry = &m->debug_info.entries[di_index];
|
||||
ssaDebugInfo *di = entry->value;
|
||||
ssa_fprintf(f, "!%d = ", di->id);
|
||||
defer (ssa_fprintf(f, "\n"));
|
||||
|
||||
switch (di->kind) {
|
||||
case ssaDebugInfo_CompileUnit: {
|
||||
auto *cu = &di->CompileUnit;
|
||||
ssaDebugInfo *file = *map_get(&m->debug_info, hash_pointer(cu->file));
|
||||
ssa_fprintf(f,
|
||||
"distinct !DICompileUnit("
|
||||
"language: DW_LANG_Go, " // Is this good enough?
|
||||
"file: !%d, "
|
||||
"producer: \"%.*s\", "
|
||||
"flags: \"\", "
|
||||
"runtimeVersion: 0, "
|
||||
"isOptimized: false, "
|
||||
"emissionKind: FullDebug"
|
||||
")",
|
||||
file->id, LIT(cu->producer));
|
||||
|
||||
} break;
|
||||
case ssaDebugInfo_File:
|
||||
ssa_fprintf(f, "!DIFile(filename: \"");
|
||||
ssa_print_escape_string(f, di->File.filename, false);
|
||||
ssa_fprintf(f, "\", directory: \"");
|
||||
ssa_print_escape_string(f, di->File.directory, false);
|
||||
ssa_fprintf(f, "\")");
|
||||
break;
|
||||
case ssaDebugInfo_Proc:
|
||||
ssa_fprintf(f, "distinct !DISubprogram("
|
||||
"name: \"%.*s\", "
|
||||
// "linkageName: \"\", "
|
||||
"file: !%d, "
|
||||
"line: %td, "
|
||||
"isDefinition: true, "
|
||||
"isLocal: false, "
|
||||
"unit: !0"
|
||||
")",
|
||||
LIT(di->Proc.name),
|
||||
di->Proc.file->id,
|
||||
di->Proc.pos.line);
|
||||
break;
|
||||
|
||||
case ssaDebugInfo_AllProcs:
|
||||
ssa_fprintf(f, "!{");
|
||||
gb_for_array(proc_index, di->AllProcs.procs) {
|
||||
ssaDebugInfo *p = di->AllProcs.procs[proc_index];
|
||||
if (proc_index > 0) {ssa_fprintf(f, ",");}
|
||||
ssa_fprintf(f, "!%d", p->id);
|
||||
}
|
||||
ssa_fprintf(f, "}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,61 @@ struct ssaBlock;
|
||||
struct ssaValue;
|
||||
|
||||
|
||||
enum ssaDebugInfoKind {
|
||||
ssaDebugInfo_Invalid,
|
||||
|
||||
ssaDebugInfo_CompileUnit,
|
||||
ssaDebugInfo_File,
|
||||
ssaDebugInfo_Proc,
|
||||
ssaDebugInfo_AllProcs,
|
||||
|
||||
ssaDebugInfo_Count,
|
||||
};
|
||||
|
||||
struct ssaDebugInfo {
|
||||
ssaDebugInfoKind kind;
|
||||
i32 id;
|
||||
|
||||
union {
|
||||
struct {
|
||||
AstFile *file;
|
||||
String producer;
|
||||
ssaDebugInfo *all_procs;
|
||||
} CompileUnit;
|
||||
struct {
|
||||
AstFile *file;
|
||||
String filename;
|
||||
String directory;
|
||||
} File;
|
||||
struct {
|
||||
Entity * entity;
|
||||
String name;
|
||||
ssaDebugInfo *file;
|
||||
TokenPos pos;
|
||||
} Proc;
|
||||
struct {
|
||||
gbArray(ssaDebugInfo *) procs;
|
||||
} AllProcs;
|
||||
};
|
||||
};
|
||||
|
||||
struct ssaModule {
|
||||
CheckerInfo * info;
|
||||
BaseTypeSizes sizes;
|
||||
gbArena arena;
|
||||
gbAllocator allocator;
|
||||
b32 generate_debug_info;
|
||||
|
||||
u32 stmt_state_flags;
|
||||
|
||||
// String source_filename;
|
||||
String layout;
|
||||
// String triple;
|
||||
|
||||
Map<ssaValue *> values; // Key: Entity *
|
||||
Map<ssaValue *> members; // Key: String
|
||||
i32 global_string_index;
|
||||
Map<ssaValue *> values; // Key: Entity *
|
||||
Map<ssaValue *> members; // Key: String
|
||||
Map<ssaDebugInfo *> debug_info; // Key: Unique pointer
|
||||
i32 global_string_index;
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +97,7 @@ struct ssaProcedure {
|
||||
ssaProcedure *parent;
|
||||
gbArray(ssaProcedure *) children;
|
||||
|
||||
Entity * entity;
|
||||
ssaModule * module;
|
||||
String name;
|
||||
Type * type;
|
||||
@@ -310,6 +353,12 @@ void ssa_module_add_value(ssaModule *m, Entity *e, ssaValue *v) {
|
||||
map_set(&m->values, hash_pointer(e), v);
|
||||
}
|
||||
|
||||
ssaDebugInfo *ssa_alloc_debug_info(gbAllocator a, ssaDebugInfoKind kind) {
|
||||
ssaDebugInfo *di = gb_alloc_item(a, ssaDebugInfo);
|
||||
di->kind = kind;
|
||||
return di;
|
||||
}
|
||||
|
||||
void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
// TODO(bill): Determine a decent size for the arena
|
||||
isize token_count = c->parser->total_token_count;
|
||||
@@ -319,8 +368,9 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
m->info = &c->info;
|
||||
m->sizes = c->sizes;
|
||||
|
||||
map_init(&m->values, gb_heap_allocator());
|
||||
map_init(&m->members, gb_heap_allocator());
|
||||
map_init(&m->values, gb_heap_allocator());
|
||||
map_init(&m->members, gb_heap_allocator());
|
||||
map_init(&m->debug_info, gb_heap_allocator());
|
||||
|
||||
// Default states
|
||||
m->stmt_state_flags = 0;
|
||||
@@ -376,11 +426,20 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ssaDebugInfo *di = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_CompileUnit);
|
||||
di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
|
||||
di->CompileUnit.producer = make_string("odin");
|
||||
|
||||
map_set(&m->debug_info, hash_pointer(m), di);
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_destroy_module(ssaModule *m) {
|
||||
map_destroy(&m->values);
|
||||
map_destroy(&m->members);
|
||||
map_destroy(&m->debug_info);
|
||||
gb_arena_free(&m->arena);
|
||||
}
|
||||
|
||||
@@ -445,6 +504,46 @@ Type *ssa_type(ssaValue *value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssaDebugInfo *ssa_add_debug_info_file(ssaProcedure *proc, AstFile *file) {
|
||||
GB_ASSERT(file != NULL);
|
||||
ssaDebugInfo *di = ssa_alloc_debug_info(proc->module->allocator, ssaDebugInfo_File);
|
||||
di->File.file = file;
|
||||
|
||||
String filename = file->tokenizer.fullpath;
|
||||
String directory = filename;
|
||||
isize slash_index = 0;
|
||||
for (isize i = filename.len-1; i >= 0; i--) {
|
||||
if (filename.text[i] == '\\' ||
|
||||
filename.text[i] == '/') {
|
||||
break;
|
||||
}
|
||||
slash_index = i;
|
||||
}
|
||||
directory.len = slash_index-1;
|
||||
filename.text = filename.text + slash_index;
|
||||
filename.len -= slash_index;
|
||||
|
||||
|
||||
di->File.filename = filename;
|
||||
di->File.directory = directory;
|
||||
|
||||
map_set(&proc->module->debug_info, hash_pointer(file), di);
|
||||
return di;
|
||||
}
|
||||
|
||||
|
||||
ssaDebugInfo *ssa_add_debug_info_proc(ssaProcedure *proc, Entity *entity, String name, ssaDebugInfo *file) {
|
||||
GB_ASSERT(entity != NULL);
|
||||
ssaDebugInfo *di = ssa_alloc_debug_info(proc->module->allocator, ssaDebugInfo_Proc);
|
||||
di->Proc.entity = entity;
|
||||
di->Proc.name = name;
|
||||
di->Proc.file = file;
|
||||
di->Proc.pos = entity->token.pos;
|
||||
|
||||
map_set(&proc->module->debug_info, hash_pointer(entity), di);
|
||||
return di;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -674,9 +773,10 @@ ssaValue *ssa_make_const_bool(gbAllocator a, b32 b) {
|
||||
}
|
||||
|
||||
|
||||
ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Type *type, AstNode *type_expr, AstNode *body, String name) {
|
||||
ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Entity *entity, Type *type, AstNode *type_expr, AstNode *body, String name) {
|
||||
ssaValue *v = ssa_alloc_value(a, ssaValue_Proc);
|
||||
v->Proc.module = m;
|
||||
v->Proc.entity = entity;
|
||||
v->Proc.type = type;
|
||||
v->Proc.type_expr = type_expr;
|
||||
v->Proc.body = body;
|
||||
@@ -1919,7 +2019,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
|
||||
Type *type = type_of_expr(proc->module->info, expr);
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, type, pl->type, pl->body, name);
|
||||
proc->module, NULL, type, pl->type, pl->body, name);
|
||||
|
||||
value->Proc.tags = pl->tags;
|
||||
|
||||
@@ -3053,7 +3153,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
||||
GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
|
||||
Entity *e = *found;
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, e->type, pd->type, pd->body, name);
|
||||
proc->module, e, e->type, pd->type, pd->body, name);
|
||||
|
||||
value->Proc.tags = pd->tags;
|
||||
|
||||
@@ -3072,7 +3172,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
||||
Entity *e = *map_get(&info->definitions, hash_pointer(pd->name));
|
||||
Entity *f = *map_get(&info->foreign_procs, hash_string(name));
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, e->type, pd->type, pd->body, name);
|
||||
proc->module, e, e->type, pd->type, pd->body, name);
|
||||
|
||||
value->Proc.tags = pd->tags;
|
||||
|
||||
@@ -3594,6 +3694,28 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
|
||||
|
||||
proc->parent = parent;
|
||||
|
||||
if (proc->entity != NULL) {
|
||||
ssaModule *m = proc->module;
|
||||
CheckerInfo *info = m->info;
|
||||
Entity *e = proc->entity;
|
||||
String filename = e->token.pos.file;
|
||||
AstFile **found = map_get(&info->files, hash_string(filename));
|
||||
GB_ASSERT(found != NULL);
|
||||
AstFile *f = *found;
|
||||
ssaDebugInfo *di_file = NULL;
|
||||
|
||||
|
||||
ssaDebugInfo **di_file_found = map_get(&m->debug_info, hash_pointer(f));
|
||||
if (di_file_found) {
|
||||
di_file = *di_file_found;
|
||||
GB_ASSERT(di_file->kind == ssaDebugInfo_File);
|
||||
} else {
|
||||
di_file = ssa_add_debug_info_file(proc, f);
|
||||
}
|
||||
|
||||
ssa_add_debug_info_proc(proc, e, proc->name, di_file);
|
||||
}
|
||||
|
||||
if (proc->body != NULL) {
|
||||
u32 prev_stmt_state_flags = proc->module->stmt_state_flags;
|
||||
defer (proc->module->stmt_state_flags = prev_stmt_state_flags);
|
||||
|
||||
@@ -148,13 +148,13 @@ int main(int argc, char **argv) {
|
||||
gb_for_array(i, parser.system_libraries) {
|
||||
String lib = parser.system_libraries[i];
|
||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" -l%.*s", LIT(lib));
|
||||
" -l%.*s.lib", LIT(lib));
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
|
||||
exit_code = win32_exec_command_line_app(
|
||||
"clang %.*s.bc -o %.*s.exe "
|
||||
"-O0 "
|
||||
"-O0 -g "
|
||||
// "-O2 "
|
||||
"-Wno-override-module "
|
||||
"%s",
|
||||
|
||||
@@ -246,6 +246,7 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \
|
||||
Token token, relpath; \
|
||||
String fullpath; \
|
||||
Token import_name; \
|
||||
b32 is_load; \
|
||||
}) \
|
||||
AST_NODE_KIND(ForeignSystemLibrary, "foreign system library", struct { Token token, filepath; }) \
|
||||
AST_NODE_KIND(_DeclEnd, "", struct{}) \
|
||||
@@ -896,11 +897,12 @@ gb_inline AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNod
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_inline AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name) {
|
||||
gb_inline AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name, b32 is_load) {
|
||||
AstNode *result = make_node(f, AstNode_ImportDecl);
|
||||
result->ImportDecl.token = token;
|
||||
result->ImportDecl.relpath = relpath;
|
||||
result->ImportDecl.import_name = import_name;
|
||||
result->ImportDecl.is_load = is_load;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2585,10 +2587,21 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
import_name = expect_token(f, Token_Identifier);
|
||||
|
||||
if (f->curr_proc == NULL) {
|
||||
return make_import_decl(f, s->TagStmt.token, file_path, import_name);
|
||||
return make_import_decl(f, s->TagStmt.token, file_path, import_name, false);
|
||||
}
|
||||
ast_file_err(f, token, "You cannot use #import within a procedure. This must be done at the file scope.");
|
||||
return make_bad_decl(f, token, file_path);
|
||||
} else if (are_strings_equal(tag, make_string("load"))) {
|
||||
// TODO(bill): better error messages
|
||||
Token file_path = expect_token(f, Token_String);
|
||||
Token import_name = file_path;
|
||||
import_name.string = make_string("_");
|
||||
|
||||
if (f->curr_proc == NULL) {
|
||||
return make_import_decl(f, s->TagStmt.token, file_path, import_name, true);
|
||||
}
|
||||
ast_file_err(f, token, "You cannot use #load within a procedure. This must be done at the file scope.");
|
||||
return make_bad_decl(f, token, file_path);
|
||||
} else if (are_strings_equal(tag, make_string("foreign_system_library"))) {
|
||||
Token file_path = expect_token(f, Token_String);
|
||||
if (f->curr_proc == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user