33
33
extern crate libc;
34
34
#[ macro_use] #[ no_link] extern crate rustc_bitflags;
35
35
36
- pub use self :: OtherAttribute :: * ;
37
- pub use self :: SpecialAttribute :: * ;
38
36
pub use self :: AttributeSet :: * ;
39
37
pub use self :: IntPredicate :: * ;
40
38
pub use self :: RealPredicate :: * ;
@@ -133,7 +131,7 @@ pub enum DLLStorageClassTypes {
133
131
}
134
132
135
133
bitflags ! {
136
- #[ derive( Debug ) ]
134
+ #[ derive( Default , Debug ) ]
137
135
flags Attribute : u64 {
138
136
const ZExt = 1 << 0 ,
139
137
const SExt = 1 << 1 ,
@@ -165,79 +163,85 @@ bitflags! {
165
163
// FIXME: These attributes are currently not included in the C API as
166
164
// a temporary measure until the API/ABI impact to the C API is understood
167
165
// and the path forward agreed upon.
168
- const SanitizeAddress = 1 << 32 ;
169
- const MinSize = 1 << 33 ;
170
- const NoDuplicate = 1 << 34 ;
171
- const StackProtectStrong = 1 << 35 ;
172
- const SanitizeThread = 1 << 36 ;
173
- const SanitizeMemory = 1 << 37 ;
174
- const NoBuiltin = 1 << 38 ;
175
- const Returned = 1 << 39 ;
176
- const Cold = 1 << 40 ;
177
- const Builtin = 1 << 41 ;
178
- const OptimizeNone = 1 << 42 ;
179
- const InAlloca = 1 << 43 ;
180
- const NonNull = 1 << 44 ;
181
- const JumpTable = 1 << 45 ;
182
- const Convergent = 1 << 46 ;
183
- const SafeStack = 1 << 47 ;
184
- const NoRecurse = 1 << 48 ;
185
- const InaccessibleMemOnly = 1 << 49 ;
186
- const InaccessibleMemOrArgMemOnly = 1 << 50 ;
166
+ const SanitizeAddress = 1 << 32 ,
167
+ const MinSize = 1 << 33 ,
168
+ const NoDuplicate = 1 << 34 ,
169
+ const StackProtectStrong = 1 << 35 ,
170
+ const SanitizeThread = 1 << 36 ,
171
+ const SanitizeMemory = 1 << 37 ,
172
+ const NoBuiltin = 1 << 38 ,
173
+ const Returned = 1 << 39 ,
174
+ const Cold = 1 << 40 ,
175
+ const Builtin = 1 << 41 ,
176
+ const OptimizeNone = 1 << 42 ,
177
+ const InAlloca = 1 << 43 ,
178
+ const NonNull = 1 << 44 ,
179
+ const JumpTable = 1 << 45 ,
180
+ const Convergent = 1 << 46 ,
181
+ const SafeStack = 1 << 47 ,
182
+ const NoRecurse = 1 << 48 ,
183
+ const InaccessibleMemOnly = 1 << 49 ,
184
+ const InaccessibleMemOrArgMemOnly = 1 << 50 ,
187
185
}
188
186
}
189
187
190
- #[ derive( Copy , Clone ) ]
191
- pub enum SpecialAttribute {
192
- DereferenceableAttribute ( u64 )
188
+ #[ derive( Copy , Clone , Default ) ]
189
+ pub struct Attributes {
190
+ regular : Attribute ,
191
+ dereferenceable_bytes : u64
193
192
}
194
193
195
- #[ repr( C ) ]
196
- #[ derive( Copy , Clone ) ]
197
- pub enum AttributeSet {
198
- ReturnIndex = 0 ,
199
- FunctionIndex = !0
200
- }
194
+ impl Attributes {
195
+ pub fn set ( & mut self , attr : Attribute ) -> & mut Self {
196
+ self . regular = self . regular | attr;
197
+ self
198
+ }
201
199
202
- pub trait AttrHelper {
203
- fn apply_llfn ( & self , idx : c_uint , llfn : ValueRef ) ;
204
- fn apply_callsite ( & self , idx : c_uint , callsite : ValueRef ) ;
205
- }
200
+ pub fn unset ( & mut self , attr : Attribute ) -> & mut Self {
201
+ self . regular = self . regular - attr ;
202
+ self
203
+ }
206
204
207
- impl AttrHelper for Attribute {
208
- fn apply_llfn ( & self , idx : c_uint , llfn : ValueRef ) {
209
- unsafe {
210
- LLVMAddFunctionAttribute ( llfn, idx, self . bits ( ) as uint64_t ) ;
211
- }
205
+ pub fn set_dereferenceable ( & mut self , bytes : u64 ) -> & mut Self {
206
+ self . dereferenceable_bytes = bytes;
207
+ self
212
208
}
213
209
214
- fn apply_callsite ( & self , idx : c_uint , callsite : ValueRef ) {
215
- unsafe {
216
- LLVMAddCallSiteAttribute ( callsite, idx, self . bits ( ) as uint64_t ) ;
217
- }
210
+ pub fn unset_dereferenceable ( & mut self ) -> & mut Self {
211
+ self . dereferenceable_bytes = 0 ;
212
+ self
218
213
}
219
- }
220
214
221
- impl AttrHelper for SpecialAttribute {
222
- fn apply_llfn ( & self , idx : c_uint , llfn : ValueRef ) {
223
- match * self {
224
- DereferenceableAttribute ( bytes) => unsafe {
225
- LLVMAddDereferenceableAttr ( llfn, idx, bytes as uint64_t ) ;
215
+ pub fn apply_llfn ( & self , idx : c_uint , llfn : ValueRef ) {
216
+ unsafe {
217
+ LLVMAddFunctionAttribute ( llfn, idx, self . regular . bits ( ) ) ;
218
+ if self . dereferenceable_bytes != 0 {
219
+ LLVMAddDereferenceableAttr ( llfn, idx,
220
+ self . dereferenceable_bytes ) ;
226
221
}
227
222
}
228
223
}
229
224
230
- fn apply_callsite ( & self , idx : c_uint , callsite : ValueRef ) {
231
- match * self {
232
- DereferenceableAttribute ( bytes) => unsafe {
233
- LLVMAddDereferenceableCallSiteAttr ( callsite, idx, bytes as uint64_t ) ;
225
+ pub fn apply_callsite ( & self , idx : c_uint , callsite : ValueRef ) {
226
+ unsafe {
227
+ LLVMAddCallSiteAttribute ( callsite, idx, self . regular . bits ( ) ) ;
228
+ if self . dereferenceable_bytes != 0 {
229
+ LLVMAddDereferenceableCallSiteAttr ( callsite, idx,
230
+ self . dereferenceable_bytes ) ;
234
231
}
235
232
}
236
233
}
237
234
}
238
235
236
+ #[ repr( C ) ]
237
+ #[ derive( Copy , Clone ) ]
238
+ pub enum AttributeSet {
239
+ ReturnIndex = 0 ,
240
+ FunctionIndex = !0
241
+ }
242
+
239
243
pub struct AttrBuilder {
240
- attrs : Vec < ( usize , Box < AttrHelper + ' static > ) >
244
+ attrs : Vec < ( usize , Attributes ) >
241
245
}
242
246
243
247
impl AttrBuilder {
@@ -247,14 +251,23 @@ impl AttrBuilder {
247
251
}
248
252
}
249
253
250
- pub fn arg < T : AttrHelper + ' static > ( & mut self , idx : usize , a : T ) -> & mut AttrBuilder {
251
- self . attrs . push ( ( idx, box a as Box < AttrHelper +' static > ) ) ;
252
- self
254
+ pub fn arg ( & mut self , idx : usize ) -> & mut Attributes {
255
+ let mut found = None ;
256
+ for ( i, & ( idx2, _) ) in self . attrs . iter ( ) . enumerate ( ) {
257
+ if idx == idx2 {
258
+ found = Some ( i) ;
259
+ break ;
260
+ }
261
+ }
262
+ let i = found. unwrap_or_else ( || {
263
+ self . attrs . push ( ( idx, Attributes :: default ( ) ) ) ;
264
+ self . attrs . len ( ) - 1
265
+ } ) ;
266
+ & mut self . attrs [ i] . 1
253
267
}
254
268
255
- pub fn ret < T : AttrHelper + ' static > ( & mut self , a : T ) -> & mut AttrBuilder {
256
- self . attrs . push ( ( ReturnIndex as usize , box a as Box < AttrHelper +' static > ) ) ;
257
- self
269
+ pub fn ret ( & mut self ) -> & mut Attributes {
270
+ self . arg ( ReturnIndex as usize )
258
271
}
259
272
260
273
pub fn apply_llfn ( & self , llfn : ValueRef ) {
0 commit comments