File tree 3 files changed +40
-6
lines changed
spec/compiler/codegen/c_abi
3 files changed +40
-6
lines changed Original file line number Diff line number Diff line change @@ -85,6 +85,30 @@ require "../../../spec_helper"
85
85
str.should contain(" declare void @foo({ i64, i64 })" )
86
86
end
87
87
88
+ it " passes struct between 64 and 128 bits as { i64, i64 } (with multiple modules/contexts)" do
89
+ codegen(%(
90
+ require "prelude"
91
+
92
+ lib LibFoo
93
+ struct Struct
94
+ x : Int64
95
+ y : Int16
96
+ end
97
+
98
+ fun foo(s : Struct)
99
+ end
100
+
101
+ module Moo
102
+ def self.moo
103
+ s = LibFoo::Struct.new
104
+ LibFoo.foo(s)
105
+ end
106
+ end
107
+
108
+ Moo.moo
109
+ ) )
110
+ end
111
+
88
112
it " passes struct between 64 and 128 bits (for real)" do
89
113
test_c(
90
114
%(
Original file line number Diff line number Diff line change @@ -523,11 +523,17 @@ module Crystal
523
523
LLVM ::Type .function(params_types, ret_type, type .varargs?)
524
524
when .struct?
525
525
llvm_name = type .struct_name
526
- @structs [llvm_name] ||= begin
527
- @llvm_context .struct(llvm_name, type .packed_struct?) do |the_struct |
528
- @structs [llvm_name] = the_struct
529
- copy_types(type .struct_element_types)
526
+ if llvm_name
527
+ @structs [llvm_name] ||= begin
528
+ @llvm_context .struct(llvm_name, type .packed_struct?) do |the_struct |
529
+ @structs [llvm_name] = the_struct
530
+ copy_types(type .struct_element_types)
531
+ end
530
532
end
533
+ else
534
+ # The case of an anonymous struct (only happens with C bindings and C ABI,
535
+ # where structs like `{ double, double }` are generated)
536
+ @llvm_context .struct(copy_types(type .struct_element_types), packed: type .packed_struct?)
531
537
end
532
538
else
533
539
raise " don't know how to copy type: #{ type } (#{ type .kind} )"
Original file line number Diff line number Diff line change @@ -63,10 +63,14 @@ struct LLVM::Type
63
63
LibLLVM .is_packed_struct(self ) != 0
64
64
end
65
65
66
- def struct_name
66
+ # Assuming this type is a struct, returns its name.
67
+ # The name can be `nil` if the struct is anynomous.
68
+ # Raises if this type is not a struct.
69
+ def struct_name : String ?
67
70
raise " not a Struct" unless kind == Kind ::Struct
68
71
69
- String .new(LibLLVM .get_struct_name(self ))
72
+ name = LibLLVM .get_struct_name(self )
73
+ name ? String .new(name) : nil
70
74
end
71
75
72
76
def struct_element_types
You can’t perform that action at this time.
0 commit comments