From f7e9649be466ea03f556e2918063c5a4d0d28e2e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 12 Dec 2017 18:21:40 +0000 Subject: Disable struct field reordering (for the time being) --- src/check_type.cpp | 214 +++-------------------------------------------------- 1 file changed, 12 insertions(+), 202 deletions(-) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index d1552a965..8600f1a55 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -34,198 +34,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map } - -void check_struct_field_decl(Checker *c, AstNode *decl, Array *fields, Map *entity_map, AstNode *struct_node, String context, bool allow_default_values) { - GB_ASSERT(fields != nullptr); - if (decl->kind == AstNode_WhenStmt) { - ast_node(ws, WhenStmt, decl); - Operand operand = {Addressing_Invalid}; - check_expr(c, &operand, ws->cond); - if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) { - error(ws->cond, "Non-constant boolean 'when' condition"); - return; - } - if (ws->body == nullptr || ws->body->kind != AstNode_BlockStmt) { - error(ws->cond, "Invalid body for 'when' statement"); - return; - } - if (operand.value.kind == ExactValue_Bool && - operand.value.value_bool) { - for_array(i, ws->body->BlockStmt.stmts) { - AstNode *stmt = ws->body->BlockStmt.stmts[i]; - check_struct_field_decl(c, stmt, fields, entity_map, struct_node, context, allow_default_values); - } - } else if (ws->else_stmt) { - switch (ws->else_stmt->kind) { - case AstNode_BlockStmt: - for_array(i, ws->else_stmt->BlockStmt.stmts) { - AstNode *stmt = ws->else_stmt->BlockStmt.stmts[i]; - check_struct_field_decl(c, stmt, fields, entity_map, struct_node, context, allow_default_values); - } - break; - case AstNode_WhenStmt: - check_struct_field_decl(c, ws->else_stmt, fields, entity_map, struct_node, context, allow_default_values); - break; - default: - error(ws->else_stmt, "Invalid 'else' statement in 'when' statement"); - break; - } - } - } - - if (decl->kind != AstNode_ValueDecl) { - return; - } - - - ast_node(vd, ValueDecl, decl); - - if (!vd->is_mutable) return; - - bool is_using = vd->is_using; - - if (is_using && vd->names.count > 1) { - error(vd->names[0], "Cannot apply 'using' to more than one of the same type"); - is_using = false; - } - - bool arity_ok = check_arity_match(c, vd); - - if (vd->values.count > 0 && !allow_default_values) { - error(vd->values[0], "Default values are not allowed within a %.*s", LIT(context)); - } - - - Type *type = nullptr; - if (vd->type != nullptr) { - type = check_type(c, vd->type); - } else if (!allow_default_values) { - error(vd->names[0], "Expected a type for this field"); - type = t_invalid; - } - - if (type != nullptr) { - if (is_type_empty_union(type)) { - error(vd->names[0], "An empty union cannot be used as a field type in %.*s", LIT(context)); - type = t_invalid; - } - if (!c->context.allow_polymorphic_types && is_type_polymorphic(base_type(type))) { - error(vd->names[0], "Invalid use of a polymorphic type in %.*s", LIT(context)); - type = t_invalid; - } - } - - Array default_values = {}; - defer (array_free(&default_values)); - if (vd->values.count > 0 && allow_default_values) { - array_init(&default_values, heap_allocator(), 2*vd->values.count); - - Type *type_hint = nullptr; - if (type != t_invalid && type != nullptr) { - type_hint = type; - } - - for_array(i, vd->values) { - AstNode *v = vd->values[i]; - Operand o = {}; - - check_expr_base(c, &o, v, type_hint); - check_not_tuple(c, &o); - - if (o.mode == Addressing_NoValue) { - error_operand_no_value(&o); - } else { - if (o.mode == Addressing_Value && o.type->kind == Type_Tuple) { - // NOTE(bill): Tuples are not first class thus never named - for_array(index, o.type->Tuple.variables) { - Operand single = {Addressing_Value}; - single.type = o.type->Tuple.variables[index]->type; - single.expr = v; - array_add(&default_values, single); - } - } else { - array_add(&default_values, o); - } - } - } - } - - - isize name_field_index = 0; - for_array(name_index, vd->names) { - AstNode *name = vd->names[name_index]; - if (!ast_node_expect(name, AstNode_Ident)) { - return; - } - - Token name_token = name->Ident.token; - - Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, is_using, cast(i32)fields->count); - e->identifier = name; - - if (name_field_index < default_values.count) { - Operand a = default_values[name_field_index]; - Operand b = default_values[name_field_index]; - check_init_variable(c, e, &b, str_lit("struct field assignment")); - if (is_operand_nil(a)) { - e->Variable.default_is_nil = true; - } else if (is_operand_undef(a)) { - e->Variable.default_is_undef = true; - } else if (b.mode != Addressing_Constant) { - error(b.expr, "Default field value must be a constant"); - } else if (is_type_any(e->type) || is_type_union(e->type)) { - gbString str = type_to_string(e->type); - error(b.expr, "A struct field of type '%s' cannot have a default value", str); - gb_string_free(str); - } else { - e->Variable.default_value = b.value; - } - - name_field_index++; - } - - GB_ASSERT(e->type != nullptr); - GB_ASSERT(is_type_typed(e->type)); - - if (is_blank_ident(name_token)) { - array_add(fields, e); - } else { - HashKey key = hash_string(name_token.string); - Entity **found = map_get(entity_map, key); - if (found != nullptr) { - Entity *e = *found; - // NOTE(bill): Scope checking already checks the declaration but in many cases, this can happen so why not? - // This may be a little janky but it's not really that much of a problem - error(name_token, "'%.*s' is already declared in this type", LIT(name_token.string)); - error(e->token, "\tpreviously declared"); - } else { - map_set(entity_map, key, e); - array_add(fields, e); - add_entity(c, c->context.scope, name, e); - } - add_entity_use(c, name, e); - } - - } - - - if (is_using && fields->count > 0) { - Type *first_type = (*fields)[fields->count-1]->type; - Type *t = base_type(type_deref(first_type)); - if (!is_type_struct(t) && !is_type_raw_union(t) && !is_type_bit_field(t) && - vd->names.count >= 1 && - vd->names[0]->kind == AstNode_Ident) { - Token name_token = vd->names[0]->Ident.token; - gbString type_str = type_to_string(first_type); - error(name_token, "'using' cannot be applied to the field '%.*s' of type '%s'", LIT(name_token.string), type_str); - gb_string_free(type_str); - return; - } - - populate_using_entity_map(c, struct_node, type, entity_map); - } -} - // Returns filled field_count Array check_struct_fields(Checker *c, AstNode *node, Array params, isize init_field_capacity, Type *named_type, String context) { @@ -301,6 +109,10 @@ Array check_struct_fields(Checker *c, AstNode *node, Array type = default_type(o.type); } else { + if (type_expr->kind == AstNode_Ident && type_expr->Ident.token.string == "Element") { + gb_printf_err("Element\n"); + } + type = check_type(c, type_expr); if (default_value != nullptr) { @@ -398,11 +210,6 @@ Array check_struct_fields(Checker *c, AstNode *node, Array } } - // for_array(decl_index, params) { - // check_struct_field_decl(c, params[decl_index], &fields, &entity_map, node, context, context == "struct"); - // } - - return fields; } @@ -488,8 +295,10 @@ bool check_custom_align(Checker *c, AstNode *node, i64 *align_) { Entity *find_polymorphic_struct_entity(Checker *c, Type *original_type, isize param_count, Array ordered_operands) { - auto *found_gen_types = map_get(&c->info.gen_types, hash_pointer(original_type)); + gb_mutex_lock(&c->mutex); + defer (gb_mutex_unlock(&c->mutex)); + auto *found_gen_types = map_get(&c->info.gen_types, hash_pointer(original_type)); if (found_gen_types != nullptr) { for_array(i, *found_gen_types) { Entity *e = (*found_gen_types)[i]; @@ -761,12 +570,15 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, ArrayStruct.is_raw_union) { type_set_offsets(c->allocator, struct_type); if (!struct_type->failure && !st->is_packed && !st->is_ordered) { struct_type->failure = false; struct_type->Struct.are_offsets_set = false; + struct_type->Struct.are_offsets_being_processed = false; gb_zero_item(&struct_type->Struct.offsets); // NOTE(bill): Reorder fields for reduced size/performance @@ -791,7 +603,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Arrayallocator, struct_type); } - +#endif if (st->align != nullptr) { if (st->is_packed) { @@ -2195,9 +2007,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) case_end; case_ast_node(pt, PointerType, e); - Type *elem = check_type(c, pt->type); - i64 esz = type_size_of(c->allocator, elem); - *type = make_type_pointer(c->allocator, elem); + *type = make_type_pointer(c->allocator, check_type(c, pt->type)); return true; case_end; -- cgit v1.2.3