diff --git a/spec/compiler/crystal/tools/hierarchy_spec.cr b/spec/compiler/crystal/tools/hierarchy_spec.cr index 9e01acded7ec..ae1bcd2dbadb 100644 --- a/spec/compiler/crystal/tools/hierarchy_spec.cr +++ b/spec/compiler/crystal/tools/hierarchy_spec.cr @@ -21,6 +21,26 @@ describe Crystal::TextHierarchyPrinter do +- class Bar (4 bytes)\n EOS end + + it "shows correct size for Bool member" do + program = semantic(<<-CRYSTAL).program + struct Foo + @x = true + end + CRYSTAL + + output = String.build { |io| Crystal.print_hierarchy(program, io, "Foo", "text") } + output.should eq(<<-EOS) + - class Object (4 bytes) + | + +- struct Value (0 bytes) + | + +- struct Struct (0 bytes) + | + +- struct Foo (1 bytes) + @x : Bool (1 bytes)\n + EOS + end end describe Crystal::JSONHierarchyPrinter do diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index ae41939fca83..e036efbf48e8 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -92,9 +92,6 @@ module Crystal # `Pointer(Void).malloc` must work like `Pointer(UInt8).malloc`, # that is, consider Void like the size of a byte. 1 - elsif type.is_a?(BoolType) - # LLVM reports 0 for bool (i1) but it must be 1 because it does occupy memory - 1 else llvm_typer.size_of(llvm_typer.llvm_type(type)) end diff --git a/src/compiler/crystal/interpreter/compiler.cr b/src/compiler/crystal/interpreter/compiler.cr index 8f59b63ec667..eddc87d65132 100644 --- a/src/compiler/crystal/interpreter/compiler.cr +++ b/src/compiler/crystal/interpreter/compiler.cr @@ -2010,7 +2010,8 @@ class Crystal::Repl::Compiler < Crystal::Visitor args = node.args obj_type = obj.try(&.type) || target_def.owner - if obj_type == @context.program + # TODO: should this use `Type#passed_as_self?` instead? + if obj_type == @context.program || obj_type.is_a?(FileModule) # Nothing elsif obj_type.passed_by_value? args_bytesize += sizeof(Pointer(UInt8)) diff --git a/src/compiler/crystal/interpreter/local_vars.cr b/src/compiler/crystal/interpreter/local_vars.cr index d8637a7f2264..5111496dd3e0 100644 --- a/src/compiler/crystal/interpreter/local_vars.cr +++ b/src/compiler/crystal/interpreter/local_vars.cr @@ -80,7 +80,8 @@ class Crystal::Repl::LocalVars def declare(name : String, type : Type) : Int32? is_self = name == "self" - return if is_self && type.is_a?(Program) + # TODO: should this use `Type#passed_as_self?` instead? + return if is_self && (type.is_a?(Program) || type.is_a?(FileModule)) key = Key.new(name, @block_level) diff --git a/src/llvm/target_data.cr b/src/llvm/target_data.cr index ed8d0c07ed91..653c69d6b0b3 100644 --- a/src/llvm/target_data.cr +++ b/src/llvm/target_data.cr @@ -7,7 +7,8 @@ struct LLVM::TargetData end def size_in_bytes(type) - size_in_bits(type) // 8 + size_in_bits = size_in_bits(type) + size_in_bits // 8 &+ (size_in_bits & 0x7 != 0 ? 1 : 0) end def abi_size(type)