mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-25 07:04:58 -07:00
foreign import x {"foo.lib", "bar.lib"}
This commit is contained in:
@@ -69,6 +69,10 @@ compare_byte_ptrs :: proc "contextless" (a, b: ^byte, n: int) -> int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
compare_ptrs :: inline proc "contextless" (a, b: rawptr, n: int) -> int {
|
||||
return compare_byte_ptrs((^byte)(a), (^byte)(b), n);
|
||||
}
|
||||
|
||||
ptr_offset :: proc "contextless" (ptr: $P/^$T, n: int) -> P {
|
||||
new := int(uintptr(ptr)) + size_of(T)*n;
|
||||
return P(uintptr(new));
|
||||
|
||||
+21
-19
@@ -2615,37 +2615,39 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
Scope *parent_scope = ctx->scope;
|
||||
GB_ASSERT(parent_scope->flags&ScopeFlag_File);
|
||||
|
||||
String fullpath = fl->fullpath;
|
||||
GB_ASSERT(fl->fullpaths.count > 0);
|
||||
String fullpath = fl->fullpaths[0];
|
||||
String library_name = path_to_entity_name(fl->library_name.string, fullpath);
|
||||
if (is_blank_ident(library_name)) {
|
||||
error(fl->token, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fl->collection_name != "system") {
|
||||
char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
|
||||
defer (gb_free(heap_allocator(), c_str));
|
||||
gb_memmove(c_str, fullpath.text, fullpath.len);
|
||||
c_str[fullpath.len] = '\0';
|
||||
// if (fl->collection_name != "system") {
|
||||
// char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
|
||||
// defer (gb_free(heap_allocator(), c_str));
|
||||
// gb_memmove(c_str, fullpath.text, fullpath.len);
|
||||
// c_str[fullpath.len] = '\0';
|
||||
|
||||
gbFile f = {};
|
||||
gbFileError file_err = gb_file_open(&f, c_str);
|
||||
defer (gb_file_close(&f));
|
||||
// gbFile f = {};
|
||||
// gbFileError file_err = gb_file_open(&f, c_str);
|
||||
// defer (gb_file_close(&f));
|
||||
|
||||
switch (file_err) {
|
||||
case gbFileError_Invalid:
|
||||
error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath));
|
||||
return;
|
||||
case gbFileError_NotExists:
|
||||
error(decl, "File cannot be found ('%.*s')", LIT(fullpath));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// switch (file_err) {
|
||||
// case gbFileError_Invalid:
|
||||
// error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath));
|
||||
// return;
|
||||
// case gbFileError_NotExists:
|
||||
// error(decl, "File cannot be found ('%.*s')", LIT(fullpath));
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
GB_ASSERT(fl->library_name.pos.line != 0);
|
||||
fl->library_name.string = library_name;
|
||||
|
||||
Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid,
|
||||
fl->fullpath, library_name);
|
||||
fl->fullpaths, library_name);
|
||||
add_entity(ctx->checker, parent_scope, nullptr, e);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -124,7 +124,7 @@ struct Entity {
|
||||
Scope *scope;
|
||||
} ImportName;
|
||||
struct {
|
||||
String path;
|
||||
Array<String> paths;
|
||||
String name;
|
||||
} LibraryName;
|
||||
i32 Nil;
|
||||
@@ -278,9 +278,9 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
||||
}
|
||||
|
||||
Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
|
||||
String path, String name) {
|
||||
Array<String> paths, String name) {
|
||||
Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
|
||||
entity->LibraryName.path = path;
|
||||
entity->LibraryName.paths = paths;
|
||||
entity->LibraryName.name = name;
|
||||
entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
|
||||
return entity;
|
||||
|
||||
+16
-14
@@ -1332,22 +1332,24 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
|
||||
GB_ASSERT(e->kind == Entity_LibraryName);
|
||||
GB_ASSERT(e->flags & EntityFlag_Used);
|
||||
|
||||
String library_path = e->LibraryName.path;
|
||||
if (library_path.len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for_array(path_index, m->foreign_library_paths) {
|
||||
String path = m->foreign_library_paths[path_index];
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
if (str_eq_ignore_case(path, library_path)) {
|
||||
#else
|
||||
if (str_eq(path, library_path)) {
|
||||
#endif
|
||||
return;
|
||||
for_array(i, e->LibraryName.paths) {
|
||||
String library_path = e->LibraryName.paths[i];
|
||||
if (library_path.len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for_array(path_index, m->foreign_library_paths) {
|
||||
String path = m->foreign_library_paths[path_index];
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
if (str_eq_ignore_case(path, library_path)) {
|
||||
#else
|
||||
if (str_eq(path, library_path)) {
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
array_add(&m->foreign_library_paths, library_path);
|
||||
}
|
||||
array_add(&m->foreign_library_paths, library_path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-2
@@ -253,7 +253,6 @@ bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_CrossLibDir, str_lit("cross-lib-dir"), BuildFlagParam_String);
|
||||
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None);
|
||||
|
||||
|
||||
GB_ASSERT(args.count >= 3);
|
||||
Array<String> flag_args = array_slice(args, 3, args.count);
|
||||
|
||||
@@ -877,9 +876,9 @@ int main(int arg_count, char **arg_ptr) {
|
||||
gbString lib_str = gb_string_make(heap_allocator(), "");
|
||||
defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {0};
|
||||
|
||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||
String lib = ir_gen.module.foreign_library_paths[i];
|
||||
// gb_printf_err("Linking lib: %.*s\n", LIT(lib));
|
||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||
" \"%.*s\"", LIT(lib));
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
|
||||
+50
-15
@@ -999,11 +999,11 @@ Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Toke
|
||||
return result;
|
||||
}
|
||||
|
||||
Ast *ast_foreign_import_decl(AstFile *f, Token token, Token filepath, Token library_name,
|
||||
Ast *ast_foreign_import_decl(AstFile *f, Token token, Array<Token> filepaths, Token library_name,
|
||||
CommentGroup *docs, CommentGroup *comment) {
|
||||
Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl);
|
||||
result->ForeignImportDecl.token = token;
|
||||
result->ForeignImportDecl.filepath = filepath;
|
||||
result->ForeignImportDecl.filepaths = filepaths;
|
||||
result->ForeignImportDecl.library_name = library_name;
|
||||
result->ForeignImportDecl.docs = docs;
|
||||
result->ForeignImportDecl.comment = comment;
|
||||
@@ -3491,15 +3491,38 @@ Ast *parse_foreign_decl(AstFile *f) {
|
||||
break;
|
||||
}
|
||||
if (is_blank_ident(lib_name)) {
|
||||
syntax_error(lib_name, "Illegal foreign_library name: '_'");
|
||||
syntax_error(lib_name, "Illegal foreign import name: '_'");
|
||||
}
|
||||
Token file_path = expect_token(f, Token_String);
|
||||
Ast *s = nullptr;
|
||||
if (f->curr_proc != nullptr) {
|
||||
syntax_error(lib_name, "You cannot use foreign_library within a procedure. This must be done at the file scope");
|
||||
s = ast_bad_decl(f, lib_name, file_path);
|
||||
Array<Token> filepaths = {};
|
||||
if (allow_token(f, Token_OpenBrace)) {
|
||||
array_init(&filepaths, heap_allocator());
|
||||
|
||||
while (f->curr_token.kind != Token_CloseBrace &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
|
||||
Token path = expect_token(f, Token_String);
|
||||
array_add(&filepaths, path);
|
||||
|
||||
if (!allow_token(f, Token_Comma)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect_token(f, Token_CloseBrace);
|
||||
} else {
|
||||
s = ast_foreign_import_decl(f, token, file_path, lib_name, docs, f->line_comment);
|
||||
filepaths = array_make<Token>(heap_allocator(), 0, 1);
|
||||
Token path = expect_token(f, Token_String);
|
||||
array_add(&filepaths, path);
|
||||
}
|
||||
|
||||
Ast *s = nullptr;
|
||||
if (filepaths.count == 0) {
|
||||
syntax_error(lib_name, "foreign import without any paths");
|
||||
s = ast_bad_decl(f, lib_name, f->curr_token);
|
||||
} else if (f->curr_proc != nullptr) {
|
||||
syntax_error(lib_name, "You cannot use foreign import within a procedure. This must be done at the file scope");
|
||||
s = ast_bad_decl(f, lib_name, filepaths[0]);
|
||||
} else {
|
||||
s = ast_foreign_import_decl(f, token, filepaths, lib_name, docs, f->line_comment);
|
||||
}
|
||||
expect_semicolon(f, s);
|
||||
return s;
|
||||
@@ -4129,22 +4152,34 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<Ast *>
|
||||
} else if (node->kind == Ast_ForeignImportDecl) {
|
||||
ast_node(fl, ForeignImportDecl, node);
|
||||
|
||||
String file_str = fl->filepath.string;
|
||||
fl->fullpath = file_str;
|
||||
fl->fullpaths.allocator = heap_allocator();
|
||||
array_reserve(&fl->fullpaths, fl->filepaths.count);
|
||||
|
||||
for_array(fp_idx, fl->filepaths) {
|
||||
String file_str = fl->filepaths[fp_idx].string;
|
||||
String fullpath = file_str;
|
||||
|
||||
if (fl->collection_name != "system") {
|
||||
String foreign_path = {};
|
||||
bool ok = determine_path_from_string(p, node, base_dir, file_str, &foreign_path);
|
||||
if (!ok) {
|
||||
decls[i] = ast_bad_decl(f, fl->filepath, fl->filepath);
|
||||
continue;
|
||||
decls[i] = ast_bad_decl(f, fl->filepaths[fp_idx], fl->filepaths[fl->filepaths.count-1]);
|
||||
goto end;
|
||||
}
|
||||
fl->fullpath = foreign_path;
|
||||
fullpath = foreign_path;
|
||||
array_add(&fl->fullpaths, fullpath);
|
||||
}
|
||||
if (fl->fullpaths.count == 0) {
|
||||
error(decls[i], "No foreign paths found");
|
||||
decls[i] = ast_bad_decl(f, fl->filepaths[0], fl->filepaths[fl->filepaths.count-1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
} else if (node->kind == Ast_WhenStmt) {
|
||||
ast_node(ws, WhenStmt, node);
|
||||
parse_setup_file_when_stmt(p, f, base_dir, ws);
|
||||
}
|
||||
|
||||
end:;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -391,10 +391,10 @@ AST_KIND(_DeclBegin, "", bool) \
|
||||
}) \
|
||||
AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \
|
||||
Token token; \
|
||||
Token filepath; \
|
||||
Array<Token> filepaths; \
|
||||
Token library_name; \
|
||||
String collection_name; \
|
||||
String fullpath; \
|
||||
Array<String> fullpaths; \
|
||||
CommentGroup *docs; \
|
||||
CommentGroup *comment; \
|
||||
}) \
|
||||
|
||||
Reference in New Issue
Block a user