diff --git a/.gitignore b/.gitignore index 50281a44270..2bb07bc394c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Generated by Cargo # will have compiled files and executables /target/ +internal_macros/target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock diff --git a/Cargo.toml b/Cargo.toml index 66cde81db5c..4c75e793eb1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ either = "1.5" enum-methods = "0.0.8" libc = "0.2" llvm-sys = "70.0" +inkwell_internal_macros = { path = "./internal_macros", version = "0.1.0" } [badges] travis-ci = { repository = "TheDan64/inkwell" } diff --git a/README.md b/README.md index 59de03ffe46..6a73eca6acc 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Inkwell aims to help you pen your own programming languages by safely wrapping l ## Requirements -* Any Rust version released in the last year or so +* Rust 1.30+ * Rust Stable, Beta, or Nightly * LLVM 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, or 7 diff --git a/internal_macros/Cargo.toml b/internal_macros/Cargo.toml new file mode 100644 index 00000000000..76e274ce5a4 --- /dev/null +++ b/internal_macros/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "inkwell_internal_macros" +version = "0.1.0" +authors = ["Daniel Kolsoi "] + +[dependencies] +syn = { version = "0.15", features = ["full"] } +quote = "0.6" + +[lib] +proc-macro = true diff --git a/internal_macros/src/lib.rs b/internal_macros/src/lib.rs new file mode 100644 index 00000000000..29945ae7ac0 --- /dev/null +++ b/internal_macros/src/lib.rs @@ -0,0 +1,67 @@ +//! These macros are only intended to be used by inkwell internally +//! and should not be expected to have public support nor stability + +extern crate proc_macro; +#[macro_use] +extern crate quote; +#[macro_use] +extern crate syn; + +use proc_macro::TokenStream; +use syn::{Arm, Expr, ExprLit, Item, Lit, punctuated::Pair, Pat, PatLit}; + +// We could include_str! inkwell's Cargo.toml and extract these features +// so that they don't need to also be managed here... +const ALL_FEATURE_VERSIONS: [&str; 8] = [ + "llvm3-6", + "llvm3-7", + "llvm3-8", + "llvm3-9", + "llvm4-0", + "llvm5-0", + "llvm6-0", + "llvm7-0", +]; + +fn panic_with_feature_versions_usage() -> ! { + panic!("feature_version must take the form: \"llvmX-Y\" => (\"llvmX-Y\" || latest)"); +} + +fn get_latest_feature() -> String { + ALL_FEATURE_VERSIONS[ALL_FEATURE_VERSIONS.len() - 1].into() +} + +#[proc_macro_attribute] +pub fn feature_versions(attribute_args: TokenStream, attributee: TokenStream) -> TokenStream { + let arm = parse_macro_input!(attribute_args as Arm); + + if arm.pats.len() != 1 { + panic_with_feature_versions_usage(); + } + + let start_feature = match arm.pats.first().unwrap() { + Pair::End(Pat::Lit(PatLit { expr })) => match **expr { + Expr::Lit(ExprLit { lit: Lit::Str(ref literal_str), .. }) => literal_str.value(), + _ => panic_with_feature_versions_usage(), + }, + _ => panic_with_feature_versions_usage(), + }; + let end_feature = match *arm.body { + Expr::Lit(ExprLit { lit: Lit::Str(literal_str), .. }) => Some(literal_str.value()), + // We could assert the path is just "latest" but this seems like a lot of extra work... + Expr::Path(_) => None, + _ => panic_with_feature_versions_usage(), + }.unwrap_or_else(get_latest_feature); + + let start_index = ALL_FEATURE_VERSIONS.iter().position(|&str| str == start_feature).unwrap(); + let end_index = ALL_FEATURE_VERSIONS.iter().position(|&str| str == end_feature).unwrap(); + let features = &ALL_FEATURE_VERSIONS[start_index..=end_index]; + let attributee: Item = syn::parse(attributee).expect("Could not parse attributed item"); + + let q = quote! { + #[cfg(any(#(feature = #features),*))] + #attributee + }; + + q.into() +} diff --git a/src/basic_block.rs b/src/basic_block.rs index df0f8021f2c..ffc831de832 100644 --- a/src/basic_block.rs +++ b/src/basic_block.rs @@ -1,7 +1,7 @@ //! A `BasicBlock` is a container of instructions. use llvm_sys::core::{LLVMGetBasicBlockParent, LLVMGetBasicBlockTerminator, LLVMGetNextBasicBlock, LLVMInsertBasicBlock, LLVMIsABasicBlock, LLVMIsConstant, LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString, LLVMTypeOf, LLVMDeleteBasicBlock, LLVMGetPreviousBasicBlock, LLVMRemoveBasicBlockFromParent, LLVMGetFirstInstruction, LLVMGetLastInstruction, LLVMGetTypeContext, LLVMBasicBlockAsValue}; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] +#[feature_versions("llvm3-9" => latest)] use llvm_sys::core::LLVMGetBasicBlockName; use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef}; @@ -436,7 +436,7 @@ impl BasicBlock { /// /// assert_eq!(*bb.get_name(), *CString::new("entry").unwrap()); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_name(&self) -> &CStr { let ptr = unsafe { LLVMGetBasicBlockName(self.basic_block) diff --git a/src/context.rs b/src/context.rs index 2ca507c4ace..ede07809940 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,13 +1,13 @@ //! A `Context` is an opaque owner and manager of core global data. use llvm_sys::core::{LLVMAppendBasicBlockInContext, LLVMContextCreate, LLVMContextDispose, LLVMCreateBuilderInContext, LLVMDoubleTypeInContext, LLVMFloatTypeInContext, LLVMFP128TypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMHalfTypeInContext, LLVMGetGlobalContext, LLVMPPCFP128TypeInContext, LLVMConstStructInContext, LLVMMDNodeInContext, LLVMMDStringInContext, LLVMGetMDKindIDInContext, LLVMX86FP80TypeInContext, LLVMConstStringInContext, LLVMContextSetDiagnosticHandler}; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] +#[feature_versions("llvm4-0" => latest)] use llvm_sys::core::{LLVMCreateEnumAttribute, LLVMCreateStringAttribute}; use llvm_sys::prelude::{LLVMContextRef, LLVMTypeRef, LLVMValueRef, LLVMDiagnosticInfoRef}; use llvm_sys::ir_reader::LLVMParseIRInContext; use libc::c_void; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] +#[feature_versions("llvm4-0" => latest)] use attributes::Attribute; use basic_block::BasicBlock; use builder::Builder; @@ -733,7 +733,7 @@ impl Context { /// /// assert!(enum_attribute.is_enum()); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] + #[feature_versions("llvm4-0" => latest)] pub fn create_enum_attribute(&self, kind_id: u32, val: u64) -> Attribute { let attribute = unsafe { LLVMCreateEnumAttribute(*self.context, kind_id, val) @@ -754,7 +754,7 @@ impl Context { /// /// assert!(string_attribute.is_string()); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] + #[feature_versions("llvm4-0" => latest)] pub fn create_string_attribute(&self, key: &str, val: &str) -> Attribute { let attribute = unsafe { LLVMCreateStringAttribute(*self.context, key.as_ptr() as *const _, key.len() as u32, val.as_ptr() as *const _, val.len() as u32) diff --git a/src/lib.rs b/src/lib.rs index f90514f7352..7854c9a0b84 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,8 @@ extern crate either; extern crate enum_methods; extern crate libc; extern crate llvm_sys; +#[macro_use] +extern crate inkwell_internal_macros; #[deny(missing_docs)] #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] diff --git a/src/passes.rs b/src/passes.rs index 4b165aae224..1dacd0f8597 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -4,13 +4,13 @@ use llvm_sys::prelude::{LLVMPassManagerRef, LLVMPassRegistryRef}; use llvm_sys::transforms::ipo::{LLVMAddArgumentPromotionPass, LLVMAddConstantMergePass, LLVMAddDeadArgEliminationPass, LLVMAddFunctionAttrsPass, LLVMAddFunctionInliningPass, LLVMAddAlwaysInlinerPass, LLVMAddGlobalDCEPass, LLVMAddGlobalOptimizerPass, LLVMAddIPConstantPropagationPass, LLVMAddIPSCCPPass, LLVMAddInternalizePass, LLVMAddStripDeadPrototypesPass, LLVMAddPruneEHPass, LLVMAddStripSymbolsPass}; use llvm_sys::transforms::pass_manager_builder::{LLVMPassManagerBuilderRef, LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderSetDisableUnitAtATime, LLVMPassManagerBuilderSetDisableUnrollLoops, LLVMPassManagerBuilderSetDisableSimplifyLibCalls, LLVMPassManagerBuilderUseInlinerWithThreshold, LLVMPassManagerBuilderPopulateFunctionPassManager, LLVMPassManagerBuilderPopulateModulePassManager, LLVMPassManagerBuilderPopulateLTOPassManager}; use llvm_sys::transforms::scalar::{LLVMAddAggressiveDCEPass, LLVMAddMemCpyOptPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddCFGSimplificationPass, LLVMAddDeadStoreEliminationPass, LLVMAddScalarizerPass, LLVMAddMergedLoadStoreMotionPass, LLVMAddGVNPass, LLVMAddIndVarSimplifyPass, LLVMAddInstructionCombiningPass, LLVMAddJumpThreadingPass, LLVMAddLICMPass, LLVMAddLoopDeletionPass, LLVMAddLoopIdiomPass, LLVMAddLoopRotatePass, LLVMAddLoopRerollPass, LLVMAddLoopUnrollPass, LLVMAddLoopUnswitchPass, LLVMAddPartiallyInlineLibCallsPass, LLVMAddSCCPPass, LLVMAddScalarReplAggregatesPass, LLVMAddScalarReplAggregatesPassSSA, LLVMAddScalarReplAggregatesPassWithThreshold, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddConstantPropagationPass, LLVMAddDemoteMemoryToRegisterPass, LLVMAddVerifierPass, LLVMAddCorrelatedValuePropagationPass, LLVMAddEarlyCSEPass, LLVMAddLowerExpectIntrinsicPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddScopedNoAliasAAPass, LLVMAddBasicAliasAnalysisPass, LLVMAddReassociatePass}; -#[cfg(not(feature = "llvm3-6"))] +#[feature_versions("llvm3-7" => latest)] use llvm_sys::transforms::scalar::LLVMAddBitTrackingDCEPass; use llvm_sys::transforms::vectorize::{LLVMAddLoopVectorizePass, LLVMAddSLPVectorizePass}; use OptimizationLevel; use module::Module; -#[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8"))] +#[feature_versions("llvm3-6" => "llvm3-8")] use targets::TargetData; use values::{AsValueRef, FunctionValue}; @@ -167,7 +167,7 @@ impl PassManager { } } - #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8"))] + #[feature_versions("llvm3-6" => "llvm3-8")] pub fn add_target_data(&self, target_data: &TargetData) { use llvm_sys::target::LLVMAddTargetData; @@ -352,8 +352,7 @@ impl PassManager { /// for each pair of compatible instructions. These heuristics /// are intended to prevent vectorization in cases where it would /// not yield a performance increase of the resulting code. - #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0", - feature = "llvm5-0", feature = "llvm6-0"))] + #[feature_versions("llvm3-6" => "llvm6-0")] pub fn add_bb_vectorize_pass(&self) { use llvm_sys::transforms::vectorize::LLVMAddBBVectorizePass; @@ -387,7 +386,7 @@ impl PassManager { } } - #[cfg(not(feature = "llvm3-6"))] + #[feature_versions("llvm3-7" => latest)] /// No LLVM documentation is available at this time. pub fn add_bit_tracking_dce_pass(&self) { unsafe { @@ -449,7 +448,7 @@ impl PassManager { /// performs redundant load elimination. // REVIEW: Is `LLVMAddGVNPass` deprecated? Should we just seemlessly replace // the old one with this one in 4.0+? - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] + #[feature_versions("llvm4-0" => latest)] pub fn add_new_gvn_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddNewGVNPass; @@ -704,9 +703,9 @@ impl PassManager { /// which allows targets to get away with not implementing the /// switch instruction until it is convenient. pub fn add_lower_switch_pass(&self) { - #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0"))] + #[feature_versions("llvm3-6" => "llvm6-0")] use llvm_sys::transforms::scalar::LLVMAddLowerSwitchPass; - #[cfg(feature = "llvm7-0")] + #[feature_versions("llvm7-0" => latest)] use llvm_sys::transforms::util::LLVMAddLowerSwitchPass; unsafe { @@ -721,9 +720,9 @@ impl PassManager { /// order to rewrite loads and stores as appropriate. This is just /// the standard SSA construction algorithm to construct "pruned" SSA form. pub fn add_promote_memory_to_register_pass(&self) { - #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0"))] + #[feature_versions("llvm3-6" => "llvm6-0")] use llvm_sys::transforms::scalar::LLVMAddPromoteMemoryToRegisterPass; - #[cfg(feature = "llvm7-0")] + #[feature_versions("llvm7-0" => latest)] use llvm_sys::transforms::util::LLVMAddPromoteMemoryToRegisterPass; unsafe { @@ -926,7 +925,7 @@ impl PassManager { } } - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] + #[feature_versions("llvm4-0" => latest)] /// No LLVM documentation is available at this time. pub fn add_early_cse_mem_ssa_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddEarlyCSEMemSSAPass; diff --git a/src/support/mod.rs b/src/support/mod.rs index 276261a0940..f24c7d084ae 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -145,10 +145,9 @@ pub fn is_multithreaded() -> bool { } pub fn enable_llvm_pretty_stack_trace() { - #[cfg(any(feature = "llvm3-6", feature = "llvm3-7"))] + #[feature_versions("llvm3-6" => "llvm3-7")] use llvm_sys::core::LLVMEnablePrettyStackTrace; - #[cfg(any(feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0", - feature = "llvm7-0"))] + #[feature_versions("llvm3-8" => latest)] use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; unsafe { diff --git a/src/types/array_type.rs b/src/types/array_type.rs index c6cf86a6064..a520c619b39 100644 --- a/src/types/array_type.rs +++ b/src/types/array_type.rs @@ -244,7 +244,7 @@ impl ArrayType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `ArrayType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.array_type.print_to_stderr() } diff --git a/src/types/float_type.rs b/src/types/float_type.rs index ef58b9236bc..6125585f2ec 100644 --- a/src/types/float_type.rs +++ b/src/types/float_type.rs @@ -387,7 +387,7 @@ impl FloatType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions. - #[cfg(any(feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0"))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.float_type.print_to_stderr() } diff --git a/src/types/fn_type.rs b/src/types/fn_type.rs index b2a2c1a873c..4a8d7e9555f 100644 --- a/src/types/fn_type.rs +++ b/src/types/fn_type.rs @@ -162,7 +162,7 @@ impl FunctionType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.fn_type.print_to_stderr() } diff --git a/src/types/int_type.rs b/src/types/int_type.rs index 6080862b552..9e71bec3088 100644 --- a/src/types/int_type.rs +++ b/src/types/int_type.rs @@ -473,7 +473,7 @@ impl IntType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions. - #[cfg(any(feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0"))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.int_type.print_to_stderr() } diff --git a/src/types/mod.rs b/src/types/mod.rs index 91f0081d731..04a1ae70442 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -32,7 +32,7 @@ pub use types::vec_type::VectorType; pub use types::void_type::VoidType; pub(crate) use types::traits::AsTypeRef; -#[cfg(not(feature = "llvm3-6"))] +#[feature_versions("llvm3-7" => "llvm4-0")] use llvm_sys::core::LLVMDumpType; use llvm_sys::core::{LLVMAlignOf, LLVMGetTypeContext, LLVMFunctionType, LLVMArrayType, LLVMGetUndef, LLVMPointerType, LLVMPrintTypeToString, LLVMTypeIsSized, LLVMSizeOf, LLVMVectorType, LLVMConstPointerNull, LLVMGetElementType, LLVMConstNull}; use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef}; @@ -65,7 +65,7 @@ impl Type { // and so will fail to link when used. I've decided to remove it from 5.0+ // for now. We should consider removing it altogether since print_to_string // could be used and manually written to stderr in rust... - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] fn print_to_stderr(&self) { unsafe { LLVMDumpType(self.type_); diff --git a/src/types/ptr_type.rs b/src/types/ptr_type.rs index 624e65690a8..c97bf60990e 100644 --- a/src/types/ptr_type.rs +++ b/src/types/ptr_type.rs @@ -178,7 +178,7 @@ impl PointerType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.ptr_type.print_to_stderr() } diff --git a/src/types/struct_type.rs b/src/types/struct_type.rs index 8ca558ff3bc..1db4e173abd 100644 --- a/src/types/struct_type.rs +++ b/src/types/struct_type.rs @@ -429,7 +429,7 @@ impl StructType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `StructType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.struct_type.print_to_stderr() } diff --git a/src/types/vec_type.rs b/src/types/vec_type.rs index f74e4ba1220..7011733d058 100644 --- a/src/types/vec_type.rs +++ b/src/types/vec_type.rs @@ -183,7 +183,7 @@ impl VectorType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.vec_type.print_to_stderr() } diff --git a/src/types/void_type.rs b/src/types/void_type.rs index f6f64c7fadb..432def947ed 100644 --- a/src/types/void_type.rs +++ b/src/types/void_type.rs @@ -118,7 +118,7 @@ impl VoidType { // See Type::print_to_stderr note on 5.0+ status /// Prints the definition of a `VoidType` to stderr. Not available in newer LLVM versions. - #[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))] + #[feature_versions("llvm3-7" => "llvm4-0")] pub fn print_to_stderr(&self) { self.void_type.print_to_stderr() } diff --git a/src/values/call_site_value.rs b/src/values/call_site_value.rs index d6764f917d4..9b3f83a85dc 100644 --- a/src/values/call_site_value.rs +++ b/src/values/call_site_value.rs @@ -3,7 +3,7 @@ use llvm_sys::LLVMTypeKind; use llvm_sys::core::{LLVMIsTailCall, LLVMSetTailCall, LLVMGetTypeKind, LLVMTypeOf, LLVMSetInstructionCallConv, LLVMGetInstructionCallConv, LLVMSetInstrParamAlignment}; use llvm_sys::prelude::LLVMValueRef; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] +#[feature_versions("llvm3-9" => latest)] use attributes::Attribute; use support::LLVMString; use values::{AsValueRef, BasicValueEnum, FunctionValue, InstructionValue, Value}; @@ -129,7 +129,7 @@ impl CallSiteValue { /// call_site_value.add_attribute(0, string_attribute); /// call_site_value.add_attribute(0, enum_attribute); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn add_attribute(&self, index: u32, attribute: Attribute) { use llvm_sys::core::LLVMAddCallSiteAttribute; @@ -161,7 +161,7 @@ impl CallSiteValue { /// /// assert_eq!(call_site_value.get_called_fn_value(), fn_value); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_called_fn_value(&self) -> FunctionValue { use llvm_sys::core::LLVMGetCalledValue; @@ -198,7 +198,7 @@ impl CallSiteValue { /// /// assert_eq!(call_site_value.count_attributes(0), 2); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn count_attributes(&self, index: u32) -> u32 { use llvm_sys::core::LLVMGetCallSiteAttributeCount; @@ -234,7 +234,7 @@ impl CallSiteValue { /// assert_eq!(call_site_value.get_enum_attribute(0, 1).unwrap(), enum_attribute); /// ``` // SubTypes: -> Attribute - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_enum_attribute(&self, index: u32, kind_id: u32) -> Option { use llvm_sys::core::LLVMGetCallSiteEnumAttribute; @@ -276,7 +276,7 @@ impl CallSiteValue { /// assert_eq!(call_site_value.get_string_attribute(0, "my_key").unwrap(), string_attribute); /// ``` // SubTypes: -> Attribute - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_string_attribute(&self, index: u32, key: &str) -> Option { use llvm_sys::core::LLVMGetCallSiteStringAttribute; @@ -318,7 +318,7 @@ impl CallSiteValue { /// /// assert_eq!(call_site_value.get_enum_attribute(0, 1), None); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn remove_enum_attribute(&self, index: u32, kind_id: u32) { use llvm_sys::core::LLVMRemoveCallSiteEnumAttribute; @@ -354,7 +354,7 @@ impl CallSiteValue { /// /// assert_eq!(call_site_value.get_string_attribute(0, "my_key"), None); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn remove_string_attribute(&self, index: u32, key: &str) { use llvm_sys::core::LLVMRemoveCallSiteStringAttribute; @@ -386,7 +386,7 @@ impl CallSiteValue { /// /// assert_eq!(call_site_value.count_arguments(), 0); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn count_arguments(&self) -> u32 { use llvm_sys::core::LLVMGetNumArgOperands; diff --git a/src/values/fn_value.rs b/src/values/fn_value.rs index e11fe0a141d..7f88a45eeb6 100644 --- a/src/values/fn_value.rs +++ b/src/values/fn_value.rs @@ -1,8 +1,8 @@ use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyFunction, LLVMViewFunctionCFG, LLVMViewFunctionCFGOnly}; use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC, LLVMSetLinkage, LLVMSetParamAlignment, LLVMGetParams}; -#[cfg(not(feature = "llvm3-6"))] +#[feature_versions("llvm3-7" => latest)] use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn}; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] +#[feature_versions("llvm3-9" => latest)] use llvm_sys::core::{LLVMAddAttributeAtIndex, LLVMGetAttributeCountAtIndex, LLVMGetEnumAttributeAtIndex, LLVMGetStringAttributeAtIndex, LLVMRemoveEnumAttributeAtIndex, LLVMRemoveStringAttributeAtIndex}; use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef}; @@ -10,7 +10,7 @@ use std::ffi::{CStr, CString}; use std::mem::forget; use std::fmt; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] +#[feature_versions("llvm3-9" => latest)] use attributes::Attribute; use basic_block::BasicBlock; use module::Linkage; @@ -279,7 +279,7 @@ impl FunctionValue { } // TODOC: How this works as an exception handler - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn has_personality_function(&self) -> bool { use llvm_sys::core::LLVMHasPersonalityFn; @@ -320,7 +320,7 @@ impl FunctionValue { FunctionValue::new(value) } - #[cfg(not(feature = "llvm3-6"))] + #[feature_versions("llvm3-7" => latest)] pub fn set_personality_function(&self, personality_fn: FunctionValue) { unsafe { LLVMSetPersonalityFn(self.as_value_ref(), personality_fn.as_value_ref()) @@ -382,7 +382,7 @@ impl FunctionValue { /// fn_value.add_attribute(0, string_attribute); /// fn_value.add_attribute(0, enum_attribute); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn add_attribute(&self, index: u32, attribute: Attribute) { unsafe { LLVMAddAttributeAtIndex(self.as_value_ref(), index, attribute.attribute) @@ -410,7 +410,7 @@ impl FunctionValue { /// /// assert_eq!(fn_value.count_attributes(0), 2); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn count_attributes(&self, index: u32) -> u32 { unsafe { LLVMGetAttributeCountAtIndex(self.as_value_ref(), index) @@ -435,7 +435,7 @@ impl FunctionValue { /// fn_value.add_attribute(0, string_attribute); /// fn_value.remove_string_attribute(0, "my_key"); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn remove_string_attribute(&self, index: u32, key: &str) { unsafe { LLVMRemoveStringAttributeAtIndex(self.as_value_ref(), index, key.as_ptr() as *const i8, key.len() as u32) @@ -460,7 +460,7 @@ impl FunctionValue { /// fn_value.add_attribute(0, enum_attribute); /// fn_value.remove_enum_attribute(0, 1); /// ``` - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn remove_enum_attribute(&self, index: u32, kind_id: u32) { unsafe { LLVMRemoveEnumAttributeAtIndex(self.as_value_ref(), index, kind_id) @@ -487,7 +487,7 @@ impl FunctionValue { /// assert_eq!(fn_value.get_enum_attribute(0, 1), Some(enum_attribute)); /// ``` // SubTypes: -> Option> - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_enum_attribute(&self, index: u32, kind_id: u32) -> Option { let ptr = unsafe { LLVMGetEnumAttributeAtIndex(self.as_value_ref(), index, kind_id) @@ -520,7 +520,7 @@ impl FunctionValue { /// assert_eq!(fn_value.get_string_attribute(0, "my_key"), Some(string_attribute)); /// ``` // SubTypes: -> Option> - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))] + #[feature_versions("llvm3-9" => latest)] pub fn get_string_attribute(&self, index: u32, key: &str) -> Option { let ptr = unsafe { LLVMGetStringAttributeAtIndex(self.as_value_ref(), index, key.as_ptr() as *const i8, key.len() as u32) diff --git a/src/values/int_value.rs b/src/values/int_value.rs index 3921fa311dc..ae003454fbe 100644 --- a/src/values/int_value.rs +++ b/src/values/int_value.rs @@ -1,5 +1,5 @@ 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}; -#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] +#[feature_versions("llvm4-0" => latest)] use llvm_sys::core::LLVMConstExactUDiv; use llvm_sys::prelude::LLVMValueRef; @@ -186,7 +186,7 @@ impl IntValue { IntValue::new(value) } - #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))] + #[feature_versions("llvm4-0" => latest)] pub fn const_exact_unsigned_div(&self, rhs: IntValue) -> Self { let value = unsafe { LLVMConstExactUDiv(self.as_value_ref(), rhs.as_value_ref())