mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Add @force to foreign import
This commit is contained in:
@@ -410,6 +410,7 @@ Foreign_Import_Decl :: struct {
|
|||||||
name: ^Ident,
|
name: ^Ident,
|
||||||
collection_name: string,
|
collection_name: string,
|
||||||
fullpaths: []string,
|
fullpaths: []string,
|
||||||
|
attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily
|
||||||
comment: ^Comment_Group,
|
comment: ^Comment_Group,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -827,6 +827,9 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
|
|||||||
case ast.Foreign_Block_Decl:
|
case ast.Foreign_Block_Decl:
|
||||||
if d.docs == nil do d.docs = docs;
|
if d.docs == nil do d.docs = docs;
|
||||||
append(&d.attributes, attribute);
|
append(&d.attributes, attribute);
|
||||||
|
case ast.Foreign_Import_Decl:
|
||||||
|
if d.docs == nil do d.docs = docs;
|
||||||
|
append(&d.attributes, attribute);
|
||||||
case:
|
case:
|
||||||
error(p, decl.pos, "expected a value or foreign declaration after an attribute");
|
error(p, decl.pos, "expected a value or foreign declaration after an attribute");
|
||||||
free(attribute);
|
free(attribute);
|
||||||
|
|||||||
@@ -803,6 +803,7 @@ void init_checker_info(CheckerInfo *i) {
|
|||||||
map_init(&i->files, a);
|
map_init(&i->files, a);
|
||||||
map_init(&i->packages, a);
|
map_init(&i->packages, a);
|
||||||
array_init(&i->variable_init_order, a);
|
array_init(&i->variable_init_order, a);
|
||||||
|
array_init(&i->required_foreign_imports_through_force, a);
|
||||||
|
|
||||||
i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions;
|
i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions;
|
||||||
if (i->allow_identifier_uses) {
|
if (i->allow_identifier_uses) {
|
||||||
@@ -823,6 +824,8 @@ void destroy_checker_info(CheckerInfo *i) {
|
|||||||
map_destroy(&i->packages);
|
map_destroy(&i->packages);
|
||||||
array_free(&i->variable_init_order);
|
array_free(&i->variable_init_order);
|
||||||
array_free(&i->identifier_uses);
|
array_free(&i->identifier_uses);
|
||||||
|
array_free(&i->required_foreign_imports_through_force);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckerContext make_checker_context(Checker *c) {
|
CheckerContext make_checker_context(Checker *c) {
|
||||||
@@ -1696,6 +1699,11 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_array(i, c->info.required_foreign_imports_through_force) {
|
||||||
|
Entity *e = c->info.required_foreign_imports_through_force[i];
|
||||||
|
add_dependency_to_set(c, e);
|
||||||
|
}
|
||||||
|
|
||||||
add_dependency_to_set(c, start);
|
add_dependency_to_set(c, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3172,6 +3180,16 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
|||||||
scope->flags |= ScopeFlag_HasBeenImported;
|
scope->flags |= ScopeFlag_HasBeenImported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
|
||||||
|
if (name == "force") {
|
||||||
|
if (value != nullptr) {
|
||||||
|
error(elem, "Expected no parameter for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
ac->force_foreign_import = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||||
if (decl->been_handled) return;
|
if (decl->been_handled) return;
|
||||||
@@ -3216,6 +3234,14 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
|||||||
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->fullpaths, library_name);
|
fl->fullpaths, library_name);
|
||||||
add_entity(ctx->checker, parent_scope, nullptr, e);
|
add_entity(ctx->checker, parent_scope, nullptr, e);
|
||||||
|
|
||||||
|
|
||||||
|
AttributeContext ac = {};
|
||||||
|
check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
|
||||||
|
if (ac.force_foreign_import) {
|
||||||
|
array_add(&ctx->info->required_foreign_imports_through_force, e);
|
||||||
|
add_entity_use(ctx, nullptr, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool collect_checked_packages_from_decl_list(Checker *c, Array<Ast *> const &decls) {
|
bool collect_checked_packages_from_decl_list(Checker *c, Array<Ast *> const &decls) {
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ struct AttributeContext {
|
|||||||
bool is_export;
|
bool is_export;
|
||||||
bool is_static;
|
bool is_static;
|
||||||
bool require_results;
|
bool require_results;
|
||||||
|
bool force_foreign_import;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
isize init_expr_list_count;
|
isize init_expr_list_count;
|
||||||
@@ -249,6 +250,8 @@ struct CheckerInfo {
|
|||||||
PtrSet<Entity *> minimum_dependency_set;
|
PtrSet<Entity *> minimum_dependency_set;
|
||||||
PtrSet<isize> minimum_dependency_type_info_set;
|
PtrSet<isize> minimum_dependency_type_info_set;
|
||||||
|
|
||||||
|
Array<Entity *> required_foreign_imports_through_force;
|
||||||
|
|
||||||
|
|
||||||
bool allow_identifier_uses;
|
bool allow_identifier_uses;
|
||||||
Array<Ast *> identifier_uses; // only used by 'odin query'
|
Array<Ast *> identifier_uses; // only used by 'odin query'
|
||||||
|
|||||||
@@ -11335,6 +11335,11 @@ void ir_gen_tree(irGen *s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_array(i, m->info->required_foreign_imports_through_force) {
|
||||||
|
Entity *e = m->info->required_foreign_imports_through_force[i];
|
||||||
|
ir_add_foreign_library_path(m, e);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
{ // Startup Runtime
|
{ // Startup Runtime
|
||||||
// Cleanup(bill): probably better way of doing code insertion
|
// Cleanup(bill): probably better way of doing code insertion
|
||||||
|
|||||||
+5
-1
@@ -1049,6 +1049,8 @@ Ast *ast_foreign_import_decl(AstFile *f, Token token, Array<Token> filepaths, To
|
|||||||
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;
|
||||||
|
result->ForeignImportDecl.attributes.allocator = heap_allocator();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3865,7 +3867,9 @@ Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, TokenKind clo
|
|||||||
array_add(&decl->ValueDecl.attributes, attribute);
|
array_add(&decl->ValueDecl.attributes, attribute);
|
||||||
} else if (decl->kind == Ast_ForeignBlockDecl) {
|
} else if (decl->kind == Ast_ForeignBlockDecl) {
|
||||||
array_add(&decl->ForeignBlockDecl.attributes, attribute);
|
array_add(&decl->ForeignBlockDecl.attributes, attribute);
|
||||||
} else {
|
} else if (decl->kind == Ast_ForeignImportDecl) {
|
||||||
|
array_add(&decl->ForeignImportDecl.attributes, attribute);
|
||||||
|
}else {
|
||||||
syntax_error(decl, "Expected a value or foreign declaration after an attribute, got %.*s", LIT(ast_strings[decl->kind]));
|
syntax_error(decl, "Expected a value or foreign declaration after an attribute, got %.*s", LIT(ast_strings[decl->kind]));
|
||||||
return ast_bad_stmt(f, token, f->curr_token);
|
return ast_bad_stmt(f, token, f->curr_token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -426,6 +426,7 @@ AST_KIND(_DeclBegin, "", bool) \
|
|||||||
Token library_name; \
|
Token library_name; \
|
||||||
String collection_name; \
|
String collection_name; \
|
||||||
Array<String> fullpaths; \
|
Array<String> fullpaths; \
|
||||||
|
Array<Ast *> attributes; \
|
||||||
CommentGroup *docs; \
|
CommentGroup *docs; \
|
||||||
CommentGroup *comment; \
|
CommentGroup *comment; \
|
||||||
}) \
|
}) \
|
||||||
|
|||||||
Reference in New Issue
Block a user