Tagged unions memory layout change; begin demo 002

This commit is contained in:
Ginger Bill
2016-09-04 22:50:17 +01:00
parent c2e3c3801a
commit ae72b3c5bd
7 changed files with 142 additions and 83 deletions
+34 -23
View File
@@ -1934,9 +1934,11 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
switch (id) {
case BuiltinProc_new: {
// new :: proc(Type) -> ^Type
Type *type = check_type(c, ce->arg_list);
if (type == NULL || type == t_invalid) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
Operand op = {};
check_expr_or_type(c, &op, ce->arg_list);
Type *type = op.type;
if (op.mode != Addressing_Type && type == NULL || type == t_invalid) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new`");
return false;
}
operand->mode = Addressing_Value;
@@ -1944,16 +1946,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
} break;
case BuiltinProc_new_slice: {
// new_slice :: proc(Type, len: int[, cap: int]) -> []Type
Type *type = check_type(c, ce->arg_list);
if (type == NULL || type == t_invalid) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
Operand op = {};
check_expr_or_type(c, &op, ce->arg_list);
Type *type = op.type;
if (op.mode != Addressing_Type && type == NULL || type == t_invalid) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new_slice`");
return false;
}
AstNode *len = ce->arg_list->next;
AstNode *cap = len->next;
Operand op = {};
check_expr(c, &op, len);
if (op.mode == Addressing_Invalid)
return false;
@@ -1967,7 +1970,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (cap != NULL) {
check_expr(c, &op, len);
check_expr(c, &op, cap);
if (op.mode == Addressing_Invalid)
return false;
if (!is_type_integer(op.type)) {
@@ -2006,7 +2009,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_size_of: {
// size_of :: proc(Type) -> int
Type *type = check_type(c, ce->arg_list);
Operand op = {};
check_expr_or_type(c, &op, ce->arg_list);
Type *type = op.type;
if (!type) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`");
return false;
@@ -2031,7 +2036,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_align_of: {
// align_of :: proc(Type) -> int
Type *type = check_type(c, ce->arg_list);
Operand op = {};
check_expr_or_type(c, &op, ce->arg_list);
Type *type = op.type;
if (!type) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `align_of`");
return false;
@@ -2054,18 +2061,22 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_offset_of: {
// offset_val :: proc(Type, field) -> int
Type *type = get_base_type(check_type(c, ce->arg_list));
Operand op = {};
check_expr_or_type(c, &op, ce->arg_list);
Type *type = get_base_type(op.type);
AstNode *field_arg = unparen_expr(ce->arg_list->next);
if (type) {
if (!is_type_struct(type)) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a structure type for `offset_of`");
return false;
}
if (field_arg == NULL ||
field_arg->kind != AstNode_Ident) {
error(&c->error_collector, ast_node_token(field_arg), "Expected an identifier for field argument");
return false;
}
if (type != NULL) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `offset_of`");
return false;
}
if (!is_type_struct(type)) {
error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a structure type for `offset_of`");
return false;
}
if (field_arg == NULL ||
field_arg->kind != AstNode_Ident) {
error(&c->error_collector, ast_node_token(field_arg), "Expected an identifier for field argument");
return false;
}
@@ -2145,7 +2156,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
gbString str = expr_to_string(ce->arg_list);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"Static assertion: `%s`", str);
"Compile time assertion: `%s`", str);
return true;
}
if (operand->mode != Addressing_Constant) {
@@ -2468,7 +2479,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (cap != NULL) {
check_expr(c, &op, len);
check_expr(c, &op, cap);
if (op.mode == Addressing_Invalid)
return false;
if (!is_type_integer(op.type)) {
+12 -17
View File
@@ -1238,22 +1238,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
switch (e->kind) {
case Entity_TypeName: {
Type *t = get_base_type(e->type);
if (is_type_enum(t)) {
if (is_type_struct(t) || is_type_enum(t)) {
for (isize i = 0; i < t->Record.other_field_count; i++) {
Entity *f = t->Record.other_fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of the constant: %.*s", expr_str, LIT(found->token.string));
return;
}
f->using_parent = e;
}
} else if (is_type_struct(t)) {
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
GB_ASSERT(found != NULL);
gb_for_array(i, (*found)->elements.entries) {
Entity *f = (*found)->elements.entries[i].value;
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
return;
@@ -1261,10 +1249,17 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
f->using_parent = e;
}
} else if (is_type_union(t)) {
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
GB_ASSERT(found != NULL);
gb_for_array(i, (*found)->elements.entries) {
Entity *f = (*found)->elements.entries[i].value;
for (isize i = 0; i < t->Record.field_count; i++) {
Entity *f = t->Record.fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
return;
}
f->using_parent = e;
}
for (isize i = 0; i < t->Record.other_field_count; i++) {
Entity *f = t->Record.other_fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
error(&c->error_collector, us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
+3 -3
View File
@@ -117,8 +117,8 @@ struct Type {
// All record types
// Theses are arrays
Entity **fields; // Entity_Variable
isize field_count; // == offset_count
Entity **fields; // Entity_Variable (otherwise Entity_TypeName if union)
isize field_count; // == offset_count is struct
AstNode *node;
// enum only
@@ -909,7 +909,7 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
if (max < size)
max = size;
}
return type_size_of(s, allocator, t_int) + max;
return align_formula(max, s.max_align) + type_size_of(s, allocator, t_int);
} break;
case TypeRecord_RawUnion: {