aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-02-11 15:50:24 +0000
committerGinger Bill <bill@gingerbill.org>2017-02-11 15:50:24 +0000
commit346aa5f71ca4e3d6a71187024f809eaf2fc6da1b (patch)
treed61331a1bf713f66bcdba8816b8b01eef3e643b2 /src/check_expr.c
parent73d6a55f5c96459d30eca5747d1458bcf6e9fec4 (diff)
Only check files that have been truly imported.
Diffstat (limited to 'src/check_expr.c')
-rw-r--r--src/check_expr.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index d3bc5895c..bec36496f 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -360,6 +360,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Token name_token = name->Ident;
+ if (str_eq(name_token.string, str_lit(""))) {
+ error(name_token, "`names` is a reserved identifier for unions");
+ continue;
+ }
+
Type *type = make_type_named(c->allocator, name_token.string, base_type, NULL);
Entity *e = make_entity_type_name(c->allocator, c->context.scope, name_token, type);
type->Named.type_name = e;
@@ -521,6 +526,11 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
struct_type->Record.fields_in_src_order = fields;
struct_type->Record.field_count = field_count;
+ // struct_type->Record.names = make_entity_field(c->allocator, c->context.scope,
+ // make_token_ident(str_lit("names")), t_string_slice, false, 0);
+ // struct_type->Record.names->Variable.is_immutable = true;
+ // struct_type->Record.names->flags |= EntityFlag_TypeField;
+
if (!st->is_packed && !st->is_ordered) {
// NOTE(bill): Reorder fields for reduced size/performance
@@ -605,6 +615,11 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
union_type->Record.fields = fields;
union_type->Record.field_count = field_count;
+
+ // union_type->Record.names = make_entity_field(c->allocator, c->context.scope,
+ // make_token_ident(str_lit("names")), t_string_slice, false, 0);
+ // union_type->Record.names->Variable.is_immutable = true;
+ // union_type->Record.names->flags |= EntityFlag_TypeField;
}
void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
@@ -628,6 +643,11 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
union_type->Record.fields = fields;
union_type->Record.field_count = field_count;
+
+// union_type->Record.names = make_entity_field(c->allocator, c->context.scope,
+// make_token_ident(str_lit("names")), t_string_slice, false, 0);
+// union_type->Record.names->Variable.is_immutable = true;
+// union_type->Record.names->flags |= EntityFlag_TypeField;
}
// GB_COMPARE_PROC(cmp_enum_order) {
@@ -664,6 +684,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
error_node(node, "Base type for enumeration must be numeric");
return;
}
+ if (is_type_enum(base_type)) {
+ error_node(node, "Base type for enumeration cannot be another enumeration");
+ return;
+ }
// NOTE(bill): Must be up here for the `check_init_constant` system
enum_type->Record.enum_base_type = base_type;
@@ -764,8 +788,9 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
add_entity_use(c, field, e);
}
}
-
GB_ASSERT(field_count <= et->fields.count);
+ gb_temp_arena_memory_end(tmp);
+
enum_type->Record.fields = fields;
enum_type->Record.field_count = field_count;
@@ -777,12 +802,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
enum_type->Record.enum_max_value = make_entity_constant(c->allocator, c->context.scope,
make_token_ident(str_lit("max_value")), constant_type, max_value);
- enum_type->Record.enum_names = make_entity_field(c->allocator, c->context.scope,
+ enum_type->Record.names = make_entity_field(c->allocator, c->context.scope,
make_token_ident(str_lit("names")), t_string_slice, false, 0);
- enum_type->Record.enum_names->Variable.is_immutable = true;
- enum_type->Record.enum_names->flags |= EntityFlag_EnumField;
-
- gb_temp_arena_memory_end(tmp);
+ enum_type->Record.names->Variable.is_immutable = true;
+ enum_type->Record.names->flags |= EntityFlag_TypeField;
}
@@ -2513,11 +2536,13 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
check_op_expr = false;
entity = scope_lookup_entity(e->ImportName.scope, sel_name);
bool is_declared = entity != NULL;
- if (entity->kind == Entity_Builtin) {
- is_declared = false;
- }
- if (entity->scope->is_global && !e->ImportName.scope->is_global) {
- is_declared = false;
+ if (is_declared) {
+ if (entity->kind == Entity_Builtin) {
+ is_declared = false;
+ }
+ if (entity->scope->is_global && !e->ImportName.scope->is_global) {
+ is_declared = false;
+ }
}
if (!is_declared) {
error_node(op_expr, "`%.*s` is not declared by `%.*s`", LIT(sel_name), LIT(name));
@@ -2613,8 +2638,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
sel = lookup_field(c->allocator, operand->type, selector->Ident.string, operand->mode == Addressing_Type);
entity = sel.entity;
- // NOTE(bill): Add enum type info needed for fields like `names`
- if (entity != NULL && (entity->flags&EntityFlag_EnumField)) {
+ // NOTE(bill): Add type info needed for fields like `names`
+ if (entity != NULL && (entity->flags&EntityFlag_TypeField)) {
add_type_info_type(c, operand->type);
}
}
@@ -4575,18 +4600,28 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
case Type_Slice:
case Type_Array:
case Type_Vector:
+ case Type_DynamicArray:
{
Type *elem_type = NULL;
String context_name = {0};
+ i64 max_type_count = -1;
if (t->kind == Type_Slice) {
elem_type = t->Slice.elem;
context_name = str_lit("slice literal");
} else if (t->kind == Type_Vector) {
elem_type = t->Vector.elem;
context_name = str_lit("vector literal");
- } else {
+ max_type_count = t->Vector.count;
+ } else if (t->kind == Type_Array) {
elem_type = t->Array.elem;
context_name = str_lit("array literal");
+ max_type_count = t->Array.count;
+ } else if (t->kind == Type_DynamicArray) {
+ elem_type = t->DynamicArray.elem;
+ context_name = str_lit("dynamic array literal");
+ is_constant = false;
+ } else {
+ GB_PANIC("unreachable");
}
@@ -4606,15 +4641,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
continue;
}
- if (t->kind == Type_Array &&
- t->Array.count >= 0 &&
- index >= t->Array.count) {
- error_node(e, "Index %lld is out of bounds (>= %lld) for array literal", index, t->Array.count);
- }
- if (t->kind == Type_Vector &&
- t->Vector.count >= 0 &&
- index >= t->Vector.count) {
- error_node(e, "Index %lld is out of bounds (>= %lld) for vector literal", index, t->Vector.count);
+ if (0 <= max_type_count && max_type_count <= index) {
+ error_node(e, "Index %lld is out of bounds (>= %lld) for %.*s", index, max_type_count, LIT(context_name));
}
Operand operand = {0};
@@ -5153,6 +5181,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
case_end;
+ case AstNode_HelperType:
case AstNode_ProcType:
case AstNode_PointerType:
case AstNode_ArrayType: