diff --git a/gccjit_sys/src/lib.rs b/gccjit_sys/src/lib.rs index 5d82778..9302600 100644 --- a/gccjit_sys/src/lib.rs +++ b/gccjit_sys/src/lib.rs @@ -270,6 +270,7 @@ pub enum gcc_jit_fn_attribute GCC_JIT_FN_ATTRIBUTE_PURE, GCC_JIT_FN_ATTRIBUTE_CONST, GCC_JIT_FN_ATTRIBUTE_WEAK, + GCC_JIT_FN_ATTRIBUTE_NONNULL, } #[cfg(feature="master")] @@ -619,6 +620,9 @@ extern { #[cfg(feature="master")] pub fn gcc_jit_function_add_string_attribute(func: *mut gcc_jit_function, attribute: gcc_jit_fn_attribute, value: *const c_char); + #[cfg(feature="master")] + pub fn gcc_jit_function_add_integer_array_attribute(func: *mut gcc_jit_function, attribute: gcc_jit_fn_attribute, value: *const c_int, length: size_t); + #[cfg(feature="master")] pub fn gcc_jit_lvalue_add_attribute(variable: *mut gcc_jit_lvalue, attribute: gcc_jit_variable_attribute, value: *const c_char); diff --git a/src/function.rs b/src/function.rs index 70cf88b..87fd061 100644 --- a/src/function.rs +++ b/src/function.rs @@ -61,6 +61,7 @@ pub enum FnAttribute<'a> { Pure, Const, Weak, + NonNull(Vec), } #[cfg(feature="master")] @@ -78,6 +79,13 @@ impl<'a> FnAttribute<'a> { | FnAttribute::Pure | FnAttribute::Const | FnAttribute::Weak => AttributeValue::None, + FnAttribute::NonNull(ref value) => { + debug_assert!( + value.iter().all(|attr| *attr > 0), + "all values must be > 0 for non-null attribute", + ); + AttributeValue::IntArray(value) + } } } @@ -95,6 +103,7 @@ impl<'a> FnAttribute<'a> { FnAttribute::Pure => gccjit_sys::gcc_jit_fn_attribute::GCC_JIT_FN_ATTRIBUTE_PURE, FnAttribute::Const => gccjit_sys::gcc_jit_fn_attribute::GCC_JIT_FN_ATTRIBUTE_CONST, FnAttribute::Weak => gccjit_sys::gcc_jit_fn_attribute::GCC_JIT_FN_ATTRIBUTE_WEAK, + FnAttribute::NonNull(_) => gccjit_sys::gcc_jit_fn_attribute::GCC_JIT_FN_ATTRIBUTE_NONNULL, } } } @@ -208,7 +217,29 @@ impl<'ctx> Function<'ctx> { pub fn add_attribute<'a>(&self, attribute: FnAttribute<'a>) { let value = attribute.get_value(); match value { - AttributeValue::Int(_) => unimplemented!(), + AttributeValue::Int(value) => { + // Basically the same as `IntArray` but for only one element. + let value = &[value]; + unsafe { + gccjit_sys::gcc_jit_function_add_integer_array_attribute( + self.ptr, + attribute.as_sys(), + value.as_ptr(), + value.len() as _, + ); + } + + } + AttributeValue::IntArray(value) => { + unsafe { + gccjit_sys::gcc_jit_function_add_integer_array_attribute( + self.ptr, + attribute.as_sys(), + value.as_ptr(), + value.len() as _, + ); + } + } AttributeValue::None => { unsafe { gccjit_sys::gcc_jit_function_add_attribute(self.ptr, attribute.as_sys()); diff --git a/src/lvalue.rs b/src/lvalue.rs index fc038da..b3f3107 100644 --- a/src/lvalue.rs +++ b/src/lvalue.rs @@ -39,6 +39,7 @@ pub enum AttributeValue<'a> { Int(i32), None, String(&'a str), + IntArray(&'a [std::ffi::c_int]), } #[cfg(feature="master")] @@ -51,7 +52,7 @@ pub enum VarAttribute { impl VarAttribute { fn get_value(&self) -> AttributeValue { match *self { - VarAttribute::Visibility(visibility) => AttributeValue::String(visibility.as_str()), + Self::Visibility(visibility) => AttributeValue::String(visibility.as_str()), } } @@ -221,6 +222,7 @@ impl<'ctx> LValue<'ctx> { let value = attribute.get_value(); match value { AttributeValue::Int(_) => unimplemented!(), + AttributeValue::IntArray(_) => unimplemented!(), AttributeValue::None => unimplemented!(), AttributeValue::String(string) => { let cstr = CString::new(string).unwrap();