aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2017-11-04 10:53:47 +0000
committergingerBill <bill@gingerbill.org>2017-11-04 10:53:47 +0000
commit04b917a60aef2b60c6580899d191913004dbb2af (patch)
tree88f674cdc19223e9d2fedf0ce5efb21fabd2092c /src
parente6c99cd2892cb34beaedfef0c8a786e2e0ef654e (diff)
More code clean up
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp27
-rw-r--r--src/check_stmt.cpp37
-rw-r--r--src/checker.cpp25
3 files changed, 47 insertions, 42 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index f8893eb67..7b71f43b6 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -478,8 +478,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
bool is_export = e->Procedure.is_export;
bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
- AttributeContext ac = {};
- ac.link_prefix = e->Procedure.link_prefix;
+ AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
if (d != nullptr) {
check_decl_attributes(c, d->attributes, proc_decl_attribute, &ac);
@@ -552,12 +551,14 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
pt->require_results = is_require_results;
}
-
+ if (ac.link_name.len > 0) {
+ e->Procedure.link_name = ac.link_name;
+ }
if (is_foreign) {
String name = e->token.string;
- if (ac.link_name.len > 0) {
- name = ac.link_name;
+ if (e->Procedure.link_name.len > 0) {
+ name = e->Procedure.link_name;
}
e->Procedure.is_foreign = true;
e->Procedure.link_name = name;
@@ -592,15 +593,11 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
}
} else {
String name = e->token.string;
- if (ac.link_name.len > 0) {
- name = ac.link_name;
+ if (e->Procedure.link_name.len > 0) {
+ name = e->Procedure.link_name;
}
-
- if (ac.link_name.len > 0 || is_export) {
+ if (e->Procedure.link_name.len > 0 || is_export) {
auto *fp = &c->info.foreigns;
-
- e->Procedure.link_name = name;
-
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
if (found) {
@@ -630,9 +627,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
}
e->flags |= EntityFlag_Visited;
- AttributeContext ac = {};
- ac.entity = e;
- ac.link_prefix = e->Variable.link_prefix;
+ AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
ac.init_expr_list_count = init_expr_list.count;
DeclInfo *decl = decl_info_of_entity(&c->info, e);
@@ -641,7 +636,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
}
ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix, ac.link_prefix_overridden);
-
+ e->Variable.thread_local_model = ac.thread_local_model;
String context_name = str_lit("variable declaration");
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 162a87994..11e0b8e52 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -1661,14 +1661,12 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
case_ast_node(fb, ForeignBlockDecl, node);
AstNode *foreign_library = fb->foreign_library;
- bool ok = true;
+ CheckerContext prev_context = c->context;
+ defer (c->context = prev_context);
+
if (foreign_library->kind != AstNode_Ident) {
error(foreign_library, "foreign library name must be an identifier");
- ok = false;
- }
-
- CheckerContext prev_context = c->context;
- if (ok) {
+ } else {
c->context.foreign_context.curr_library = foreign_library;
c->context.foreign_context.default_cc = ProcCC_CDecl;
}
@@ -1681,8 +1679,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
check_stmt(c, decl, flags);
}
}
-
- c->context = prev_context;
case_end;
case_ast_node(vd, ValueDecl, node);
@@ -1692,7 +1688,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
Entity **entities = gb_alloc_array(c->allocator, Entity *, vd->names.count);
isize entity_count = 0;
-
for_array(i, vd->names) {
AstNode *name = vd->names[i];
Entity *entity = nullptr;
@@ -1750,6 +1745,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
}
}
+
+ // TODO NOTE(bill): This technically checks things multple times
+ AttributeContext ac = make_attribute_context(c->context.foreign_context.link_prefix);
+ check_decl_attributes(c, vd->attributes, var_decl_attribute, &ac);
+
for (isize i = 0; i < entity_count; i++) {
Entity *e = entities[i];
GB_ASSERT(e != nullptr);
@@ -1762,11 +1762,12 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
if (e->type == nullptr) {
e->type = init_type;
}
+ ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix, ac.link_prefix_overridden);
+ e->Variable.thread_local_model = ac.thread_local_model;
-
- AttributeContext ac = {};
- ac.entity = e;
- check_decl_attributes(c, vd->attributes, var_decl_attribute, &ac);
+ if (ac.link_name.len > 0) {
+ e->Variable.link_name = ac.link_name;
+ }
}
check_arity_match(c, vd);
@@ -1778,9 +1779,17 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
if (vd->values.count > 0) {
error(e->token, "A foreign variable declaration cannot have a default value");
}
- init_entity_foreign_library(c, e);
String name = e->token.string;
+ if (e->Variable.link_name.len > 0) {
+ name = e->Variable.link_name;
+ }
+
+ if (vd->values.count > 0) {
+ error(e->token, "A foreign variable declaration cannot have a default value");
+ }
+ init_entity_foreign_library(c, e);
+
auto *fp = &c->info.foreigns;
HashKey key = hash_string(name);
Entity **found = map_get(fp, key);
diff --git a/src/checker.cpp b/src/checker.cpp
index 0ef3de9fd..a10b503b4 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1863,18 +1863,22 @@ struct AttributeContext {
String link_name;
String link_prefix;
bool link_prefix_overridden;
- Entity *entity;
isize init_expr_list_count;
+ String thread_local_model;
};
+AttributeContext make_attribute_context(String link_prefix) {
+ AttributeContext ac = {};
+ ac.link_prefix = link_prefix;
+ return ac;
+}
+
#define DECL_ATTRIBUTE_PROC(_name) bool _name(Checker *c, AstNode *elem, String name, ExactValue value, AttributeContext *ac)
typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc);
void check_decl_attributes(Checker *c, Array<AstNode *> attributes, DeclAttributeProc *proc, AttributeContext *ac);
-
-
DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
if (name == "default_calling_convention") {
if (value.kind == ExactValue_String) {
@@ -1905,8 +1909,6 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
return false;
}
-
-
DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
if (name == "link_name") {
if (value.kind == ExactValue_String) {
@@ -1936,11 +1938,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
}
DECL_ATTRIBUTE_PROC(var_decl_attribute) {
- GB_ASSERT(ac->entity != nullptr);
- Entity *e = ac->entity;
- GB_ASSERT(e->kind == Entity_Variable);
-
- if (!e->scope->is_file) {
+ if (c->context.curr_proc_decl != nullptr) {
error(elem, "Only a variable at file scope can have a `%.*s`", LIT(name));
return true;
}
@@ -1971,14 +1969,16 @@ 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->context.foreign_context.curr_library || c->context.foreign_context.in_export) {
+ error(elem, "A foreign block variable cannot be thread local");
} else if (value.kind == ExactValue_Invalid) {
- e->Variable.thread_local_model = str_lit("default");
+ ac->thread_local_model = str_lit("default");
} else if (value.kind == ExactValue_String) {
String model = value.value_string;
if (model == "localdynamic" ||
model == "initialexec" ||
model == "localexec") {
- e->Variable.thread_local_model = model;
+ ac->thread_local_model = model;
} else {
error(elem, "Invalid thread local model `%.*s`", LIT(model));
}
@@ -1992,6 +1992,7 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
+
#include "check_expr.cpp"
#include "check_type.cpp"
#include "check_decl.cpp"