foreign import x {"foo.lib", "bar.lib"}

This commit is contained in:
gingerBill
2018-07-29 20:56:09 +01:00
parent dc5da7933a
commit a6fe656f21
7 changed files with 97 additions and 55 deletions
+4
View File
@@ -69,6 +69,10 @@ compare_byte_ptrs :: proc "contextless" (a, b: ^byte, n: int) -> int {
return 0; 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 { ptr_offset :: proc "contextless" (ptr: $P/^$T, n: int) -> P {
new := int(uintptr(ptr)) + size_of(T)*n; new := int(uintptr(ptr)) + size_of(T)*n;
return P(uintptr(new)); return P(uintptr(new));
+21 -19
View File
@@ -2615,37 +2615,39 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
Scope *parent_scope = ctx->scope; Scope *parent_scope = ctx->scope;
GB_ASSERT(parent_scope->flags&ScopeFlag_File); 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); String library_name = path_to_entity_name(fl->library_name.string, fullpath);
if (is_blank_ident(library_name)) { 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)); 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; return;
} }
if (fl->collection_name != "system") { // if (fl->collection_name != "system") {
char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1); // char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
defer (gb_free(heap_allocator(), c_str)); // defer (gb_free(heap_allocator(), c_str));
gb_memmove(c_str, fullpath.text, fullpath.len); // gb_memmove(c_str, fullpath.text, fullpath.len);
c_str[fullpath.len] = '\0'; // c_str[fullpath.len] = '\0';
gbFile f = {}; // gbFile f = {};
gbFileError file_err = gb_file_open(&f, c_str); // gbFileError file_err = gb_file_open(&f, c_str);
defer (gb_file_close(&f)); // defer (gb_file_close(&f));
switch (file_err) { // switch (file_err) {
case gbFileError_Invalid: // case gbFileError_Invalid:
error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath)); // error(decl, "Invalid file or cannot be found ('%.*s')", LIT(fullpath));
return; // return;
case gbFileError_NotExists: // case gbFileError_NotExists:
error(decl, "File cannot be found ('%.*s')", LIT(fullpath)); // error(decl, "File cannot be found ('%.*s')", LIT(fullpath));
return; // return;
} // }
} // }
GB_ASSERT(fl->library_name.pos.line != 0); GB_ASSERT(fl->library_name.pos.line != 0);
fl->library_name.string = library_name; fl->library_name.string = library_name;
Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid, 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); add_entity(ctx->checker, parent_scope, nullptr, e);
} }
+3 -3
View File
@@ -124,7 +124,7 @@ struct Entity {
Scope *scope; Scope *scope;
} ImportName; } ImportName;
struct { struct {
String path; Array<String> paths;
String name; String name;
} LibraryName; } LibraryName;
i32 Nil; 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, 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 *entity = alloc_entity(Entity_LibraryName, scope, token, type);
entity->LibraryName.path = path; entity->LibraryName.paths = paths;
entity->LibraryName.name = name; entity->LibraryName.name = name;
entity->state = EntityState_Resolved; // TODO(bill): Is this correct? entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
return entity; return entity;
+16 -14
View File
@@ -1332,22 +1332,24 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
GB_ASSERT(e->kind == Entity_LibraryName); GB_ASSERT(e->kind == Entity_LibraryName);
GB_ASSERT(e->flags & EntityFlag_Used); GB_ASSERT(e->flags & EntityFlag_Used);
String library_path = e->LibraryName.path; for_array(i, e->LibraryName.paths) {
if (library_path.len == 0) { String library_path = e->LibraryName.paths[i];
return; 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
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
continue;
}
}
array_add(&m->foreign_library_paths, library_path);
} }
array_add(&m->foreign_library_paths, library_path);
} }
+1 -2
View File
@@ -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_CrossLibDir, str_lit("cross-lib-dir"), BuildFlagParam_String);
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None);
GB_ASSERT(args.count >= 3); GB_ASSERT(args.count >= 3);
Array<String> flag_args = array_slice(args, 3, args.count); 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(), ""); gbString lib_str = gb_string_make(heap_allocator(), "");
defer (gb_string_free(lib_str)); defer (gb_string_free(lib_str));
char lib_str_buf[1024] = {0}; char lib_str_buf[1024] = {0};
for_array(i, ir_gen.module.foreign_library_paths) { for_array(i, ir_gen.module.foreign_library_paths) {
String lib = ir_gen.module.foreign_library_paths[i]; 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), isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
" \"%.*s\"", LIT(lib)); " \"%.*s\"", LIT(lib));
lib_str = gb_string_appendc(lib_str, lib_str_buf); lib_str = gb_string_appendc(lib_str, lib_str_buf);
+50 -15
View File
@@ -999,11 +999,11 @@ Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Toke
return result; 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) { CommentGroup *docs, CommentGroup *comment) {
Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl); Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl);
result->ForeignImportDecl.token = token; result->ForeignImportDecl.token = token;
result->ForeignImportDecl.filepath = filepath; result->ForeignImportDecl.filepaths = filepaths;
result->ForeignImportDecl.library_name = library_name; result->ForeignImportDecl.library_name = library_name;
result->ForeignImportDecl.docs = docs; result->ForeignImportDecl.docs = docs;
result->ForeignImportDecl.comment = comment; result->ForeignImportDecl.comment = comment;
@@ -3491,15 +3491,38 @@ Ast *parse_foreign_decl(AstFile *f) {
break; break;
} }
if (is_blank_ident(lib_name)) { 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); Array<Token> filepaths = {};
Ast *s = nullptr; if (allow_token(f, Token_OpenBrace)) {
if (f->curr_proc != nullptr) { array_init(&filepaths, heap_allocator());
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); 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 { } 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); expect_semicolon(f, s);
return 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) { } else if (node->kind == Ast_ForeignImportDecl) {
ast_node(fl, ForeignImportDecl, node); ast_node(fl, ForeignImportDecl, node);
String file_str = fl->filepath.string; fl->fullpaths.allocator = heap_allocator();
fl->fullpath = file_str; 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 = {}; String foreign_path = {};
bool ok = determine_path_from_string(p, node, base_dir, file_str, &foreign_path); bool ok = determine_path_from_string(p, node, base_dir, file_str, &foreign_path);
if (!ok) { if (!ok) {
decls[i] = ast_bad_decl(f, fl->filepath, fl->filepath); decls[i] = ast_bad_decl(f, fl->filepaths[fp_idx], fl->filepaths[fl->filepaths.count-1]);
continue; 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) { } else if (node->kind == Ast_WhenStmt) {
ast_node(ws, WhenStmt, node); ast_node(ws, WhenStmt, node);
parse_setup_file_when_stmt(p, f, base_dir, ws); parse_setup_file_when_stmt(p, f, base_dir, ws);
} }
end:;
} }
} }
+2 -2
View File
@@ -391,10 +391,10 @@ AST_KIND(_DeclBegin, "", bool) \
}) \ }) \
AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \ AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \
Token token; \ Token token; \
Token filepath; \ Array<Token> filepaths; \
Token library_name; \ Token library_name; \
String collection_name; \ String collection_name; \
String fullpath; \ Array<String> fullpaths; \
CommentGroup *docs; \ CommentGroup *docs; \
CommentGroup *comment; \ CommentGroup *comment; \
}) \ }) \