Skip to content

Commit f13d42f

Browse files
committed
Fixed rust-lang#97
1 parent f203922 commit f13d42f

File tree

5 files changed

+146
-110
lines changed

5 files changed

+146
-110
lines changed

src/attributes.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,28 @@ impl Attribute {
189189
}
190190
}
191191
}
192+
193+
/// An `AttributeLoc` determines where on a function an attribute is assigned to.
194+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
195+
pub enum AttributeLoc {
196+
/// Assign to the `FunctionValue`'s return type.
197+
Return,
198+
/// Assign to one of the `FunctionValue`'s params (0-indexed).
199+
Param(u32),
200+
/// Assign to the `FunctionValue` itself.
201+
Function,
202+
}
203+
204+
impl AttributeLoc {
205+
pub(crate) fn get_index(&self) -> u32 {
206+
match self {
207+
AttributeLoc::Return => 0,
208+
AttributeLoc::Param(index) => {
209+
assert!(*index <= u32::max_value() - 2, "Param index must be <= u32::max_value() - 2");
210+
211+
index + 1
212+
},
213+
AttributeLoc::Function => u32::max_value(),
214+
}
215+
}
216+
}

src/values/call_site_value.rs

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use llvm_sys::core::{LLVMIsTailCall, LLVMSetTailCall, LLVMGetTypeKind, LLVMTypeO
44
use llvm_sys::prelude::LLVMValueRef;
55

66
#[llvm_versions(3.9..=latest)]
7-
use crate::attributes::Attribute;
7+
use crate::attributes::{Attribute, AttributeLoc};
88
use crate::support::LLVMString;
99
use crate::values::{AsValueRef, BasicValueEnum, InstructionValue, Value};
1010
#[llvm_versions(3.9..=latest)]
@@ -112,6 +112,7 @@ impl CallSiteValue {
112112
/// # Example
113113
///
114114
/// ```no_run
115+
/// use inkwell::attributes::AttributeLoc;
115116
/// use inkwell::context::Context;
116117
///
117118
/// let context = Context::create();
@@ -128,15 +129,15 @@ impl CallSiteValue {
128129
///
129130
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
130131
///
131-
/// call_site_value.add_attribute(0, string_attribute);
132-
/// call_site_value.add_attribute(0, enum_attribute);
132+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
133+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
133134
/// ```
134135
#[llvm_versions(3.9..=latest)]
135-
pub fn add_attribute(&self, index: u32, attribute: Attribute) {
136+
pub fn add_attribute(&self, loc: AttributeLoc, attribute: Attribute) {
136137
use llvm_sys::core::LLVMAddCallSiteAttribute;
137138

138139
unsafe {
139-
LLVMAddCallSiteAttribute(self.as_value_ref(), index, attribute.attribute)
140+
LLVMAddCallSiteAttribute(self.as_value_ref(), loc.get_index(), attribute.attribute)
140141
}
141142
}
142143

@@ -179,6 +180,7 @@ impl CallSiteValue {
179180
/// # Example
180181
///
181182
/// ```no_run
183+
/// use inkwell::attributes::AttributeLoc;
182184
/// use inkwell::context::Context;
183185
///
184186
/// let context = Context::create();
@@ -195,17 +197,17 @@ impl CallSiteValue {
195197
///
196198
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
197199
///
198-
/// call_site_value.add_attribute(0, string_attribute);
199-
/// call_site_value.add_attribute(0, enum_attribute);
200+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
201+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
200202
///
201-
/// assert_eq!(call_site_value.count_attributes(0), 2);
203+
/// assert_eq!(call_site_value.count_attributes(AttributeLoc::Return), 2);
202204
/// ```
203205
#[llvm_versions(3.9..=latest)]
204-
pub fn count_attributes(&self, index: u32) -> u32 {
206+
pub fn count_attributes(&self, loc: AttributeLoc) -> u32 {
205207
use llvm_sys::core::LLVMGetCallSiteAttributeCount;
206208

207209
unsafe {
208-
LLVMGetCallSiteAttributeCount(self.as_value_ref(), index)
210+
LLVMGetCallSiteAttributeCount(self.as_value_ref(), loc.get_index())
209211
}
210212
}
211213

@@ -214,6 +216,7 @@ impl CallSiteValue {
214216
/// # Example
215217
///
216218
/// ```no_run
219+
/// use inkwell::attributes::AttributeLoc;
217220
/// use inkwell::context::Context;
218221
///
219222
/// let context = Context::create();
@@ -230,18 +233,18 @@ impl CallSiteValue {
230233
///
231234
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
232235
///
233-
/// call_site_value.add_attribute(0, string_attribute);
234-
/// call_site_value.add_attribute(0, enum_attribute);
236+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
237+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
235238
///
236-
/// assert_eq!(call_site_value.get_enum_attribute(0, 1).unwrap(), enum_attribute);
239+
/// assert_eq!(call_site_value.get_enum_attribute(AttributeLoc::Return, 1).unwrap(), enum_attribute);
237240
/// ```
238241
// SubTypes: -> Attribute<Enum>
239242
#[llvm_versions(3.9..=latest)]
240-
pub fn get_enum_attribute(&self, index: u32, kind_id: u32) -> Option<Attribute> {
243+
pub fn get_enum_attribute(&self, loc: AttributeLoc, kind_id: u32) -> Option<Attribute> {
241244
use llvm_sys::core::LLVMGetCallSiteEnumAttribute;
242245

243246
let ptr = unsafe {
244-
LLVMGetCallSiteEnumAttribute(self.as_value_ref(), index, kind_id)
247+
LLVMGetCallSiteEnumAttribute(self.as_value_ref(), loc.get_index(), kind_id)
245248
};
246249

247250
if ptr.is_null() {
@@ -256,6 +259,7 @@ impl CallSiteValue {
256259
/// # Example
257260
///
258261
/// ```no_run
262+
/// use inkwell::attributes::AttributeLoc;
259263
/// use inkwell::context::Context;
260264
///
261265
/// let context = Context::create();
@@ -272,18 +276,18 @@ impl CallSiteValue {
272276
///
273277
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
274278
///
275-
/// call_site_value.add_attribute(0, string_attribute);
276-
/// call_site_value.add_attribute(0, enum_attribute);
279+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
280+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
277281
///
278-
/// assert_eq!(call_site_value.get_string_attribute(0, "my_key").unwrap(), string_attribute);
282+
/// assert_eq!(call_site_value.get_string_attribute(AttributeLoc::Return, "my_key").unwrap(), string_attribute);
279283
/// ```
280284
// SubTypes: -> Attribute<String>
281285
#[llvm_versions(3.9..=latest)]
282-
pub fn get_string_attribute(&self, index: u32, key: &str) -> Option<Attribute> {
286+
pub fn get_string_attribute(&self, loc: AttributeLoc, key: &str) -> Option<Attribute> {
283287
use llvm_sys::core::LLVMGetCallSiteStringAttribute;
284288

285289
let ptr = unsafe {
286-
LLVMGetCallSiteStringAttribute(self.as_value_ref(), index, key.as_ptr() as *const i8, key.len() as u32)
290+
LLVMGetCallSiteStringAttribute(self.as_value_ref(), loc.get_index(), key.as_ptr() as *const i8, key.len() as u32)
287291
};
288292

289293
if ptr.is_null() {
@@ -298,6 +302,7 @@ impl CallSiteValue {
298302
/// # Example
299303
///
300304
/// ```no_run
305+
/// use inkwell::attributes::AttributeLoc;
301306
/// use inkwell::context::Context;
302307
///
303308
/// let context = Context::create();
@@ -314,18 +319,18 @@ impl CallSiteValue {
314319
///
315320
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
316321
///
317-
/// call_site_value.add_attribute(0, string_attribute);
318-
/// call_site_value.add_attribute(0, enum_attribute);
319-
/// call_site_value.remove_enum_attribute(0, 1);
322+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
323+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
324+
/// call_site_value.remove_enum_attribute(AttributeLoc::Return, 1);
320325
///
321-
/// assert_eq!(call_site_value.get_enum_attribute(0, 1), None);
326+
/// assert_eq!(call_site_value.get_enum_attribute(AttributeLoc::Return, 1), None);
322327
/// ```
323328
#[llvm_versions(3.9..=latest)]
324-
pub fn remove_enum_attribute(&self, index: u32, kind_id: u32) {
329+
pub fn remove_enum_attribute(&self, loc: AttributeLoc, kind_id: u32) {
325330
use llvm_sys::core::LLVMRemoveCallSiteEnumAttribute;
326331

327332
unsafe {
328-
LLVMRemoveCallSiteEnumAttribute(self.as_value_ref(), index, kind_id)
333+
LLVMRemoveCallSiteEnumAttribute(self.as_value_ref(), loc.get_index(), kind_id)
329334
}
330335
}
331336

@@ -334,6 +339,7 @@ impl CallSiteValue {
334339
/// # Example
335340
///
336341
/// ```no_run
342+
/// use inkwell::attributes::AttributeLoc;
337343
/// use inkwell::context::Context;
338344
///
339345
/// let context = Context::create();
@@ -350,18 +356,18 @@ impl CallSiteValue {
350356
///
351357
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
352358
///
353-
/// call_site_value.add_attribute(0, string_attribute);
354-
/// call_site_value.add_attribute(0, enum_attribute);
355-
/// call_site_value.remove_string_attribute(0, "my_key");
359+
/// call_site_value.add_attribute(AttributeLoc::Return, string_attribute);
360+
/// call_site_value.add_attribute(AttributeLoc::Return, enum_attribute);
361+
/// call_site_value.remove_string_attribute(AttributeLoc::Return, "my_key");
356362
///
357-
/// assert_eq!(call_site_value.get_string_attribute(0, "my_key"), None);
363+
/// assert_eq!(call_site_value.get_string_attribute(AttributeLoc::Return, "my_key"), None);
358364
/// ```
359365
#[llvm_versions(3.9..=latest)]
360-
pub fn remove_string_attribute(&self, index: u32, key: &str) {
366+
pub fn remove_string_attribute(&self, loc: AttributeLoc, key: &str) {
361367
use llvm_sys::core::LLVMRemoveCallSiteStringAttribute;
362368

363369
unsafe {
364-
LLVMRemoveCallSiteStringAttribute(self.as_value_ref(), index, key.as_ptr() as *const i8, key.len() as u32)
370+
LLVMRemoveCallSiteStringAttribute(self.as_value_ref(), loc.get_index(), key.as_ptr() as *const i8, key.len() as u32)
365371
}
366372
}
367373

@@ -370,6 +376,7 @@ impl CallSiteValue {
370376
/// # Example
371377
///
372378
/// ```no_run
379+
/// use inkwell::attributes::AttributeLoc;
373380
/// use inkwell::context::Context;
374381
///
375382
/// let context = Context::create();
@@ -462,6 +469,7 @@ impl CallSiteValue {
462469
/// # Example
463470
///
464471
/// ```no_run
472+
/// use inkwell::attributes::AttributeLoc;
465473
/// use inkwell::context::Context;
466474
///
467475
/// let context = Context::create();
@@ -476,13 +484,13 @@ impl CallSiteValue {
476484
///
477485
/// let call_site_value = builder.build_call(fn_value, &[], "my_fn");
478486
///
479-
/// call_site_value.set_param_alignment_attribute(0, 2);
487+
/// call_site_value.set_alignment_attribute(AttributeLoc::Param(0), 2);
480488
/// ```
481-
pub fn set_param_alignment_attribute(&self, index: u32, alignment: u32) {
489+
pub fn set_alignment_attribute(&self, loc: AttributeLoc, alignment: u32) {
482490
assert_eq!(alignment.count_ones(), 1, "Alignment must be a power of two.");
483491

484492
unsafe {
485-
LLVMSetInstrParamAlignment(self.as_value_ref(), index, alignment)
493+
LLVMSetInstrParamAlignment(self.as_value_ref(), loc.get_index(), alignment)
486494
}
487495
}
488496

0 commit comments

Comments
 (0)