Skip to content

Commit

Permalink
Merge pull request rust-lang#125 from wasmerio/constantint
Browse files Browse the repository at this point in the history
Add IntValue::is_constant_int() which is true iff is_const() and the int value is not a constant expression.
  • Loading branch information
TheDan64 authored Nov 2, 2019
2 parents e4fc903 + 0861b69 commit 2dd4d2a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
30 changes: 26 additions & 4 deletions src/values/int_value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use llvm_sys::core::{LLVMConstNot, LLVMConstNeg, LLVMConstNSWNeg, LLVMConstNUWNeg, LLVMConstAdd, LLVMConstNSWAdd, LLVMConstNUWAdd, LLVMConstSub, LLVMConstNSWSub, LLVMConstNUWSub, LLVMConstMul, LLVMConstNSWMul, LLVMConstNUWMul, LLVMConstUDiv, LLVMConstSDiv, LLVMConstSRem, LLVMConstURem, LLVMConstIntCast, LLVMConstXor, LLVMConstOr, LLVMConstAnd, LLVMConstExactSDiv, LLVMConstShl, LLVMConstLShr, LLVMConstAShr, LLVMConstUIToFP, LLVMConstSIToFP, LLVMConstIntToPtr, LLVMConstTrunc, LLVMConstSExt, LLVMConstZExt, LLVMConstTruncOrBitCast, LLVMConstSExtOrBitCast, LLVMConstZExtOrBitCast, LLVMConstBitCast, LLVMConstICmp, LLVMConstIntGetZExtValue, LLVMConstIntGetSExtValue, LLVMConstSelect};
use llvm_sys::core::{LLVMConstNot, LLVMConstNeg, LLVMConstNSWNeg, LLVMConstNUWNeg, LLVMConstAdd, LLVMConstNSWAdd, LLVMConstNUWAdd, LLVMConstSub, LLVMConstNSWSub, LLVMConstNUWSub, LLVMConstMul, LLVMConstNSWMul, LLVMConstNUWMul, LLVMConstUDiv, LLVMConstSDiv, LLVMConstSRem, LLVMConstURem, LLVMConstIntCast, LLVMConstXor, LLVMConstOr, LLVMConstAnd, LLVMConstExactSDiv, LLVMConstShl, LLVMConstLShr, LLVMConstAShr, LLVMConstUIToFP, LLVMConstSIToFP, LLVMConstIntToPtr, LLVMConstTrunc, LLVMConstSExt, LLVMConstZExt, LLVMConstTruncOrBitCast, LLVMConstSExtOrBitCast, LLVMConstZExtOrBitCast, LLVMConstBitCast, LLVMConstICmp, LLVMConstIntGetZExtValue, LLVMConstIntGetSExtValue, LLVMConstSelect, LLVMIsAConstantInt};
#[llvm_versions(4.0..=latest)]
use llvm_sys::core::LLVMConstExactUDiv;
use llvm_sys::prelude::LLVMValueRef;
Expand Down Expand Up @@ -385,7 +385,10 @@ impl IntValue {
BasicValueEnum::new(value)
}

/// Determines whether or not an `IntValue` is a constant.
/// Determines whether or not an `IntValue` is an `llvm::Constant`.
///
/// Constants includes values that are not known at compile time, for
/// example the address of a function casted to an integer.
///
/// # Example
///
Expand All @@ -402,6 +405,25 @@ impl IntValue {
self.int_value.is_const()
}

/// Determines whether or not an `IntValue` is an `llvm::ConstantInt`.
///
/// ConstantInt only includes values that are known at compile time.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let i64_type = context.i64_type();
/// let i64_val = i64_type.const_int(12, false);
///
/// assert!(i64_val.is_constant_int());
/// ```
pub fn is_constant_int(&self) -> bool {
!unsafe { LLVMIsAConstantInt(self.as_value_ref()) }.is_null()
}

/// Obtains a constant `IntValue`'s zero extended value.
///
/// # Example
Expand All @@ -417,7 +439,7 @@ impl IntValue {
/// ```
pub fn get_zero_extended_constant(&self) -> Option<u64> {
// Garbage values are produced on non constant values
if !self.is_const() {
if !self.is_constant_int() {
return None;
}
if self.get_type().get_bit_width() > 64 {
Expand All @@ -444,7 +466,7 @@ impl IntValue {
/// ```
pub fn get_sign_extended_constant(&self) -> Option<i64> {
// Garbage values are produced on non constant values
if !self.is_const() {
if !self.is_constant_int() {
return None;
}
if self.get_type().get_bit_width() > 64 {
Expand Down
17 changes: 17 additions & 0 deletions tests/all/test_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1251,3 +1251,20 @@ fn test_aggregate_returns() {

assert!(module.verify().is_ok());
}

#[test]
fn test_constant_expression() {
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_mod");

let i32_type = context.i32_type();
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);

let function = module.add_function("", fn_type, None);
let expr = builder.build_ptr_to_int(function.as_global_value().as_pointer_value(), i32_type, "");

assert!(expr.is_const());
assert!(!expr.is_constant_int());
}

0 comments on commit 2dd4d2a

Please sign in to comment.