Skip to content

Commit

Permalink
Compiler: missing fix for abstract structs as virtual types. Fixes #2529
Browse files Browse the repository at this point in the history
Ary Borenszweig committed May 3, 2016

Verified

This commit was signed with the committer’s verified signature.
rasendubi Oleksii Shmalko
1 parent 9826714 commit 0887c93
Showing 2 changed files with 46 additions and 10 deletions.
32 changes: 32 additions & 0 deletions spec/compiler/codegen/struct_spec.cr
Original file line number Diff line number Diff line change
@@ -349,4 +349,36 @@ describe "Code gen: struct" do
foo.x
)).to_i.should eq(1)
end

it "codegens virtual struct with pointer" do
run(%(
abstract struct Foo
end
struct Bar < Foo
def initialize
@x = 1
end
def x
@x
end
end
struct Baz < Foo
def initialize
@x = 2
end
def x
@x
end
end
ptr = Pointer(Foo).malloc(1_u64)
ptr.value = Baz.new
ptr.value = Bar.new
ptr.value.x
)).to_i.should eq(1)
end
end
24 changes: 14 additions & 10 deletions src/compiler/crystal/codegen/llvm_typer.cr
Original file line number Diff line number Diff line change
@@ -127,7 +127,7 @@ module Crystal
LLVM::Type.struct(type.llvm_name) do |a_struct|
@cache[type] = a_struct

type.tuple_types.map { |tuple_type| llvm_embedded_type(tuple_type) }
type.tuple_types.map { |tuple_type| llvm_embedded_type(tuple_type) as LLVM::Type }
end
end

@@ -299,43 +299,47 @@ module Crystal
end
end

def llvm_embedded_type(type : CStructType)
def llvm_embedded_type(type)
llvm_embedded_type_impl(type.remove_indirection)
end

private def llvm_embedded_type_impl(type : CStructType)
llvm_struct_type type
end

def llvm_embedded_type(type : CUnionType)
private def llvm_embedded_type_impl(type : CUnionType)
llvm_struct_type type
end

def llvm_embedded_type(type : FunInstanceType)
private def llvm_embedded_type_impl(type : FunInstanceType)
llvm_type type
end

def llvm_embedded_type(type : PointerInstanceType)
private def llvm_embedded_type_impl(type : PointerInstanceType)
llvm_type type
end

def llvm_embedded_type(type : InstanceVarContainer)
private def llvm_embedded_type_impl(type : InstanceVarContainer)
if type.struct?
llvm_struct_type type
else
llvm_type type
end
end

def llvm_embedded_type(type : StaticArrayInstanceType)
private def llvm_embedded_type_impl(type : StaticArrayInstanceType)
llvm_type type
end

def llvm_embedded_type(type : NoReturnType)
private def llvm_embedded_type_impl(type : NoReturnType)
LLVM::Int8
end

def llvm_embedded_type(type : VoidType)
private def llvm_embedded_type_impl(type : VoidType)
LLVM::Int8
end

def llvm_embedded_type(type)
private def llvm_embedded_type_impl(type)
llvm_type type
end

0 comments on commit 0887c93

Please sign in to comment.