diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-07-30 14:52:42 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-07-30 14:52:42 +0100 |
| commit | 62a72f0163b2f35ca11cd8f4bbb4c7de2c66fca4 (patch) | |
| tree | e334be658d8ed4018e8ae8bb37334dbc1834f14c /src | |
| parent | 655931f0ea282f8dbaa769a213311a774e4f84c6 (diff) | |
`transmute(type)x`; Minor code clean up
Diffstat (limited to 'src')
| -rw-r--r-- | src/build_settings.cpp | 10 | ||||
| -rw-r--r-- | src/check_decl.cpp | 16 | ||||
| -rw-r--r-- | src/check_expr.cpp | 57 | ||||
| -rw-r--r-- | src/checker.cpp | 44 | ||||
| -rw-r--r-- | src/ir.cpp | 87 | ||||
| -rw-r--r-- | src/ir_print.cpp | 28 | ||||
| -rw-r--r-- | src/parser.cpp | 7 | ||||
| -rw-r--r-- | src/tokenizer.cpp | 1 | ||||
| -rw-r--r-- | src/types.cpp | 17 |
9 files changed, 169 insertions, 98 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 3f5530da4..4b5ffdc64 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -160,6 +160,7 @@ String odin_root_dir(void) { } array_init_count(&path_buf, heap_allocator(), 300); + defer (array_free(&path_buf)); len = 0; for (;;) { @@ -179,7 +180,10 @@ String odin_root_dir(void) { tmp = gb_temp_arena_memory_begin(&string_buffer_arena); + defer (gb_temp_arena_memory_end(tmp)); + text = gb_alloc_array(string_buffer_allocator, u8, len + 1); + gb_memmove(text, &path_buf[0], len); path = make_string(text, len); @@ -194,10 +198,6 @@ String odin_root_dir(void) { global_module_path = path; global_module_path_set = true; - gb_temp_arena_memory_end(tmp); - - array_free(&path_buf); - return path; } #endif @@ -267,7 +267,7 @@ String get_fullpath_core(gbAllocator a, String path) { } -String const ODIN_VERSION = str_lit("0.6.0-dev"); +String const ODIN_VERSION = str_lit("0.6.0"); void init_build_context(void) { BuildContext *bc = &build_context; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 72ca6d7c4..8b2ab0941 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -319,14 +319,12 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) { if (is_type_integer(x) && is_type_integer(y)) { GB_ASSERT(x->kind == Type_Basic); GB_ASSERT(y->kind == Type_Basic); - if (x->Basic.size == y->Basic.size) { - continue; - } + i64 sx = type_size_of(heap_allocator(), x); + i64 sy = type_size_of(heap_allocator(), y); + if (sx == sy) continue; } - if (!are_types_identical(x, y)) { - return false; - } + if (!are_types_identical(x, y)) return false; } for (isize i = 0; i < a->result_count; i++) { Type *x = base_type(a->results->Tuple.variables[i]->type); @@ -338,9 +336,9 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) { if (is_type_integer(x) && is_type_integer(y)) { GB_ASSERT(x->kind == Type_Basic); GB_ASSERT(y->kind == Type_Basic); - if (x->Basic.size == y->Basic.size) { - continue; - } + i64 sx = type_size_of(heap_allocator(), x); + i64 sy = type_size_of(heap_allocator(), y); + if (sx == sy) continue; } if (!are_types_identical(x, y)) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 4ac092b64..ae7018a8c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2121,6 +2121,10 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari type = determine_type_from_polymorphic(c, type, op); if (type == t_invalid) { success = false; + } else if (!c->context.no_polymorphic_errors) { + // NOTE(bill): The type should be determined now and thus, no need to determine the type any more + is_type_polymorphic_type = false; + // is_type_polymorphic_type = is_type_polymorphic(base_type(type)); } } @@ -3959,6 +3963,43 @@ void check_cast(Checker *c, Operand *x, Type *type) { x->type = type; } +bool check_transmute(Checker *c, AstNode *node, Operand *o, Type *t) { + if (o->mode == Addressing_Constant) { + gbString expr_str = expr_to_string(o->expr); + error(o->expr, "Cannot transmute a constant expression: `%s`", expr_str); + gb_string_free(expr_str); + o->mode = Addressing_Invalid; + o->expr = node; + return false; + } + + if (is_type_untyped(o->type)) { + gbString expr_str = expr_to_string(o->expr); + error(o->expr, "Cannot transmute untyped expression: `%s`", expr_str); + gb_string_free(expr_str); + o->mode = Addressing_Invalid; + o->expr = node; + return false; + } + + i64 srcz = type_size_of(c->allocator, o->type); + i64 dstz = type_size_of(c->allocator, t); + if (srcz != dstz) { + gbString expr_str = expr_to_string(o->expr); + gbString type_str = type_to_string(t); + error(o->expr, "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz); + gb_string_free(type_str); + gb_string_free(expr_str); + o->mode = Addressing_Invalid; + o->expr = node; + return false; + } + + o->mode = Addressing_Value; + o->type = t; + return true; +} + bool check_binary_vector_expr(Checker *c, Token op, Operand *x, Operand *y) { if (is_type_vector(x->type) && !is_type_vector(y->type)) { if (check_is_assignable_to(c, y, x->type)) { @@ -4870,7 +4911,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id case BuiltinProc_align_of: case BuiltinProc_offset_of: case BuiltinProc_type_info_of: - case BuiltinProc_transmute: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; default: @@ -5891,6 +5931,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id } } break; + #if 0 case BuiltinProc_transmute: { Operand op = {}; check_expr_or_type(c, &op, ce->args[0]); @@ -5940,6 +5981,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id o->mode = Addressing_Value; o->type = t; } break; + #endif } return true; @@ -7814,7 +7856,18 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t Type *type = o->type; check_expr_base(c, o, tc->expr, type); if (o->mode != Addressing_Invalid) { - check_cast(c, o, type); + switch (tc->token.kind) { + case Token_transmute: + check_transmute(c, node, o, type); + break; + case Token_cast: + check_cast(c, o, type); + break; + default: + error(node, "Invalid AST: Invalid casting expression"); + o->mode = Addressing_Invalid; + break; + } } return Expr_Expr; case_end; diff --git a/src/checker.cpp b/src/checker.cpp index ec907cc1d..c243c704b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -61,8 +61,6 @@ enum BuiltinProcId { BuiltinProc_abs, BuiltinProc_clamp, - BuiltinProc_transmute, - BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures BuiltinProc_COUNT, @@ -107,8 +105,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("abs"), 1, false, Expr_Expr}, {STR_LIT("clamp"), 3, false, Expr_Expr}, - {STR_LIT("transmute"), 2, false, Expr_Expr}, - {STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE }; @@ -2172,33 +2168,37 @@ void check_import_entities(Checker *c, Map<Scope *> *file_scopes) { scope->has_been_imported = true; if (id->import_name.string == ".") { - // NOTE(bill): Add imported entities to this file's scope - for_array(elem_index, scope->elements.entries) { - Entity *e = scope->elements.entries[elem_index].value; - if (e->scope == parent_scope) { - continue; - } + if (parent_scope->is_global) { + error(id->import_name, "#shared_global_scope imports cannot use ."); + } else { + // NOTE(bill): Add imported entities to this file's scope + for_array(elem_index, scope->elements.entries) { + Entity *e = scope->elements.entries[elem_index].value; + if (e->scope == parent_scope) { + continue; + } - if (!is_entity_kind_exported(e->kind)) { - continue; - } - if (id->is_import) { - if (is_entity_exported(e)) { - // TODO(bill): Should these entities be imported but cause an error when used? - bool ok = add_entity(c, parent_scope, e->identifier, e); - if (ok) { - map_set(&parent_scope->implicit, hash_entity(e), true); + if (!is_entity_kind_exported(e->kind)) { + continue; + } + if (id->is_import) { + if (is_entity_exported(e)) { + // TODO(bill): Should these entities be imported but cause an error when used? + bool ok = add_entity(c, parent_scope, e->identifier, e); + if (ok) { + map_set(&parent_scope->implicit, hash_entity(e), true); + } } + } else { + add_entity(c, parent_scope, e->identifier, e); } - } else { - add_entity(c, parent_scope, e->identifier, e); } } } else { String import_name = path_to_entity_name(id->import_name.string, id->fullpath); if (is_blank_ident(import_name)) { - error(token, "File name, %.*s, cannot be as an import name as it is not a valid identifier", LIT(id->import_name.string)); + error(token, "File name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string)); } else { GB_ASSERT(id->import_name.pos.line != 0); id->import_name.string = import_name; diff --git a/src/ir.cpp b/src/ir.cpp index a3655ae25..62603c801 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2435,52 +2435,69 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) { Type *t = base_type(ir_type(s)); Type *result_type = nullptr; - if (is_type_struct(t)) { + switch (t->kind) { + case Type_Basic: + switch (t->Basic.kind) { + case Basic_string: + switch (index) { + case 0: result_type = t_u8_ptr; break; + case 1: result_type = t_int; break; + } + break; + case Basic_any: + switch (index) { + case 0: result_type = t_rawptr; break; + case 1: result_type = t_type_info_ptr; break; + } + break; + case Basic_complex64: case Basic_complex128: + { + Type *ft = base_complex_elem_type(t); + switch (index) { + case 0: result_type = ft; break; + case 1: result_type = ft; break; + } + } break; + } + break; + case Type_Struct: result_type = t->Struct.fields[index]->type; - } else if (is_type_union(t)) { + break; + case Type_Union: GB_ASSERT(index == -1); return ir_emit_union_tag_value(proc, s); - } else if (is_type_tuple(t)) { + case Type_Tuple: GB_ASSERT(t->Tuple.variables.count > 0); result_type = t->Tuple.variables[index]->type; - } else if (is_type_complex(t)) { - Type *ft = base_complex_elem_type(t); - switch (index) { - case 0: result_type = ft; break; - case 1: result_type = ft; break; - } - } else if (is_type_slice(t)) { + break; + case Type_Slice: switch (index) { case 0: result_type = make_type_pointer(a, t->Slice.elem); break; case 1: result_type = t_int; break; case 2: result_type = t_int; break; } - } else if (is_type_string(t)) { - switch (index) { - case 0: result_type = t_u8_ptr; break; - case 1: result_type = t_int; break; - } - } else if (is_type_any(t)) { - switch (index) { - case 0: result_type = t_rawptr; break; - case 1: result_type = t_type_info_ptr; break; - } - } else if (is_type_dynamic_array(t)) { + break; + case Type_DynamicArray: switch (index) { case 0: result_type = make_type_pointer(a, t->DynamicArray.elem); break; case 1: result_type = t_int; break; case 2: result_type = t_int; break; case 3: result_type = t_allocator; break; } - } else if (is_type_map(t)) { + break; + + case Type_Map: { generate_map_internal_types(a, t); Type *gst = t->Map.generated_struct_type; switch (index) { case 0: result_type = gst->Struct.fields[0]->type; break; case 1: result_type = gst->Struct.fields[1]->type; break; } - } else { + } break; + + default: GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(ir_type(s)), index); + break; } GB_ASSERT(result_type != nullptr); @@ -2492,6 +2509,7 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) { irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) { GB_ASSERT(sel.index.count > 0); Type *type = type_deref(ir_type(e)); + gbAllocator a = proc->module->allocator; for_array(i, sel.index) { i32 index = cast(i32)sel.index[i]; @@ -2502,21 +2520,23 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) { } type = core_type(type); - if (is_type_raw_union(type)) { type = type->Struct.fields[index]->type; - e = ir_emit_conv(proc, e, make_type_pointer(proc->module->allocator, type)); + e = ir_emit_conv(proc, e, make_type_pointer(a, type)); } else if (type->kind == Type_Union) { GB_ASSERT(index == -1); type = t_type_info_ptr; e = ir_emit_struct_ep(proc, e, index); } else if (type->kind == Type_Struct) { type = type->Struct.fields[index]->type; - e = ir_emit_struct_ep(proc, e, index); + if (type->Struct.is_raw_union) { + } else { + e = ir_emit_struct_ep(proc, e, index); + } } else if (type->kind == Type_Tuple) { type = type->Tuple.variables[index]->type; e = ir_emit_struct_ep(proc, e, index); - }else if (type->kind == Type_Basic) { + } else if (type->kind == Type_Basic) { switch (type->Basic.kind) { case Basic_any: { if (index == 0) { @@ -3867,11 +3887,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv return ir_type_info(proc, t); } break; - case BuiltinProc_transmute: { - irValue *x = ir_build_expr(proc, ce->args[1]); - return ir_emit_transmute(proc, x, tv.type); - } - case BuiltinProc_len: { irValue *v = ir_build_expr(proc, ce->args[0]); Type *t = base_type(ir_type(v)); @@ -4694,7 +4709,13 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { case_ast_node(tc, TypeCast, expr); irValue *e = ir_build_expr(proc, tc->expr); - return ir_emit_conv(proc, e, tv.type); + switch (tc->token.kind) { + case Token_cast: + return ir_emit_conv(proc, e, tv.type); + case Token_transmute: + return ir_emit_transmute(proc, e, tv.type); + } + GB_PANIC("Invalid AST TypeCast"); case_end; case_ast_node(ue, UnaryExpr, expr); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index c6fb56616..58e89dbf6 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -275,7 +275,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { case Type_DynamicArray: ir_fprintf(f, "{"); ir_print_type(f, m, t->DynamicArray.elem); - ir_fprintf(f, "*, i%lld, i%lld,", word_bits, word_bits); + ir_fprintf(f, "*, i%lld, i%lld, ", word_bits, word_bits); ir_print_type(f, m, t_allocator); ir_fprintf(f, "}"); return; @@ -523,7 +523,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * if (!has_defaults) { ir_fprintf(f, "zeroinitializer"); } else { - ir_print_compound_element(f, m, empty_exact_value, type); + ir_print_exact_value(f, m, empty_exact_value, type); } break; } @@ -881,9 +881,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { case irInstr_Store: { Type *type = type_deref(ir_type(instr->Store.address)); ir_fprintf(f, "store "); - if (instr->Store.atomic) { - ir_fprintf(f, "atomic "); - } ir_print_type(f, m, type); ir_fprintf(f, " "); ir_print_value(f, m, instr->Store.value, type); @@ -891,29 +888,17 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_print_type(f, m, type); ir_fprintf(f, "* "); ir_print_value(f, m, instr->Store.address, type); - if (instr->Store.atomic) { - // TODO(bill): Do ordering - ir_fprintf(f, " unordered"); - ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type)); - } ir_fprintf(f, "\n"); } break; case irInstr_Load: { Type *type = instr->Load.type; ir_fprintf(f, "%%%d = load ", value->index); - // if (is_type_atomic(type)) { - // ir_fprintf(f, "atomic "); - // } ir_print_type(f, m, type); ir_fprintf(f, ", "); ir_print_type(f, m, type); ir_fprintf(f, "* "); ir_print_value(f, m, instr->Load.address, type); - // if (is_type_atomic(type)) { - // TODO(bill): Do ordering - // ir_fprintf(f, " unordered"); - // } ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type)); } break; @@ -1409,7 +1394,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { if (param_index > 0) ir_fprintf(f, ", "); ir_print_type(f, m, t_context_ptr); - ir_fprintf(f, " noalias nonnull"); + ir_fprintf(f, " noalias nonnull "); ir_print_value(f, m, call->context_ptr, t_context_ptr); } ir_fprintf(f, ")\n"); @@ -1568,26 +1553,27 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { #endif case irInstr_DebugDeclare: { - /* irInstrDebugDeclare *dd = &instr->DebugDeclare; + irInstrDebugDeclare *dd = &instr->DebugDeclare; Type *vt = ir_type(dd->value); irDebugInfo *di = dd->debug_info; Entity *e = dd->entity; String name = e->token.string; TokenPos pos = e->token.pos; // gb_printf("debug_declare %.*s\n", LIT(dd->entity->token.string)); + ir_fprintf(f, "; "); ir_fprintf(f, "call void @llvm.dbg.declare("); ir_fprintf(f, "metadata "); ir_print_type(f, m, vt); ir_fprintf(f, " "); ir_print_value(f, m, dd->value, vt); ir_fprintf(f, ", metadata !DILocalVariable(name: \""); - ir_print_escape_string(f, name, false); + ir_print_escape_string(f, name, false, false); ir_fprintf(f, "\", scope: !%d, line: %td)", di->id, pos.line); ir_fprintf(f, ", metadata !DIExpression()"); ir_fprintf(f, ")"); ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, di->id); - ir_fprintf(f, "\n"); */ + ir_fprintf(f, "\n"); } break; } } diff --git a/src/parser.cpp b/src/parser.cpp index b7209058e..9ef0759ef 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2850,6 +2850,13 @@ AstNode *parse_unary_expr(AstFile *f, bool lhs) { Token close = expect_token(f, Token_CloseParen); return ast_type_cast(f, token, type, parse_unary_expr(f, lhs)); } break; + case Token_transmute: { + Token token = expect_token(f, Token_transmute); + Token open = expect_token_after(f, Token_OpenParen, "transmute"); + AstNode *type = parse_type(f); + Token close = expect_token(f, Token_CloseParen); + return ast_type_cast(f, token, type, parse_unary_expr(f, lhs)); + } break; } AstNode *operand = parse_operand(f, lhs); diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 68ecf6178..cd55edac5 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -114,6 +114,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_static, "static"), \ TOKEN_KIND(Token_dynamic, "dynamic"), \ TOKEN_KIND(Token_cast, "cast"), \ + TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_using, "using"), \ TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_push_context, "push_context"), \ diff --git a/src/types.cpp b/src/types.cpp index f738dd50f..86b673796 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2141,7 +2141,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) { t = base_type(t); - if (t->kind == Type_Struct && !t->Struct.is_raw_union) { + if (t->kind == Type_Struct) { type_set_offsets(allocator, t); if (gb_is_between(index, 0, t->Struct.fields.count-1)) { return t->Struct.offsets[index]; @@ -2155,7 +2155,7 @@ i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) { if (t->Basic.kind == Basic_string) { switch (index) { case 0: return 0; // data - case 1: return build_context.word_size; // count + case 1: return build_context.word_size; // len } } else if (t->Basic.kind == Basic_any) { switch (index) { @@ -2166,16 +2166,21 @@ i64 type_offset_of(gbAllocator allocator, Type *t, i32 index) { } else if (t->kind == Type_Slice) { switch (index) { case 0: return 0; // data - case 1: return 1*build_context.word_size; // count - case 2: return 2*build_context.word_size; // capacity + case 1: return 1*build_context.word_size; // len + case 2: return 2*build_context.word_size; // cap } } else if (t->kind == Type_DynamicArray) { switch (index) { case 0: return 0; // data - case 1: return 1*build_context.word_size; // count - case 2: return 2*build_context.word_size; // capacity + case 1: return 1*build_context.word_size; // len + case 2: return 2*build_context.word_size; // cap case 3: return 3*build_context.word_size; // allocator } + } else if (t->kind == Type_Union) { + i64 s = type_size_of(allocator, t); + switch (index) { + case -1: return align_formula(t->Union.variant_block_size, build_context.word_size); // __type_info + } } return 0; } |