aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-02-23 21:39:47 +0000
committergingerBill <bill@gingerbill.org>2019-02-23 21:39:47 +0000
commite551d2b25ea39afb95f7b8ee4309ef0cc8b502b8 (patch)
tree664e1906ba18e2d7d1fdb64915c54c1d10b4536d /src
parent38ae2e9efaf8d227a138d749085599e7ee9fde54 (diff)
Replace `foreign export {}` with `@export`
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp11
-rw-r--r--src/check_expr.cpp16
-rw-r--r--src/check_type.cpp6
-rw-r--r--src/checker.cpp54
-rw-r--r--src/checker.hpp2
-rw-r--r--src/parser.cpp10
-rw-r--r--src/tokenizer.cpp1
7 files changed, 70 insertions, 30 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 91fd0ff01..e9d6d5860 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -551,20 +551,20 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
check_procedure_type(&tmp_ctx, proc_type, pl->type);
TypeProc *pt = &proc_type->Proc;
-
- bool is_foreign = e->Procedure.is_foreign;
- bool is_export = e->Procedure.is_export;
- bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
-
AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
if (d != nullptr) {
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
}
+ e->Procedure.is_export = ac.is_export;
e->deprecated_message = ac.deprecated_message;
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
+ bool is_foreign = e->Procedure.is_foreign;
+ bool is_export = e->Procedure.is_export;
+ bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
+
if (e->pkg != nullptr && e->token.string == "main") {
if (pt->param_count != 0 ||
pt->result_count != 0) {
@@ -718,6 +718,7 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_ex
check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
}
+ e->Variable.is_export = ac.is_export;
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
e->Variable.thread_local_model = ac.thread_local_model;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 75c16b705..ea125a5eb 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1241,6 +1241,14 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string));
return false;
}
+ if (is_type_simd_vector(o->type)) {
+ switch (op.kind) {
+ case Token_ModMod:
+ case Token_ModModEq:
+ error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string));
+ return false;
+ }
+ }
break;
case Token_AndNot:
@@ -1249,6 +1257,14 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
error(op, "Operator '%.*s' is only allowed with integers and bit sets", LIT(op.string));
return false;
}
+ if (is_type_simd_vector(o->type)) {
+ switch (op.kind) {
+ case Token_AndNot:
+ case Token_AndNotEq:
+ error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string));
+ return false;
+ }
+ }
break;
case Token_CmpAnd:
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 8b6b67e65..1c5d5ac85 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -1783,7 +1783,11 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
Type *new_type = original_type;
if (is_type_boolean(original_type)) {
- return t_llvm_bool;
+ Type *t = core_type(base_type(new_type));
+ if (t == t_bool) {
+ return t_llvm_bool;
+ }
+ return new_type;
}
if (build_context.ODIN_ARCH == "386") {
diff --git a/src/checker.cpp b/src/checker.cpp
index 7900555a5..9bbe64839 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1952,7 +1952,18 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
}
DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
- if (name == "deferred") {
+ if (name == "export") {
+ ExactValue ev = check_decl_attribute_value(c, value);
+ if (ev.kind == ExactValue_Invalid) {
+ ac->is_export = true;
+ } else if (ev.kind == ExactValue_Bool) {
+ ac->is_export = ev.value_bool;
+ } else {
+ error(value, "Expected either a boolean or no parameter for 'export'");
+ return false;
+ }
+ return true;
+ } else if (name == "deferred") {
if (value != nullptr) {
Operand o = {};
check_expr(c, &o, value);
@@ -2064,7 +2075,20 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
return true;
}
- if (name == "link_name") {
+ if (name == "export") {
+ ExactValue ev = check_decl_attribute_value(c, value);
+ if (ev.kind == ExactValue_Invalid) {
+ ac->is_export = true;
+ } else if (ev.kind == ExactValue_Bool) {
+ ac->is_export = ev.value_bool;
+ } else {
+ error(value, "Expected either a boolean or no parameter for 'export'");
+ return false;
+ }
+ if (ac->thread_local_model != "") {
+ error(elem, "An exported variable cannot be thread local");
+ }
+ } else if (name == "link_name") {
if (ev.kind == ExactValue_String) {
ac->link_name = ev.value_string;
if (!is_foreign_name_valid(ac->link_name)) {
@@ -2087,8 +2111,10 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
} else if (name == "thread_local") {
if (ac->init_expr_list_count > 0) {
error(elem, "A thread local variable declaration cannot have initialization values");
- } else if (c->foreign_context.curr_library || c->foreign_context.in_export) {
+ } else if (c->foreign_context.curr_library) {
error(elem, "A foreign block variable cannot be thread local");
+ } else if (ac->is_export) {
+ error(elem, "An exported variable cannot be thread local");
} else if (ev.kind == ExactValue_Invalid) {
ac->thread_local_model = str_lit("default");
} else if (ev.kind == ExactValue_String) {
@@ -2151,9 +2177,17 @@ void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, De
case_ast_node(i, Ident, elem);
name = i->token.string;
case_end;
+ case_ast_node(i, Implicit, elem);
+ name = i->string;
+ case_end;
case_ast_node(fv, FieldValue, elem);
- GB_ASSERT(fv->field->kind == Ast_Ident);
- name = fv->field->Ident.token.string;
+ if (fv->field->kind == Ast_Ident) {
+ name = fv->field->Ident.token.string;
+ } else if (fv->field->kind == Ast_Implicit) {
+ name = fv->field->Implicit.string;
+ } else {
+ GB_PANIC("Unknown Field Value name");
+ }
value = fv->value;
case_end;
default:
@@ -2407,9 +2441,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
e->Variable.foreign_library_ident = fl;
e->Variable.link_prefix = c->foreign_context.link_prefix;
-
- } else if (c->foreign_context.in_export) {
- e->Variable.is_export = true;
}
Ast *init_expr = value;
@@ -2475,9 +2506,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
GB_ASSERT(cc != ProcCC_Invalid);
pl->type->ProcType.calling_convention = cc;
-
- } else if (c->foreign_context.in_export) {
- e->Procedure.is_export = true;
}
d->proc_lit = init;
d->type_expr = pl->type;
@@ -2516,7 +2544,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
}
if (e->kind != Entity_Procedure) {
- if (fl != nullptr || c->foreign_context.in_export) {
+ if (fl != nullptr) {
AstKind kind = init->kind;
error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_strings[kind]));
if (kind == Ast_ProcType) {
@@ -2544,8 +2572,6 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) {
CheckerContext c = *ctx;
if (foreign_library->kind == Ast_Ident) {
c.foreign_context.curr_library = foreign_library;
- } else if (foreign_library->kind == Ast_Implicit && foreign_library->Implicit.kind == Token_export) {
- c.foreign_context.in_export = true;
} else {
error(foreign_library, "Foreign block name must be an identifier or 'export'");
c.foreign_context.curr_library = nullptr;
diff --git a/src/checker.hpp b/src/checker.hpp
index de491671e..759e343bf 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -305,6 +305,7 @@ struct DeferredProcedure {
struct AttributeContext {
+ bool is_export;
String link_name;
String link_prefix;
isize init_expr_list_count;
@@ -423,7 +424,6 @@ struct ForeignContext {
Ast * curr_library;
ProcCallingConvention default_cc;
String link_prefix;
- bool in_export;
};
typedef Array<Entity *> CheckerTypePath;
diff --git a/src/parser.cpp b/src/parser.cpp
index e38c34a0a..9d42b3828 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1199,7 +1199,6 @@ void fix_advance_to_next_stmt(AstFile *f) {
case Token_package:
case Token_foreign:
case Token_import:
- case Token_export:
case Token_if:
case Token_for:
@@ -2452,9 +2451,7 @@ void parse_foreign_block_decl(AstFile *f, Array<Ast *> *decls) {
Ast *parse_foreign_block(AstFile *f, Token token) {
CommentGroup *docs = f->lead_comment;
Ast *foreign_library = nullptr;
- if (f->curr_token.kind == Token_export) {
- foreign_library = ast_implicit(f, expect_token(f, Token_export));
- } else if (f->curr_token.kind == Token_OpenBrace) {
+ if (f->curr_token.kind == Token_OpenBrace) {
foreign_library = ast_ident(f, blank_token);
} else {
foreign_library = parse_ident(f);
@@ -3590,7 +3587,6 @@ Ast *parse_foreign_decl(AstFile *f) {
Token token = expect_token(f, Token_foreign);
switch (f->curr_token.kind) {
- case Token_export:
case Token_Ident:
case Token_OpenBrace:
return parse_foreign_block(f, token);
@@ -3667,6 +3663,7 @@ Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, TokenKind clo
f->curr_token.kind != Token_EOF) {
Ast *elem = nullptr;
elem = parse_ident(f);
+
if (f->curr_token.kind == Token_Eq) {
Token eq = expect_token(f, Token_Eq);
Ast *value = parse_value(f);
@@ -3732,9 +3729,6 @@ Ast *parse_stmt(AstFile *f) {
case Token_import:
return parse_import_decl(f, ImportDecl_Standard);
- // case Token_export:
- // return parse_export_decl(f);
-
case Token_if: return parse_if_stmt(f);
case Token_when: return parse_when_stmt(f);
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 02770e371..31afe3d2e 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -82,7 +82,6 @@ TOKEN_KIND(Token__OperatorEnd, ""), \
\
TOKEN_KIND(Token__KeywordBegin, ""), \
TOKEN_KIND(Token_import, "import"), \
- TOKEN_KIND(Token_export, "export"), \
TOKEN_KIND(Token_foreign, "foreign"), \
TOKEN_KIND(Token_package, "package"), \
TOKEN_KIND(Token_typeid, "typeid"), \