diff --git a/base.cpp b/base.cpp index 0166a2d..bfd845a 100644 --- a/base.cpp +++ b/base.cpp @@ -21,6 +21,7 @@ typedef S64 SizeS; typedef float F32; typedef double F64; + #define U64MAX UINT64_MAX #define U32MAX UINT32_MAX #define U16MAX UINT16_MAX diff --git a/core_typechecking.cpp b/core_typechecking.cpp index a6eb8bb..c8e1f5c 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1234,6 +1234,11 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ } Ast_Type *type = name.type == type_type ? name.type_val : name.type; + type_complete(type); + if(type->size == 0){ + compiler_error(node->pos, "Internal compiler error: calling SizeOf but the resulting size of type is obviously invalid suggesting that type was not completed properly"); + } + Value v = value_int(type->size); rewrite_into_const(node, Ast_Builtin, v); return operand_const_rvalue(v); @@ -1265,8 +1270,16 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL)); node->kind = AST_ALIGN_OF; - if(!name.is_const) compiler_error(node->pos, "AlignOf requires a constant value"); + if(!name.is_const) { + compiler_error(node->pos, "AlignOf requires a constant value"); + } + Ast_Type *type = name.type == type_type ? name.type_val : name.type; + type_complete(type); + if(type->size == 0){ + compiler_error(node->pos, "Internal compiler error: calling SizeOf but the resulting size of type is obviously invalid suggesting that type was not completed properly"); + } + Value v = value_int(type->align); rewrite_into_const(node, Ast_Builtin, v); return operand_const_rvalue(v); diff --git a/core_typechecking.h b/core_typechecking.h index 19d54ce..81a470b 100644 --- a/core_typechecking.h +++ b/core_typechecking.h @@ -261,21 +261,33 @@ type_incomplete(Ast *ast){ return result; } +function void type_complete(Ast_Type *type); function void type_struct_complete(Ast_Type *type, Ast_Decl *node){ assert(node->kind == AST_STRUCT); // @todo: compute size, alignement, offset !!! // @note: resolve all the struct members first - type->kind = TYPE_COMPLETING; Scratch scratch; Array members = {scratch}; + type->kind = TYPE_COMPLETING; + size_t members_size = 0; For(node->scope->decls){ resolve_decl(it); + assert(it->type->kind != TYPE_INCOMPLETE); + assert(is_pow2(it->type->align)); + Ast_Resolved_Member m = {}; + m.offset = type->size; + members_size += it->type->size; + type->align = max(type->align, it->type->align); + type->size = it->type->size + align_up(type->size, it->type->align); + m.name = it->name; m.value = it->value; members.add(m); } + type->size = align_up(type->size, type->align); + type->padding = type->size - members_size; type->agg.members = members.tight_copy(pctx->perm); type->kind = TYPE_STRUCT; } diff --git a/core_types.h b/core_types.h index d3107c1..679f09f 100644 --- a/core_types.h +++ b/core_types.h @@ -63,6 +63,7 @@ union{ \ Ast_Type *type_val; \ }; #define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};} +#define ARRAY_SIZE_SLICE (-1) struct Value{VALUE_FIELDS}; struct Ast; @@ -74,13 +75,13 @@ struct Ast_Resolved_Member{ INLINE_VALUE_FIELDS; }; -#define ARRAY_SIZE_SLICE (-1) struct Ast_Type{ Ast_Type_Kind kind; S32 size; S32 align; S32 is_unsigned; S32 type_id; + S32 padding; Ast *ast; union{ @@ -137,7 +138,7 @@ const SizeU pointer_align = __alignof(SizeU); global Ast_Type type__void = {TYPE_VOID}; global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; -global Ast_Type type__type = {TYPE_TYPE}; +global Ast_Type type__type = {TYPE_TYPE, sizeof(U32), __alignof(U32)}; global Ast_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)}; global Ast_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)}; diff --git a/examples/drawing_to_screen_using_windows_api.kl b/examples/drawing_to_screen_using_windows_api.kl index 42b9999..302d57a 100644 --- a/examples/drawing_to_screen_using_windows_api.kl +++ b/examples/drawing_to_screen_using_windows_api.kl @@ -24,9 +24,11 @@ CreateBitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap if bottom_up == false result.size.y = -result.size.y + header_size: U32 = SizeOf(BITMAPINFOHEADER) + Assert(header_size == 40) bminfo := BITMAPINFO{ BITMAPINFOHEADER{ - biSize = 40, // @todo!!! SizeOf(BITMAPINFOHEADER), + biSize = header_size, biWidth = size.x->LONG, biHeight = size.y->LONG, biPlanes = 1,