aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-05-14 00:13:26 +0100
committergingerBill <bill@gingerbill.org>2020-05-14 00:13:26 +0100
commitf661d3404952d33d4cb683899ebd05d4b580b2bc (patch)
tree79f957be88db8740ebdf214a8107672f88a67052 /src
parentaf1d4d6e72eeb75b32c40f3d4ca7bf6a78e8a043 (diff)
Implement Explicit context creation #639
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp9
-rw-r--r--src/check_type.cpp22
-rw-r--r--src/checker.cpp5
-rw-r--r--src/checker.hpp4
4 files changed, 31 insertions, 9 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index d55692a41..159ae5e3a 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -7724,6 +7724,15 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
return kind;
}
+ if (unparen_expr(c->assignment_lhs_hint) == node) {
+ c->scope->flags |= ScopeFlag_ContextDefined;
+ }
+
+ if ((c->scope->flags & ScopeFlag_ContextDefined) == 0) {
+ error(node, "'context' has not been defined within this scope");
+ // Continue with value
+ }
+
init_core_context(c->checker);
o->mode = Addressing_Context;
o->type = t_context;
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 976c945fd..8d8bae1a7 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2501,6 +2501,19 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
c->curr_proc_sig = type;
c->in_proc_sig = true;
+
+ ProcCallingConvention cc = pt->calling_convention;
+ if (cc == ProcCC_ForeignBlockDefault) {
+ cc = ProcCC_CDecl;
+ if (c->foreign_context.default_cc > 0) {
+ cc = c->foreign_context.default_cc;
+ }
+ }
+ GB_ASSERT(cc > 0);
+ if (cc == ProcCC_Odin) {
+ c->scope->flags |= ScopeFlag_ContextDefined;
+ }
+
bool variadic = false;
isize variadic_index = -1;
bool success = true;
@@ -2534,14 +2547,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
}
- ProcCallingConvention cc = pt->calling_convention;
- if (cc == ProcCC_ForeignBlockDefault) {
- cc = ProcCC_CDecl;
- if (c->foreign_context.default_cc > 0) {
- cc = c->foreign_context.default_cc;
- }
- }
- GB_ASSERT(cc > 0);
+
bool optional_ok = (pt->tags & ProcTag_optional_ok) != 0;
if (optional_ok) {
diff --git a/src/checker.cpp b/src/checker.cpp
index 992aeb9b3..2bf79134d 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -231,6 +231,11 @@ Scope *create_scope(Scope *parent, gbAllocator allocator, isize init_elements_ca
if (parent != nullptr && parent != builtin_pkg->scope) {
DLIST_APPEND(parent->first_child, parent->last_child, s);
}
+
+ if (parent != nullptr && parent->flags & ScopeFlag_ContextDefined) {
+ s->flags |= ScopeFlag_ContextDefined;
+ }
+
return s;
}
diff --git a/src/checker.hpp b/src/checker.hpp
index 5f5486fe2..efd6aae54 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -158,7 +158,7 @@ struct ProcInfo {
-enum ScopeFlag {
+enum ScopeFlag : i32 {
ScopeFlag_Pkg = 1<<1,
ScopeFlag_Global = 1<<2,
ScopeFlag_File = 1<<3,
@@ -167,6 +167,8 @@ enum ScopeFlag {
ScopeFlag_Type = 1<<6,
ScopeFlag_HasBeenImported = 1<<10, // This is only applicable to file scopes
+
+ ScopeFlag_ContextDefined = 1<<16,
};
struct Scope {