diff options
| author | gingerBill <bill@gingerbill.org> | 2017-10-15 16:05:42 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2017-10-15 16:05:42 +0100 |
| commit | 3d8bf36a304f3500840d4e2a990e78d15da70cb1 (patch) | |
| tree | 718153c089e1a959510af7fc259b5b66a1589fb1 /src/checker.cpp | |
| parent | 85f7c2d040e44e09c77da86b42aaf172666b73cf (diff) | |
`foreign export` block
```
foreign export {
my_i32: i32;
my_foo :: proc() -> i32 {
return 123;
}
}
```
Diffstat (limited to 'src/checker.cpp')
| -rw-r--r-- | src/checker.cpp | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/src/checker.cpp b/src/checker.cpp index 1d5dee576..fbdd299a1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -423,6 +423,7 @@ struct CheckerContext { DeclInfo * curr_proc_decl; AstNode * curr_foreign_library; + bool in_foreign_export; bool collect_delayed_decls; bool allow_polymorphic_types; bool no_polymorphic_errors; @@ -1481,13 +1482,13 @@ PtrSet<Entity *> generate_minimum_dependency_set(CheckerInfo *info, Entity *star add_dependency_to_map(&map, info, e); } } else if (e->kind == Entity_Procedure) { - if ((e->Procedure.tags & ProcTag_export) != 0) { - add_dependency_to_map(&map, info, e); - } if (e->Procedure.is_foreign) { add_dependency_to_map(&map, info, e->Procedure.foreign_library); } } + if (e->flags & EntityFlag_ForeignExport) { + add_dependency_to_map(&map, info, e); + } } add_dependency_to_map(&map, info, start); @@ -1969,6 +1970,8 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { GB_ASSERT(fl->kind == AstNode_Ident); e->Variable.is_foreign = true; e->Variable.foreign_library_ident = fl; + } else if (c->context.in_foreign_export) { + e->flags |= EntityFlag_ForeignExport; } entities[entity_count++] = e; @@ -2027,7 +2030,9 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { if (fl != nullptr) { GB_ASSERT(fl->kind == AstNode_Ident); e->Procedure.foreign_library_ident = fl; - pl->tags |= ProcTag_foreign; + e->Procedure.is_foreign = true; + } else if (c->context.in_foreign_export) { + e->flags |= EntityFlag_ForeignExport; } d->proc_lit = init; d->type_expr = pl->type; @@ -2038,13 +2043,14 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { } e->identifier = name; - if (fl != nullptr && e->kind != Entity_Procedure) { - AstNodeKind kind = init->kind; - error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[kind])); - if (kind == AstNode_ProcType) { - gb_printf_err("\tDid you forget to append `---` to the procedure?\n"); + if (e->kind != Entity_Procedure) { + if (fl != nullptr || c->context.in_foreign_export) { + AstNodeKind kind = init->kind; + error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[kind])); + if (kind == AstNode_ProcType) { + gb_printf_err("\tDid you forget to append `---` to the procedure?\n"); + } } - // continue; } add_entity_and_decl_info(c, name, e, d); @@ -2061,13 +2067,18 @@ void check_add_foreign_block_decl(Checker *c, AstNode *decl) { fb->been_handled = true; AstNode *foreign_library = fb->foreign_library; - if (foreign_library->kind != AstNode_Ident) { - error(foreign_library, "foreign library name must be an identifier"); - foreign_library = nullptr; - } + CheckerContext prev_context = c->context; - c->context.curr_foreign_library = foreign_library; + if (foreign_library->kind == AstNode_Ident) { + c->context.curr_foreign_library = foreign_library; + } else if (foreign_library->kind == AstNode_Implicit && foreign_library->Implicit.kind == Token_export) { + c->context.in_foreign_export = true; + } else { + error(foreign_library, "Foreign block name must be an identifier or `export`"); + c->context.curr_foreign_library = nullptr; + } + c->context.collect_delayed_decls = true; check_collect_entities(c, fb->decls); c->context = prev_context; |