42
42
//! taken to it, implementing them for Rust seems difficult.
43
43
44
44
use rustc:: ty:: { self , Ty } ;
45
- use rustc:: ty:: layout:: { self , Align , HasDataLayout , LayoutOf , Size , FullLayout } ;
45
+ use rustc:: ty:: layout:: { self , HasDataLayout , LayoutOf , Size , FullLayout } ;
46
46
47
47
use context:: CrateContext ;
48
48
use type_:: Type ;
@@ -72,11 +72,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
72
72
return ;
73
73
}
74
74
match * l. layout {
75
- layout:: NullablePointer { .. } |
76
- layout:: General { .. } |
77
- layout:: UntaggedUnion { .. } => { }
78
-
79
- layout:: Univariant ( ref variant) => {
75
+ layout:: Univariant ( _) => {
80
76
let is_enum = if let ty:: TyAdt ( def, _) = t. sty {
81
77
def. is_enum ( )
82
78
} else {
@@ -87,9 +83,11 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
87
83
} else {
88
84
l
89
85
} ;
90
- llty. set_struct_body ( & struct_llfields ( cx, variant_layout) , variant. packed )
91
- } ,
92
- _ => bug ! ( "This function cannot handle {} with layout {:#?}" , t, l)
86
+ llty. set_struct_body ( & struct_llfields ( cx, variant_layout) ,
87
+ variant_layout. is_packed ( ) )
88
+ }
89
+
90
+ _ => { }
93
91
}
94
92
}
95
93
@@ -102,81 +100,65 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
102
100
return cx. llvm_type_of ( value. to_ty ( cx. tcx ( ) ) ) ;
103
101
}
104
102
match * l. layout {
105
- layout:: Univariant ( ref variant ) => {
103
+ layout:: Univariant ( _ ) => {
106
104
match name {
107
105
None => {
108
- Type :: struct_ ( cx, & struct_llfields ( cx, l) , variant . packed )
106
+ Type :: struct_ ( cx, & struct_llfields ( cx, l) , l . is_packed ( ) )
109
107
}
110
108
Some ( name) => {
111
109
Type :: named_struct ( cx, name)
112
110
}
113
111
}
114
112
}
115
- layout:: UntaggedUnion ( ref un) => {
116
- // Use alignment-sized ints to fill all the union storage.
117
- let fill = union_fill ( cx, un. stride ( ) , un. align ) ;
118
- match name {
119
- None => {
120
- Type :: struct_ ( cx, & [ fill] , un. packed )
121
- }
122
- Some ( name) => {
123
- let mut llty = Type :: named_struct ( cx, name) ;
124
- llty. set_struct_body ( & [ fill] , un. packed ) ;
125
- llty
126
- }
127
- }
128
- }
129
- layout:: NullablePointer { size, align, .. } |
130
- layout:: General { size, align, .. } => {
131
- let fill = union_fill ( cx, size, align) ;
113
+ _ => {
114
+ let align = l. align ( cx) ;
115
+ let abi_align = align. abi ( ) ;
116
+ let elem_ty = if let Some ( ity) = layout:: Integer :: for_abi_align ( cx, align) {
117
+ Type :: from_integer ( cx, ity)
118
+ } else {
119
+ let vec_align = cx. data_layout ( ) . vector_align ( Size :: from_bytes ( abi_align) ) ;
120
+ assert_eq ! ( vec_align. abi( ) , abi_align) ;
121
+ Type :: vector ( & Type :: i32 ( cx) , abi_align / 4 )
122
+ } ;
123
+
124
+ let size = l. size ( cx) . bytes ( ) ;
125
+ assert_eq ! ( size % abi_align, 0 ) ;
126
+ let fill = Type :: array ( & elem_ty, size / abi_align) ;
132
127
match name {
133
128
None => {
134
- Type :: struct_ ( cx, & [ fill] , false )
129
+ Type :: struct_ ( cx, & [ fill] , l . is_packed ( ) )
135
130
}
136
131
Some ( name) => {
137
132
let mut llty = Type :: named_struct ( cx, name) ;
138
- llty. set_struct_body ( & [ fill] , false ) ;
133
+ llty. set_struct_body ( & [ fill] , l . is_packed ( ) ) ;
139
134
llty
140
135
}
141
136
}
142
137
}
143
- _ => bug ! ( "Unsupported type {} represented as {:#?}" , t, l)
144
138
}
145
139
}
146
140
147
- fn union_fill ( cx : & CrateContext , size : Size , align : Align ) -> Type {
148
- let abi_align = align. abi ( ) ;
149
- let elem_ty = if let Some ( ity) = layout:: Integer :: for_abi_align ( cx, align) {
150
- Type :: from_integer ( cx, ity)
151
- } else {
152
- let vec_align = cx. data_layout ( ) . vector_align ( Size :: from_bytes ( abi_align) ) ;
153
- assert_eq ! ( vec_align. abi( ) , abi_align) ;
154
- Type :: vector ( & Type :: i32 ( cx) , abi_align / 4 )
155
- } ;
156
-
157
- let size = size. bytes ( ) ;
158
- assert_eq ! ( size % abi_align, 0 ) ;
159
- Type :: array ( & elem_ty, size / abi_align)
160
- }
161
-
162
141
/// Double an index and add 1 to account for padding.
163
142
pub fn memory_index_to_gep ( index : u64 ) -> u64 {
164
143
1 + index * 2
165
144
}
166
145
167
146
pub fn struct_llfields < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
168
147
layout : FullLayout < ' tcx > ) -> Vec < Type > {
169
- let variant = match * layout. layout {
170
- layout:: Univariant ( ref variant) => variant,
171
- _ => bug ! ( "unexpected {:#?}" , layout)
172
- } ;
148
+ debug ! ( "struct_llfields: {:#?}" , layout) ;
149
+ let align = layout. align ( cx) ;
150
+ let size = layout. size ( cx) ;
173
151
let field_count = layout. fields . count ( ) ;
174
- debug ! ( "struct_llfields: variant: {:?}" , variant ) ;
152
+
175
153
let mut offset = Size :: from_bytes ( 0 ) ;
176
154
let mut result: Vec < Type > = Vec :: with_capacity ( 1 + field_count * 2 ) ;
177
- for i in variant. field_index_by_increasing_offset ( ) {
155
+ let field_index_by_increasing_offset = match * layout. layout {
156
+ layout:: Univariant ( ref variant) => variant. field_index_by_increasing_offset ( ) ,
157
+ _ => bug ! ( "unexpected {:#?}" , layout)
158
+ } ;
159
+ for i in field_index_by_increasing_offset {
178
160
let field = layout. field ( cx, i) ;
179
- let target_offset = variant . offsets [ i as usize ] ;
161
+ let target_offset = layout . fields . offset ( i as usize ) ;
180
162
debug ! ( "struct_llfields: {}: {:?} offset: {:?} target_offset: {:?}" ,
181
163
i, field, offset, target_offset) ;
182
164
assert ! ( target_offset >= offset) ;
@@ -187,30 +169,30 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
187
169
let llty = cx. llvm_type_of ( field. ty ) ;
188
170
result. push ( llty) ;
189
171
190
- if variant . packed {
172
+ if layout . is_packed ( ) {
191
173
assert_eq ! ( padding. bytes( ) , 0 ) ;
192
174
} else {
193
175
let field_align = field. align ( cx) ;
194
- assert ! ( field_align. abi( ) <= variant . align. abi( ) ,
176
+ assert ! ( field_align. abi( ) <= align. abi( ) ,
195
177
"non-packed type has field with larger align ({}): {:#?}" ,
196
- field_align. abi( ) , variant ) ;
178
+ field_align. abi( ) , layout ) ;
197
179
}
198
180
199
181
offset = target_offset + field. size ( cx) ;
200
182
}
201
- if variant . sized && field_count > 0 {
202
- if offset > variant . stride ( ) {
203
- bug ! ( "variant : {:?} stride: {:?} offset: {:?}" ,
204
- variant , variant . stride ( ) , offset) ;
183
+ if !layout . is_unsized ( ) && field_count > 0 {
184
+ if offset > size {
185
+ bug ! ( "layout : {:# ?} stride: {:?} offset: {:?}" ,
186
+ layout , size , offset) ;
205
187
}
206
- let padding = variant . stride ( ) - offset;
207
- debug ! ( "struct_llfields: pad_bytes: {:?} offset: {:?} min_size: {:?} stride: {:?}" ,
208
- padding, offset, variant . min_size , variant . stride ( ) ) ;
188
+ let padding = size - offset;
189
+ debug ! ( "struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}" ,
190
+ padding, offset, size ) ;
209
191
result. push ( Type :: array ( & Type :: i8 ( cx) , padding. bytes ( ) ) ) ;
210
192
assert ! ( result. len( ) == 1 + field_count * 2 ) ;
211
193
} else {
212
- debug ! ( "struct_llfields: offset: {:?} min_size: {:?} stride: {:?}" ,
213
- offset, variant . min_size , variant . stride ( ) ) ;
194
+ debug ! ( "struct_llfields: offset: {:?} stride: {:?}" ,
195
+ offset, size ) ;
214
196
}
215
197
216
198
result
0 commit comments