From d3c24d159fbb380393ff6ce9261be734646cb5c4 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 15 Jun 2017 12:25:53 +0100 Subject: [PATCH] Merge size_of and size_of_val et al. --- src/check_expr.cpp | 139 +++++++++++---------------------------------- src/checker.cpp | 12 +--- src/ir.cpp | 4 -- 3 files changed, 35 insertions(+), 120 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 33eb88284..8fdec8e53 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3945,54 +3945,43 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id case BuiltinProc_size_of: { - // proc size_of(Type) -> untyped int - Type *type = check_type(c, ce->args[0]); - if (type == NULL || type == t_invalid) { - error_node(ce->args[0], "Expected a type for `size_of`"); + // proc size_of(Type or expr) -> untyped int + Operand o = {}; + check_expr_or_type(c, &o, ce->args[0]); + if (o.mode == Addressing_Invalid) { return false; } + Type *t = o.type; + if (t == NULL || t == t_invalid) { + error_node(ce->args[0], "Invalid argument for `size_of`"); + return false; + } + t = default_type(t); operand->mode = Addressing_Constant; - operand->value = exact_value_i64(type_size_of(c->allocator, type)); + operand->value = exact_value_i64(type_size_of(c->allocator, t)); operand->type = t_untyped_integer; - } break; - case BuiltinProc_size_of_val: - // proc size_of_val(val: Type) -> untyped int - check_assignment(c, operand, NULL, str_lit("argument of `size_of_val`")); - if (operand->mode == Addressing_Invalid) { - return false; - } - - operand->mode = Addressing_Constant; - operand->value = exact_value_i64(type_size_of(c->allocator, operand->type)); - operand->type = t_untyped_integer; - break; - case BuiltinProc_align_of: { - // proc align_of(Type) -> untyped int - Type *type = check_type(c, ce->args[0]); - if (type == NULL || type == t_invalid) { - error_node(ce->args[0], "Expected a type for `align_of`"); + // proc align_of(Type or expr) -> untyped int + Operand o = {}; + check_expr_or_type(c, &o, ce->args[0]); + if (o.mode == Addressing_Invalid) { return false; } + Type *t = o.type; + if (t == NULL || t == t_invalid) { + error_node(ce->args[0], "Invalid argument for `align_of`"); + return false; + } + t = default_type(t); + operand->mode = Addressing_Constant; - operand->value = exact_value_i64(type_align_of(c->allocator, type)); + operand->value = exact_value_i64(type_align_of(c->allocator, t)); operand->type = t_untyped_integer; } break; - case BuiltinProc_align_of_val: - // proc align_of_val(val: Type) -> untyped int - check_assignment(c, operand, NULL, str_lit("argument of `align_of_val`")); - if (operand->mode == Addressing_Invalid) { - return false; - } - - operand->mode = Addressing_Constant; - operand->value = exact_value_i64(type_align_of(c->allocator, operand->type)); - operand->type = t_untyped_integer; - break; case BuiltinProc_offset_of: { // proc offset_of(Type, field) -> untyped int @@ -4038,56 +4027,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id operand->type = t_untyped_integer; } break; - case BuiltinProc_offset_of_val: { - // proc offset_of_val(val: expression) -> untyped int - AstNode *arg = unparen_expr(ce->args[0]); - if (arg->kind != AstNode_SelectorExpr) { - gbString str = expr_to_string(arg); - error_node(arg, "`%s` is not a selector expression", str); - return false; - } - ast_node(s, SelectorExpr, arg); - check_expr(c, operand, s->expr); - if (operand->mode == Addressing_Invalid) { - return false; - } - - Type *type = operand->type; - if (base_type(type)->kind == Type_Pointer) { - Type *p = base_type(type); - if (is_type_struct(p)) { - type = p->Pointer.elem; - } - } - if (is_type_array(type) || is_type_vector(type)) { - error_node(arg, "Invalid type for `offset_of_val`"); - return false; - } - - ast_node(i, Ident, s->selector); - Selection sel = lookup_field(c->allocator, type, i->string, operand->mode == Addressing_Type); - if (sel.entity == NULL) { - gbString type_str = type_to_string(type); - error_node(arg, - "`%s` has no field named `%.*s`", type_str, LIT(i->string)); - return false; - } - if (sel.indirect) { - gbString type_str = type_to_string(type); - error_node(ce->args[0], - "Field `%.*s` is embedded via a pointer in `%s`", LIT(i->string), type_str); - gb_string_free(type_str); - return false; - } - - operand->mode = Addressing_Constant; - // IMPORTANT TODO(bill): Fix for anonymous fields - operand->value = exact_value_i64(type_offset_of_from_selection(c->allocator, type, sel)); - operand->type = t_untyped_integer; - } break; - - case BuiltinProc_type_of_val: + case BuiltinProc_type_of: // proc type_of_val(val: Type) -> type(Type) check_assignment(c, operand, NULL, str_lit("argument of `type_of_val`")); if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) { @@ -4110,31 +4051,19 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id // NOTE(bill): The type information may not be setup yet init_preload(c); AstNode *expr = ce->args[0]; - Type *type = check_type(c, expr); - if (type == NULL || type == t_invalid) { - error_node(expr, "Invalid argument to `type_info`"); + Operand o = {}; + check_expr_or_type(c, &o, ce->args[0]); + if (o.mode == Addressing_Invalid) { return false; } - - add_type_info_type(c, type); - - operand->mode = Addressing_Value; - operand->type = t_type_info_ptr; - } break; - - case BuiltinProc_type_info_of_val: { - // proc type_info_of_val(val: Type) -> ^Type_Info - if (c->context.scope->is_global) { - compiler_error("`type_info` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works"); - } - - // NOTE(bill): The type information may not be setup yet - init_preload(c); - AstNode *expr = ce->args[0]; - check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`")); - if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) + Type *t = o.type; + if (t == NULL || t == t_invalid) { + error_node(ce->args[0], "Invalid argument for `size_of`"); return false; - add_type_info_type(c, operand->type); + } + t = default_type(t); + + add_type_info_type(c, t); operand->mode = Addressing_Value; operand->type = t_type_info_ptr; diff --git a/src/checker.cpp b/src/checker.cpp index 82e68e483..53d9c77aa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -37,15 +37,10 @@ enum BuiltinProcId { BuiltinProc_delete, BuiltinProc_size_of, - BuiltinProc_size_of_val, BuiltinProc_align_of, - BuiltinProc_align_of_val, BuiltinProc_offset_of, - BuiltinProc_offset_of_val, - BuiltinProc_type_of_val, - + BuiltinProc_type_of, BuiltinProc_type_info, - BuiltinProc_type_info_of_val, BuiltinProc_compile_assert, BuiltinProc_assert, @@ -88,15 +83,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT("delete"), 2, false, Expr_Stmt}, {STR_LIT("size_of"), 1, false, Expr_Expr}, - {STR_LIT("size_of_val"), 1, false, Expr_Expr}, {STR_LIT("align_of"), 1, false, Expr_Expr}, - {STR_LIT("align_of_val"), 1, false, Expr_Expr}, {STR_LIT("offset_of"), 2, false, Expr_Expr}, - {STR_LIT("offset_of_val"), 1, false, Expr_Expr}, {STR_LIT("type_of_val"), 1, false, Expr_Expr}, - {STR_LIT("type_info"), 1, false, Expr_Expr}, - {STR_LIT("type_info_of_val"), 1, false, Expr_Expr}, {STR_LIT("compile_assert"), 1, false, Expr_Expr}, {STR_LIT("assert"), 1, false, Expr_Expr}, diff --git a/src/ir.cpp b/src/ir.cpp index 5daa42ad8..a14da8288 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3622,10 +3622,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv Type *t = default_type(type_of_expr(proc->module->info, ce->args[0])); return ir_type_info(proc, t); } break; - case BuiltinProc_type_info_of_val: { - Type *t = default_type(type_of_expr(proc->module->info, ce->args[0])); - return ir_type_info(proc, t); - } break; case BuiltinProc_transmute: { irValue *x = ir_build_expr(proc, ce->args[1]);