From 6c0fb56b3554e939f9ca61b465043d6a84fb7b95 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 8 May 2024 23:54:38 +0200 Subject: [PATCH] Update `llvm_versions` macro syntax to match Rust ranges (#493) * Update macro syntax to match Rust ranges * Update macro usage --- .../implementation_typed_pointers.rs | 4 +- examples/kaleidoscope/main.rs | 8 +- internal_macros/src/cfg.rs | 254 ++++++++ internal_macros/src/enum.rs | 217 +++++++ internal_macros/src/lib.rs | 571 +----------------- src/attributes.rs | 20 +- src/builder.rs | 72 +-- src/context.rs | 42 +- src/debug_info.rs | 68 +-- src/intrinsics.rs | 4 +- src/lib.rs | 12 +- src/module.rs | 46 +- src/passes.rs | 190 +++--- src/support/mod.rs | 4 +- src/targets.rs | 26 +- src/types/array_type.rs | 2 +- src/types/float_type.rs | 2 +- src/types/int_type.rs | 2 +- src/types/metadata_type.rs | 10 +- src/types/mod.rs | 4 +- src/types/ptr_type.rs | 10 +- src/types/struct_type.rs | 2 +- src/types/vec_type.rs | 2 +- src/values/call_site_value.rs | 6 +- src/values/callable_value.rs | 2 +- src/values/float_value.rs | 28 +- src/values/fn_value.rs | 12 +- src/values/global_value.rs | 38 +- src/values/instruction_value.rs | 37 +- src/values/int_value.rs | 46 +- src/values/metadata_value.rs | 6 +- src/values/mod.rs | 4 +- src/values/ptr_value.rs | 12 +- src/values/traits.rs | 8 +- src/values/vec_value.rs | 4 +- tests/all/test_attributes.rs | 2 +- tests/all/test_builder.rs | 20 +- tests/all/test_context.rs | 2 +- tests/all/test_debug_info.rs | 4 +- tests/all/test_instruction_values.rs | 12 +- tests/all/test_intrinsics.rs | 8 +- tests/all/test_object_file.rs | 14 +- tests/all/test_passes.rs | 8 +- tests/all/test_targets.rs | 4 +- tests/all/test_types.rs | 2 +- tests/all/test_values.rs | 8 +- 46 files changed, 901 insertions(+), 958 deletions(-) create mode 100644 internal_macros/src/cfg.rs create mode 100644 internal_macros/src/enum.rs diff --git a/examples/kaleidoscope/implementation_typed_pointers.rs b/examples/kaleidoscope/implementation_typed_pointers.rs index 5d752f04a85..96ffeb6f233 100644 --- a/examples/kaleidoscope/implementation_typed_pointers.rs +++ b/examples/kaleidoscope/implementation_typed_pointers.rs @@ -858,12 +858,12 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> { builder.build_alloca(self.context.f64_type(), name).unwrap() } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_load(&self, ptr: PointerValue<'ctx>, name: &str) -> BasicValueEnum<'ctx> { self.builder.build_load(ptr, name).unwrap() } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_load(&self, ptr: PointerValue<'ctx>, name: &str) -> BasicValueEnum<'ctx> { self.builder.build_load(self.context.f64_type(), ptr, name).unwrap() } diff --git a/examples/kaleidoscope/main.rs b/examples/kaleidoscope/main.rs index 1ce876bed6c..9e30673e689 100644 --- a/examples/kaleidoscope/main.rs +++ b/examples/kaleidoscope/main.rs @@ -20,10 +20,10 @@ use std::io::{self, Write}; use inkwell::context::Context; use inkwell::module::Module; -#[llvm_versions(4.0..=15.0)] +#[llvm_versions(..=15)] use inkwell::passes::PassManager; use inkwell::OptimizationLevel; -#[llvm_versions(16.0..=latest)] +#[llvm_versions(16..)] use inkwell::{ passes::PassBuilderOptions, targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine}, @@ -65,7 +65,7 @@ pub extern "C" fn printd(x: f64) -> f64 { #[used] static EXTERNAL_FNS: [extern "C" fn(f64) -> f64; 2] = [putchard, printd]; -#[llvm_versions(4.0..=15.0)] +#[llvm_versions(..=15)] fn run_passes_on(module: &Module) { let fpm = PassManager::create(()); @@ -79,7 +79,7 @@ fn run_passes_on(module: &Module) { fpm.run_on(module); } -#[llvm_versions(16.0..=latest)] +#[llvm_versions(16..)] fn run_passes_on(module: &Module) { Target::initialize_all(&InitializationConfig::default()); let target_triple = TargetMachine::get_default_triple(); diff --git a/internal_macros/src/cfg.rs b/internal_macros/src/cfg.rs new file mode 100644 index 00000000000..73e1f1e425a --- /dev/null +++ b/internal_macros/src/cfg.rs @@ -0,0 +1,254 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use std::cmp::Ordering; +use syn::fold::Fold; +use syn::parse::{Error, Parse, ParseStream, Result}; +use syn::spanned::Spanned; +use syn::{Attribute, Field, Item, Token, Variant}; +use syn::{Lit, RangeLimits}; + +// This array should match the LLVM features in the top level Cargo manifest +const FEATURE_VERSIONS: &[&str] = &[ + "llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", + "llvm14-0", "llvm15-0", "llvm16-0", "llvm17-0", "llvm18-0", +]; + +pub struct VersionRange { + start: Option, + limits: RangeLimits, + end: Option, + features: &'static [&'static str], +} + +impl Parse for VersionRange { + fn parse(input: ParseStream) -> Result { + let start = if input.peek(Token![..]) || input.peek(Token![..=]) { + None + } else { + Some(input.parse()?) + }; + let limits = input.parse::()?; + let end = if matches!(limits, RangeLimits::HalfOpen(_)) && (input.is_empty() || input.peek(Token![,])) { + None + } else { + Some(input.parse()?) + }; + let mut this = Self { + start, + limits, + end, + features: &[], + }; + this.features = this.get_features()?; + Ok(this) + } +} + +impl VersionRange { + fn doc_cfg(&self) -> Option { + if cfg!(feature = "nightly") { + let features = self.features; + Some(quote! { + #[doc(cfg(any(#(feature = #features),*)))] + }) + } else { + None + } + } + + fn cfg(&self) -> TokenStream { + let features = self.features; + quote! { + #[cfg(any(#(feature = #features),*))] + } + } + + fn get_features(&self) -> Result<&'static [&'static str]> { + let features = FEATURE_VERSIONS; + let start = self.start.as_ref().map(|v| v.get_index(features)).transpose()?; + if let Some(0) = start { + let min = features[0]; + return Err(Error::new( + self.start.as_ref().unwrap().span, + format!("start version is the same as the minimum version ({min})"), + )); + } + let start = start.unwrap_or(0); + + let end = self.end.as_ref().map(|v| v.get_index(features)).transpose()?; + if let Some(end) = end { + let span = || self.end.as_ref().unwrap().span; + match end.cmp(&start) { + Ordering::Less => return Err(Error::new(span(), "end version is before start version")), + Ordering::Equal => return Err(Error::new(span(), "start and end versions are the same")), + Ordering::Greater => {}, + } + } + let selected = match (self.limits, end) { + (RangeLimits::Closed(_), end) => &features[start..=end.expect("already checked")], + (RangeLimits::HalfOpen(_), None) => &features[start..], + (RangeLimits::HalfOpen(_), Some(end)) => &features[start..end], + }; + if selected.len() == features.len() { + return Err(Error::new(self.span(), "selected all features, remove this attribute")); + } + Ok(selected) + } + + fn span(&self) -> Span { + match (&self.start, &self.end) { + (Some(start), Some(end)) => start.span.join(end.span).unwrap(), + (Some(start), None) => start.span, + (None, Some(end)) => end.span, + (None, None) => self.limits.span(), + } + } +} + +struct Version { + major: u32, + minor: u32, + span: Span, +} + +impl Parse for Version { + fn parse(input: ParseStream) -> Result { + let lit = input.parse::()?; + let (major, minor) = match &lit { + Lit::Int(int) => (int.base10_parse()?, 0), + Lit::Float(float) => { + let s = float.base10_digits(); + let mut parts = s.split('.'); + let major = parts + .next() + .unwrap() + .parse() + .map_err(|e| syn::Error::new(float.span(), e))?; + let minor = if let Some(minor) = parts.next() { + minor.parse().map_err(|e| syn::Error::new(float.span(), e))? + } else { + 0 + }; + (major, minor) + }, + _ => return Err(Error::new(lit.span(), "expected integer or float")), + }; + Ok(Self { + major, + minor, + span: lit.span(), + }) + } +} + +impl Version { + fn get_index(&self, features: &[&str]) -> Result { + let feature = self.as_feature(); + match features.iter().position(|&s| s == feature) { + None => Err(Error::new(self.span, format!("undefined feature version: {feature:?}"))), + Some(index) => Ok(index), + } + } + + fn as_feature(&self) -> String { + format!("llvm{}-{}", self.major, self.minor) + } +} + +/// Folder for expanding `llvm_versions` attributes. +pub struct VersionFolder { + result: Result<()>, +} + +impl VersionFolder { + pub fn new() -> Self { + Self { result: Ok(()) } + } + + pub fn fold_any(f: impl FnOnce(&mut Self, T) -> T, t: T) -> Result { + let mut folder = VersionFolder::new(); + let t = f(&mut folder, t); + folder.result?; + Ok(t) + } + + fn has_error(&self) -> bool { + self.result.is_err() + } + + fn expand_llvm_versions_attr(&mut self, attr: &Attribute) -> Attribute { + // Make no modifications if we've generated an error + if self.has_error() { + return attr.clone(); + } + + // If this isn't an llvm_versions attribute, skip it + if !attr.path().is_ident("llvm_versions") { + return attr.clone(); + } + + // Expand from llvm_versions to raw cfg attribute + match attr.parse_args::() { + Ok(version_range) => { + let cfg = version_range.cfg(); + syn::parse_quote!(#cfg) + }, + Err(err) => { + self.result = Err(err); + attr.clone() + }, + } + } +} + +impl Fold for VersionFolder { + fn fold_variant(&mut self, mut variant: Variant) -> Variant { + if self.has_error() { + return variant; + } + + let attrs = variant + .attrs + .iter() + .map(|attr| self.expand_llvm_versions_attr(attr)) + .collect::>(); + variant.attrs = attrs; + variant + } + + fn fold_field(&mut self, mut field: Field) -> Field { + if self.has_error() { + return field; + } + + let attrs = field + .attrs + .iter() + .map(|attr| self.expand_llvm_versions_attr(attr)) + .collect::>(); + field.attrs = attrs; + field + } +} + +pub fn expand(args: Option, input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input_clone = input.clone(); + let item = syn::parse_macro_input!(input as Item); + let args = match args { + Some(args) => { + let cfg = args.cfg(); + let doc_cfg = args.doc_cfg(); + quote! { #cfg #doc_cfg } + }, + None => quote! {}, + }; + match VersionFolder::fold_any(Fold::fold_item, item) { + Ok(item) => quote! { #args #item }, + Err(err) => { + let err = err.into_compile_error(); + let input = proc_macro2::TokenStream::from(input_clone); + quote! { #err #args #input } + }, + } + .into() +} diff --git a/internal_macros/src/enum.rs b/internal_macros/src/enum.rs new file mode 100644 index 00000000000..5272b40ccfe --- /dev/null +++ b/internal_macros/src/enum.rs @@ -0,0 +1,217 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::fold::Fold; +use syn::parse::{Error, Parse, ParseStream, Result}; +use syn::parse_quote; +use syn::spanned::Spanned; +use syn::{Arm, PatPath, Path}; +use syn::{Attribute, Ident, Variant}; + +/// Used to track an enum variant and its corresponding mappings (LLVM <-> Rust), +/// as well as attributes +struct EnumVariant { + llvm_variant: Ident, + rust_variant: Ident, + attrs: Vec, +} + +impl EnumVariant { + fn new(variant: &Variant) -> Self { + let rust_variant = variant.ident.clone(); + let llvm_variant = Ident::new(&format!("LLVM{}", rust_variant), variant.span()); + let mut attrs = variant.attrs.clone(); + attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); + Self { + llvm_variant, + rust_variant, + attrs, + } + } + + fn with_name(variant: &Variant, mut llvm_variant: Ident) -> Self { + let rust_variant = variant.ident.clone(); + llvm_variant.set_span(rust_variant.span()); + let mut attrs = variant.attrs.clone(); + attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); + Self { + llvm_variant, + rust_variant, + attrs, + } + } +} + +/// Used when constructing the variants of an enum declaration. +#[derive(Default)] +struct EnumVariants { + variants: Vec, + error: Option, +} + +impl EnumVariants { + #[inline] + fn len(&self) -> usize { + self.variants.len() + } + + #[inline] + fn iter(&self) -> core::slice::Iter<'_, EnumVariant> { + self.variants.iter() + } + + #[inline] + fn has_error(&self) -> bool { + self.error.is_some() + } + + #[inline] + fn set_error(&mut self, err: &str, span: Span) { + self.error = Some(Error::new(span, err)); + } + + fn into_error(self) -> Error { + self.error.unwrap() + } +} + +impl Fold for EnumVariants { + fn fold_variant(&mut self, mut variant: Variant) -> Variant { + use syn::Meta; + + if self.has_error() { + return variant; + } + + // Check for llvm_variant + if let Some(attr) = variant.attrs.iter().find(|attr| attr.path().is_ident("llvm_variant")) { + // Extract attribute meta + if let Meta::List(meta) = &attr.meta { + // We should only have one element + + if let Ok(Meta::Path(name)) = meta.parse_args() { + self.variants + .push(EnumVariant::with_name(&variant, name.get_ident().unwrap().clone())); + // Strip the llvm_variant attribute from the final AST + variant.attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); + return variant; + } + } + + // If at any point we fall through to here, it is the same basic issue, invalid format + self.set_error("expected #[llvm_variant(VARIANT_NAME)]", attr.span()); + return variant; + } + + self.variants.push(EnumVariant::new(&variant)); + variant + } +} + +/// Used to parse an enum declaration decorated with `#[llvm_enum(..)]` +pub struct LLVMEnumType { + name: Ident, + decl: syn::ItemEnum, + variants: EnumVariants, +} + +impl Parse for LLVMEnumType { + fn parse(input: ParseStream) -> Result { + // Parse enum declaration + let decl = input.parse::()?; + let name = decl.ident.clone(); + + // Fold over variants and expand llvm_versions + let decl = crate::cfg::VersionFolder::fold_any(Fold::fold_item_enum, decl)?; + + let mut variants = EnumVariants::default(); + let decl = variants.fold_item_enum(decl); + if variants.has_error() { + return Err(variants.into_error()); + } + + Ok(Self { name, decl, variants }) + } +} + +pub fn llvm_enum(llvm_ty: Path, llvm_enum_type: LLVMEnumType) -> TokenStream { + // Construct match arms for LLVM -> Rust enum conversion + let mut from_arms = Vec::with_capacity(llvm_enum_type.variants.len()); + for variant in llvm_enum_type.variants.iter() { + let src_variant = variant.llvm_variant.clone(); + // Filter out doc comments or else rustc will warn about docs on match arms in newer versions. + let src_attrs: Vec<_> = variant + .attrs + .iter() + .filter(|&attr| !attr.meta.path().is_ident("doc")) + .collect(); + let src_ty = llvm_ty.clone(); + let dst_variant = variant.rust_variant.clone(); + let dst_ty = llvm_enum_type.name.clone(); + + let pat = PatPath { + attrs: Vec::new(), + qself: None, + path: parse_quote!(#src_ty::#src_variant), + }; + + let arm: Arm = parse_quote! { + #(#src_attrs)* + #pat => { #dst_ty::#dst_variant } + }; + from_arms.push(arm); + } + + // Construct match arms for Rust -> LLVM enum conversion + let mut to_arms = Vec::with_capacity(llvm_enum_type.variants.len()); + for variant in llvm_enum_type.variants.iter() { + let src_variant = variant.rust_variant.clone(); + // Filter out doc comments or else rustc will warn about docs on match arms in newer versions. + let src_attrs: Vec<_> = variant + .attrs + .iter() + .filter(|&attr| !attr.meta.path().is_ident("doc")) + .collect(); + let src_ty = llvm_enum_type.name.clone(); + let dst_variant = variant.llvm_variant.clone(); + let dst_ty = llvm_ty.clone(); + + let pat = PatPath { + attrs: Vec::new(), + qself: None, + path: parse_quote!(#src_ty::#src_variant), + }; + + let arm: Arm = parse_quote! { + #(#src_attrs)* + #pat => { #dst_ty::#dst_variant } + }; + to_arms.push(arm); + } + + let enum_ty = llvm_enum_type.name.clone(); + let enum_decl = llvm_enum_type.decl; + + quote! { + #enum_decl + + impl #enum_ty { + fn new(src: #llvm_ty) -> Self { + match src { + #(#from_arms)* + } + } + } + impl From<#llvm_ty> for #enum_ty { + fn from(src: #llvm_ty) -> Self { + Self::new(src) + } + } + impl Into<#llvm_ty> for #enum_ty { + fn into(self) -> #llvm_ty { + match self { + #(#to_arms),* + } + } + } + } +} diff --git a/internal_macros/src/lib.rs b/internal_macros/src/lib.rs index 137efb58a51..14088ce0c4a 100644 --- a/internal_macros/src/lib.rs +++ b/internal_macros/src/lib.rs @@ -3,345 +3,36 @@ //! Here be dragons 🐉 use proc_macro::TokenStream; -use proc_macro2::Span; -use quote::quote; -use syn::fold::Fold; -use syn::parse::{Error, Parse, ParseStream, Result}; -use syn::spanned::Spanned; -use syn::{parse_macro_input, parse_quote}; -use syn::{Attribute, Field, Ident, Item, LitFloat, Token, Variant}; +use syn::parse_macro_input; -// This array should match the LLVM features in the top level Cargo manifest -const FEATURE_VERSIONS: [&str; 15] = [ - "llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", - "llvm14-0", "llvm15-0", "llvm16-0", "llvm17-0", "llvm18-0", -]; - -/// Gets the index of the feature version that represents `latest` -fn get_latest_feature_index(features: &[&str]) -> usize { - features.len() - 1 -} - -/// Gets the index of the feature version that matches the input string -fn get_feature_index(features: &[&str], feature: String, span: Span) -> Result { - let feat = feature.as_str(); - match features.iter().position(|&s| s == feat) { - None => Err(Error::new( - span, - format!("Invalid feature version: {}, not defined", feature), - )), - Some(index) => Ok(index), - } -} - -/// Gets a vector of feature versions represented by the given VersionType -fn get_features(vt: VersionType) -> Result> { - let features = FEATURE_VERSIONS; - let latest = get_latest_feature_index(&features); - match vt { - VersionType::Specific(version, span) => { - let feature = f64_to_feature_string(version); - let index = get_feature_index(&features, feature, span)?; - Ok(features[index..=index].to_vec()) - }, - VersionType::InclusiveRangeToLatest(version, span) => { - let feature = f64_to_feature_string(version); - let index = get_feature_index(&features, feature, span)?; - Ok(features[index..=latest].to_vec()) - }, - VersionType::InclusiveRange((start, start_span), (end, end_span)) => { - let start_feature = f64_to_feature_string(start); - let end_feature = f64_to_feature_string(end); - let start_index = get_feature_index(&features, start_feature, start_span)?; - let end_index = get_feature_index(&features, end_feature, end_span)?; - if end_index < start_index { - let message = format!( - "Invalid version range: {} must be greater than or equal to {}", - start, end - ); - Err(Error::new(end_span, message)) - } else { - Ok(features[start_index..=end_index].to_vec()) - } - }, - VersionType::ExclusiveRangeToLatest(version, span) => { - let feature = f64_to_feature_string(version); - let index = get_feature_index(&features, feature, span)?; - if latest == index { - let message = format!( - "Invalid version range: {}..latest produces an empty feature set", - version - ); - Err(Error::new(span, message)) - } else { - Ok(features[index..latest].to_vec()) - } - }, - VersionType::ExclusiveRange((start, start_span), (end, end_span)) => { - let start_feature = f64_to_feature_string(start); - let end_feature = f64_to_feature_string(end); - let start_index = get_feature_index(&features, start_feature, start_span)?; - let end_index = get_feature_index(&features, end_feature, end_span)?; - - match end_index.cmp(&start_index) { - std::cmp::Ordering::Equal => { - let message = format!( - "Invalid version range: {}..{} produces an empty feature set", - start, end - ); - Err(Error::new(start_span, message)) - }, - std::cmp::Ordering::Less => { - let message = format!("Invalid version range: {} must be greater than {}", start, end); - Err(Error::new(end_span, message)) - }, - - std::cmp::Ordering::Greater => Ok(features[start_index..end_index].to_vec()), - } - }, - } -} - -/// Converts a version number as a float to its feature version -/// string form (e.g. 8.0 ..= llvm8-0) -fn f64_to_feature_string(float: f64) -> String { - let int = float as u64; - - format!("llvm{}-{}", int, (float * 10.) % 10.) -} - -/// This struct defines the type of version expressions parsable by `llvm_versions` -#[derive(Debug)] -enum VersionType { - Specific(f64, Span), - InclusiveRange((f64, Span), (f64, Span)), - InclusiveRangeToLatest(f64, Span), - ExclusiveRange((f64, Span), (f64, Span)), - ExclusiveRangeToLatest(f64, Span), -} -impl Parse for VersionType { - fn parse(input: ParseStream) -> Result { - // We use lookahead to produce better syntax errors - let lookahead = input.lookahead1(); - // All version specifiers begin with a float - if lookahead.peek(LitFloat) { - let from = input.parse::().unwrap(); - let from_val = from.base10_parse().unwrap(); - // If that's the end of the input, this was a specific version string - if input.is_empty() { - return Ok(VersionType::Specific(from_val, from.span())); - } - // If the next token is ..= it is an inclusive range, .. is exclusive - // In both cases the right-hand operand must be either a float or an ident, `latest` - let lookahead = input.lookahead1(); - if lookahead.peek(Token![..=]) { - let _: Token![..=] = input.parse().unwrap(); - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) { - let to = input.parse::().unwrap(); - if to == "latest" { - Ok(VersionType::InclusiveRangeToLatest(from_val, from.span())) - } else { - Err(Error::new(to.span(), "expected `latest` or `X.Y`")) - } - } else if lookahead.peek(LitFloat) { - let to = input.parse::().unwrap(); - let to_val = to.base10_parse().unwrap(); - Ok(VersionType::InclusiveRange( - (from_val, from.span()), - (to_val, to.span()), - )) - } else { - Err(lookahead.error()) - } - } else if lookahead.peek(Token![..]) { - let _: Token![..] = input.parse().unwrap(); - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) { - let to = input.parse::().unwrap(); - if to == "latest" { - Ok(VersionType::ExclusiveRangeToLatest(from_val, from.span())) - } else { - Err(Error::new(to.span(), "expected `latest` or `X.Y`")) - } - } else if lookahead.peek(LitFloat) { - let to = input.parse::().unwrap(); - let to_val = to.base10_parse().unwrap(); - Ok(VersionType::ExclusiveRange( - (from_val, from.span()), - (to_val, to.span()), - )) - } else { - Err(lookahead.error()) - } - } else { - Err(lookahead.error()) - } - } else { - Err(lookahead.error()) - } - } -} - -/// Handler for parsing of TokenStreams contained in item attributes -#[derive(Debug)] -struct ParenthesizedFeatureSet(FeatureSet); -impl Parse for ParenthesizedFeatureSet { - fn parse(input: ParseStream) -> Result { - input.parse::().map(Self) - } -} - -/// Handler for parsing of TokenStreams from macro input -#[derive(Clone, Debug)] -struct FeatureSet(std::vec::IntoIter<&'static str>, Option); -impl Default for FeatureSet { - fn default() -> Self { - // Default to all versions - #[allow(clippy::unnecessary_to_owned)] // Falsely fires since array::IntoIter != vec::IntoIter - Self(FEATURE_VERSIONS.to_vec().into_iter(), None) - } -} -impl Parse for FeatureSet { - fn parse(input: ParseStream) -> Result { - let version_type = input.parse::()?; - let features = get_features(version_type)?; - Ok(Self(features.into_iter(), None)) - } -} -impl Iterator for FeatureSet { - type Item = &'static str; - - fn next(&mut self) -> Option { - self.0.next() - } -} -impl FeatureSet { - #[inline] - fn has_error(&self) -> bool { - self.1.is_some() - } - - #[inline] - fn set_error(&mut self, err: Error) { - self.1 = Some(err); - } - - fn into_error(self) -> Error { - self.1.unwrap() - } - - fn into_compile_error(self) -> TokenStream { - TokenStream::from(self.1.unwrap().to_compile_error()) - } - - fn expand_llvm_versions_attr(&mut self, attr: &Attribute) -> Attribute { - // Make no modifications if we've generated an error - if self.has_error() { - return attr.clone(); - } - - // If this isn't an llvm_versions attribute, skip it - if !attr.path().is_ident("llvm_versions") { - return attr.clone(); - } - - // Expand from llvm_versions to raw cfg attribute - match attr.parse_args() { - Ok(ParenthesizedFeatureSet(features)) => { - parse_quote! { - #[cfg(any(#(feature = #features),*))] - } - }, - Err(err) => { - // We've hit an error, but we can't break out yet, - // so we set the error in the FeatureSet state and - // avoid any further modifications until we can produce - // the error - self.set_error(err); - attr.clone() - }, - } - } -} -impl Fold for FeatureSet { - fn fold_variant(&mut self, mut variant: Variant) -> Variant { - if self.has_error() { - return variant; - } - - let attrs = variant - .attrs - .iter() - .map(|attr| self.expand_llvm_versions_attr(attr)) - .collect::>(); - variant.attrs = attrs; - variant - } - - fn fold_field(&mut self, mut field: Field) -> Field { - if self.has_error() { - return field; - } - - let attrs = field - .attrs - .iter() - .map(|attr| self.expand_llvm_versions_attr(attr)) - .collect::>(); - field.attrs = attrs; - field - } -} +mod cfg; +mod r#enum; /// This macro can be used to specify version constraints for an enum/struct/union or /// other item which can be decorated with an attribute. /// +/// It takes one argument which is any range of major or `major.minor` LLVM versions. +/// /// To use with enum variants or struct fields, you need to decorate the parent item with /// the `#[llvm_versioned_item]` attribute, as this is the hook we need to modify the AST -/// of those items +/// of those items. /// /// # Examples /// /// ```ignore -/// // Inclusive range from 3.6 up to and including 3.9 -/// #[llvm_versions(3.6..=3.9)] +/// // Inclusive range from 15 up to and including 18. +/// #[llvm_versions(15..=18)] /// -/// // Exclusive range from 3.6 up to but not including 4.0 -/// #[llvm_versions(3.6..4.0)] +/// // Exclusive range from 15 up to but not including 18. +/// #[llvm_versions(15..18)] /// -/// // Inclusive range from 3.6 up to and including the latest release -/// #[llvm_versions(3.6..=latest)] +/// // Inclusive range from 15.1 up to and including the latest release. +/// #[llvm_versions(15.1..)] /// ``` #[proc_macro_attribute] -pub fn llvm_versions(attribute_args: TokenStream, attributee: TokenStream) -> TokenStream { - let mut features = parse_macro_input!(attribute_args as FeatureSet); - - let attributee = parse_macro_input!(attributee as Item); - let folded = features.fold_item(attributee); - - if features.has_error() { - return features.into_compile_error(); - } - - // Add nightly only doc cfgs to improve documentation on nightly builds - // such as our own hosted docs. - let doc = if cfg!(feature = "nightly") { - let features2 = features.clone(); - quote! { - #[doc(cfg(any(#(feature = #features2),*)))] - } - } else { - quote! {} - }; - - let q = quote! { - #[cfg(any(#(feature = #features),*))] - #doc - #folded - }; - - q.into() +pub fn llvm_versions(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args as cfg::VersionRange); + cfg::expand(Some(args), input) } /// This attribute is used to decorate enums, structs, or unions which may contain @@ -359,142 +50,9 @@ pub fn llvm_versions(attribute_args: TokenStream, attributee: TokenStream) -> To /// } /// ``` #[proc_macro_attribute] -pub fn llvm_versioned_item(_attribute_args: TokenStream, attributee: TokenStream) -> TokenStream { - let attributee = parse_macro_input!(attributee as Item); - - let mut features = FeatureSet::default(); - let folded = features.fold_item(attributee); - - if features.has_error() { - return features.into_compile_error(); - } - - quote!(#folded).into() -} - -/// Used to track an enum variant and its corresponding mappings (LLVM <-> Rust), -/// as well as attributes -struct EnumVariant { - llvm_variant: Ident, - rust_variant: Ident, - attrs: Vec, -} -impl EnumVariant { - fn new(variant: &Variant) -> Self { - let rust_variant = variant.ident.clone(); - let llvm_variant = Ident::new(&format!("LLVM{}", rust_variant), variant.span()); - let mut attrs = variant.attrs.clone(); - attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); - Self { - llvm_variant, - rust_variant, - attrs, - } - } - - fn with_name(variant: &Variant, mut llvm_variant: Ident) -> Self { - let rust_variant = variant.ident.clone(); - llvm_variant.set_span(rust_variant.span()); - let mut attrs = variant.attrs.clone(); - attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); - Self { - llvm_variant, - rust_variant, - attrs, - } - } -} - -/// Used when constructing the variants of an enum declaration. -#[derive(Default)] -struct EnumVariants { - variants: Vec, - error: Option, -} -impl EnumVariants { - #[inline] - fn len(&self) -> usize { - self.variants.len() - } - - #[inline] - fn iter(&self) -> core::slice::Iter<'_, EnumVariant> { - self.variants.iter() - } - - #[inline] - fn has_error(&self) -> bool { - self.error.is_some() - } - - #[inline] - fn set_error(&mut self, err: &str, span: Span) { - self.error = Some(Error::new(span, err)); - } - - fn into_error(self) -> Error { - self.error.unwrap() - } -} -impl Fold for EnumVariants { - fn fold_variant(&mut self, mut variant: Variant) -> Variant { - use syn::Meta; - - if self.has_error() { - return variant; - } - - // Check for llvm_variant - if let Some(attr) = variant.attrs.iter().find(|attr| attr.path().is_ident("llvm_variant")) { - // Extract attribute meta - if let Meta::List(meta) = &attr.meta { - // We should only have one element - - if let Ok(Meta::Path(name)) = meta.parse_args() { - self.variants - .push(EnumVariant::with_name(&variant, name.get_ident().unwrap().clone())); - // Strip the llvm_variant attribute from the final AST - variant.attrs.retain(|attr| !attr.path().is_ident("llvm_variant")); - return variant; - } - } - - // If at any point we fall through to here, it is the same basic issue, invalid format - self.set_error("expected #[llvm_variant(VARIANT_NAME)]", attr.span()); - return variant; - } - - self.variants.push(EnumVariant::new(&variant)); - variant - } -} - -/// Used to parse an enum declaration decorated with `#[llvm_enum(..)]` -struct LLVMEnumType { - name: Ident, - decl: syn::ItemEnum, - variants: EnumVariants, -} -impl Parse for LLVMEnumType { - fn parse(input: ParseStream) -> Result { - // Parse enum declaration - let decl = input.parse::()?; - let name = decl.ident.clone(); - // Fold over variants and expand llvm_versions - let mut features = FeatureSet::default(); - let decl = features.fold_item_enum(decl); - if features.has_error() { - return Err(features.into_error()); - } - - let mut variants = EnumVariants::default(); - let decl = variants.fold_item_enum(decl); - if variants.has_error() { - return Err(variants.into_error()); - } - - Ok(Self { name, decl, variants }) - } +pub fn llvm_versioned_item(args: TokenStream, input: TokenStream) -> TokenStream { + parse_macro_input!(args as syn::parse::Nothing); + cfg::expand(None, input) } /// This attribute macro allows you to decorate an enum declaration which represents @@ -512,7 +70,7 @@ impl Parse for LLVMEnumType { /// #[llvm_enum(LLVMOpcode)] /// enum InstructionOpcode { /// Call, -/// #[llvm_versions(3.8..=latest)] +/// #[llvm_versions(3.8..)] /// CatchPad, /// ..., /// #[llvm_variant(LLVMRet)] @@ -526,92 +84,9 @@ impl Parse for LLVMEnumType { /// to. In the above example, `Ret` was deemed unnecessarily concise, so the /// source variant is named `Return` and mapped manually to `LLVMRet`. #[proc_macro_attribute] -pub fn llvm_enum(attribute_args: TokenStream, attributee: TokenStream) -> TokenStream { - use syn::{Arm, PatPath, Path}; - +pub fn llvm_enum(args: TokenStream, input: TokenStream) -> TokenStream { // Expect something like #[llvm_enum(LLVMOpcode)] - let llvm_ty = parse_macro_input!(attribute_args as Path); - let llvm_enum_type = parse_macro_input!(attributee as LLVMEnumType); - - // Construct match arms for LLVM -> Rust enum conversion - let mut from_arms = Vec::with_capacity(llvm_enum_type.variants.len()); - for variant in llvm_enum_type.variants.iter() { - let src_variant = variant.llvm_variant.clone(); - // Filter out doc comments or else rustc will warn about docs on match arms in newer versions. - let src_attrs: Vec<_> = variant - .attrs - .iter() - .filter(|&attr| !attr.meta.path().is_ident("doc")) - .collect(); - let src_ty = llvm_ty.clone(); - let dst_variant = variant.rust_variant.clone(); - let dst_ty = llvm_enum_type.name.clone(); - - let pat = PatPath { - attrs: Vec::new(), - qself: None, - path: parse_quote!(#src_ty::#src_variant), - }; - - let arm: Arm = parse_quote! { - #(#src_attrs)* - #pat => { #dst_ty::#dst_variant } - }; - from_arms.push(arm); - } - - // Construct match arms for Rust -> LLVM enum conversion - let mut to_arms = Vec::with_capacity(llvm_enum_type.variants.len()); - for variant in llvm_enum_type.variants.iter() { - let src_variant = variant.rust_variant.clone(); - // Filter out doc comments or else rustc will warn about docs on match arms in newer versions. - let src_attrs: Vec<_> = variant - .attrs - .iter() - .filter(|&attr| !attr.meta.path().is_ident("doc")) - .collect(); - let src_ty = llvm_enum_type.name.clone(); - let dst_variant = variant.llvm_variant.clone(); - let dst_ty = llvm_ty.clone(); - - let pat = PatPath { - attrs: Vec::new(), - qself: None, - path: parse_quote!(#src_ty::#src_variant), - }; - - let arm: Arm = parse_quote! { - #(#src_attrs)* - #pat => { #dst_ty::#dst_variant } - }; - to_arms.push(arm); - } - - let enum_ty = llvm_enum_type.name.clone(); - let enum_decl = llvm_enum_type.decl; - - let q = quote! { - #enum_decl - - impl #enum_ty { - fn new(src: #llvm_ty) -> Self { - match src { - #(#from_arms)* - } - } - } - impl From<#llvm_ty> for #enum_ty { - fn from(src: #llvm_ty) -> Self { - Self::new(src) - } - } - impl Into<#llvm_ty> for #enum_ty { - fn into(self) -> #llvm_ty { - match self { - #(#to_arms),* - } - } - } - }; - q.into() + let llvm_ty = parse_macro_input!(args as syn::Path); + let llvm_enum_type = parse_macro_input!(input as r#enum::LLVMEnumType); + r#enum::llvm_enum(llvm_ty, llvm_enum_type).into() } diff --git a/src/attributes.rs b/src/attributes.rs index 17806041217..70dec1eb631 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -4,13 +4,13 @@ use llvm_sys::core::{ LLVMGetEnumAttributeKind, LLVMGetEnumAttributeKindForName, LLVMGetEnumAttributeValue, LLVMGetLastEnumAttributeKind, LLVMGetStringAttributeKind, LLVMGetStringAttributeValue, LLVMIsEnumAttribute, LLVMIsStringAttribute, }; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use llvm_sys::core::{LLVMGetTypeAttributeValue, LLVMIsTypeAttribute}; use llvm_sys::prelude::LLVMAttributeRef; use std::ffi::CStr; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use crate::types::AnyTypeEnum; // SubTypes: Attribute, Attribute @@ -149,13 +149,13 @@ impl Attribute { /// /// assert!(type_attribute.is_type()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn is_type(self) -> bool { unsafe { LLVMIsTypeAttribute(self.attribute) == 1 } } // private function to make code elsewhere easier - #[llvm_versions(4.0..12.0)] + #[llvm_versions(..12)] fn is_type(self) -> bool { false } @@ -190,7 +190,7 @@ impl Attribute { /// /// assert_eq!(enum_attribute.get_enum_kind_id(), 0); /// ``` - #[llvm_versions(4.0..=11.0)] + #[llvm_versions(..=11)] pub fn get_enum_kind_id(self) -> u32 { assert!(self.get_enum_kind_id_is_valid()); // FIXME: SubTypes @@ -227,19 +227,19 @@ impl Attribute { /// /// assert_eq!(type_attribute.get_enum_kind_id(), kind_id); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_enum_kind_id(self) -> u32 { assert!(self.get_enum_kind_id_is_valid()); // FIXME: SubTypes unsafe { LLVMGetEnumAttributeKind(self.attribute) } } - #[llvm_versions(4.0..=11.0)] + #[llvm_versions(..=11)] fn get_enum_kind_id_is_valid(self) -> bool { self.is_enum() } - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn get_enum_kind_id_is_valid(self) -> bool { self.is_enum() || self.is_type() } @@ -339,7 +339,7 @@ impl Attribute { /// assert_eq!(type_attribute.get_type_value(), any_type); /// assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_type_value(&self) -> AnyTypeEnum { assert!(self.is_type()); // FIXME: SubTypes @@ -347,7 +347,7 @@ impl Attribute { } // private function to make code elsewhere easier - #[llvm_versions(4.0..12.0)] + #[llvm_versions(..12)] fn get_type_value(&self) { unreachable!("not implemented in this version") } diff --git a/src/builder.rs b/src/builder.rs index dd75ac22d3d..9455134030d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -19,30 +19,30 @@ use llvm_sys::core::{ LLVMInsertIntoBuilderWithName, LLVMPositionBuilder, LLVMPositionBuilderAtEnd, LLVMPositionBuilderBefore, LLVMSetCleanup, }; -#[llvm_versions(4.0..=14.0)] +#[llvm_versions(..=14)] use llvm_sys::core::{ LLVMBuildCall, LLVMBuildGEP, LLVMBuildInBoundsGEP, LLVMBuildInvoke, LLVMBuildLoad, LLVMBuildPtrDiff, LLVMBuildStructGEP, }; -#[llvm_versions(15.0..=latest)] +#[llvm_versions(15..)] use llvm_sys::core::{ LLVMBuildCall2, LLVMBuildGEP2, LLVMBuildInBoundsGEP2, LLVMBuildInvoke2, LLVMBuildLoad2, LLVMBuildPtrDiff2, LLVMBuildStructGEP2, }; -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use llvm_sys::core::{LLVMBuildIntCast2, LLVMBuildMemCpy, LLVMBuildMemMove, LLVMBuildMemSet}; use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef}; use thiserror::Error; use crate::basic_block::BasicBlock; -#[llvm_versions(7.0..=8.0)] +#[llvm_versions(7..=8)] use crate::context::AsContextRef; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::debug_info::DILocation; use crate::support::to_c_str; use crate::types::{AsTypeRef, BasicType, FloatMathType, FunctionType, IntMathType, PointerMathType, PointerType}; -#[llvm_versions(4.0..=14.0)] +#[llvm_versions(..=14)] use crate::values::CallableValue; use crate::values::{ AggregateValue, AggregateValueEnum, AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, @@ -218,7 +218,7 @@ impl<'ctx> Builder<'ctx> { /// /// builder.build_return(Some(&ret_val)).unwrap(); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_call( &self, function: F, @@ -254,7 +254,7 @@ impl<'ctx> Builder<'ctx> { } /// Builds a function call instruction. Alias for [Builder::build_direct_call]. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_call( &self, function: FunctionValue<'ctx>, @@ -295,7 +295,7 @@ impl<'ctx> Builder<'ctx> { /// /// builder.build_return(Some(&ret_val)).unwrap(); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_direct_call( &self, function: FunctionValue<'ctx>, @@ -338,7 +338,7 @@ impl<'ctx> Builder<'ctx> { /// builder.build_return(Some(&ret_val)).unwrap(); /// ``` /// - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_indirect_call( &self, function_type: FunctionType<'ctx>, @@ -352,7 +352,7 @@ impl<'ctx> Builder<'ctx> { self.build_call_help(function_type, function_pointer.as_value_ref(), args, name) } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] fn build_call_help( &self, function_type: FunctionType<'ctx>, @@ -470,7 +470,7 @@ impl<'ctx> Builder<'ctx> { /// builder.build_return(Some(&f32_type.const_zero())).unwrap(); /// } /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_invoke( &self, function: F, @@ -588,7 +588,7 @@ impl<'ctx> Builder<'ctx> { /// builder.build_return(Some(&f32_type.const_zero())).unwrap(); /// } /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_invoke( &self, function: FunctionValue<'ctx>, @@ -603,7 +603,7 @@ impl<'ctx> Builder<'ctx> { self.build_direct_invoke(function, args, then_block, catch_block, name) } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_direct_invoke( &self, function: FunctionValue<'ctx>, @@ -625,7 +625,7 @@ impl<'ctx> Builder<'ctx> { ) } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_indirect_invoke( &self, function_type: FunctionType<'ctx>, @@ -648,7 +648,7 @@ impl<'ctx> Builder<'ctx> { ) } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] fn build_invoke_help( &self, fn_ty: FunctionType<'ctx>, @@ -961,7 +961,7 @@ impl<'ctx> Builder<'ctx> { // REVIEW: Doesn't GEP work on array too? /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub unsafe fn build_gep( &self, ptr: PointerValue<'ctx>, @@ -988,7 +988,7 @@ impl<'ctx> Builder<'ctx> { // REVIEW: Doesn't GEP work on array too? /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub unsafe fn build_gep>( &self, pointee_ty: T, @@ -1018,7 +1018,7 @@ impl<'ctx> Builder<'ctx> { // REVIEW: Doesn't GEP work on array too? // REVIEW: This could be merge in with build_gep via a in_bounds: bool param /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub unsafe fn build_in_bounds_gep( &self, ptr: PointerValue<'ctx>, @@ -1046,7 +1046,7 @@ impl<'ctx> Builder<'ctx> { // REVIEW: Doesn't GEP work on array too? // REVIEW: This could be merge in with build_gep via a in_bounds: bool param /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub unsafe fn build_in_bounds_gep>( &self, pointee_ty: T, @@ -1109,7 +1109,7 @@ impl<'ctx> Builder<'ctx> { /// assert!(builder.build_struct_gep(struct_ptr, 1, "struct_gep").is_ok()); /// assert!(builder.build_struct_gep(struct_ptr, 2, "struct_gep").is_err()); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_struct_gep( &self, ptr: PointerValue<'ctx>, @@ -1175,7 +1175,7 @@ impl<'ctx> Builder<'ctx> { /// assert!(builder.build_struct_gep(struct_ty, struct_ptr, 1, "struct_gep").is_ok()); /// assert!(builder.build_struct_gep(struct_ty, struct_ptr, 2, "struct_gep").is_err()); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_struct_gep>( &self, pointee_ty: T, @@ -1241,7 +1241,7 @@ impl<'ctx> Builder<'ctx> { /// builder.build_ptr_diff(i32_ptr_param1, i32_ptr_param2, "diff").unwrap(); /// builder.build_return(None).unwrap(); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_ptr_diff( &self, lhs_ptr: PointerValue<'ctx>, @@ -1292,7 +1292,7 @@ impl<'ctx> Builder<'ctx> { /// builder.build_ptr_diff(i32_ptr_type, i32_ptr_param1, i32_ptr_param2, "diff").unwrap(); /// builder.build_return(None).unwrap(); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_ptr_diff>( &self, pointee_ty: T, @@ -1402,7 +1402,7 @@ impl<'ctx> Builder<'ctx> { /// /// builder.build_return(Some(&pointee)).unwrap(); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn build_load(&self, ptr: PointerValue<'ctx>, name: &str) -> Result, BuilderError> { if self.positioned.get() != PositionState::Set { return Err(BuilderError::UnsetPosition); @@ -1442,7 +1442,7 @@ impl<'ctx> Builder<'ctx> { /// /// builder.build_return(Some(&pointee)).unwrap(); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn build_load>( &self, pointee_ty: T, @@ -1504,7 +1504,7 @@ impl<'ctx> Builder<'ctx> { /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn build_memcpy( &self, dest: PointerValue<'ctx>, @@ -1552,7 +1552,7 @@ impl<'ctx> Builder<'ctx> { /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2 under 2^64. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn build_memmove( &self, dest: PointerValue<'ctx>, @@ -1600,7 +1600,7 @@ impl<'ctx> Builder<'ctx> { /// Returns an `Err(BuilderError::AlignmentError)` if the source alignment is not a power of 2 under 2^64. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn build_memset( &self, dest: PointerValue<'ctx>, @@ -2161,7 +2161,7 @@ impl<'ctx> Builder<'ctx> { } /// Like `build_int_cast`, but respects the signedness of the type being cast to. - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn build_int_cast_sign_flag>( &self, int: T, @@ -3429,7 +3429,7 @@ impl<'ctx> Builder<'ctx> { } /// Set the debug info source location of the instruction currently pointed at by the builder - #[llvm_versions(7.0..=8.0)] + #[llvm_versions(7..=8)] pub fn set_current_debug_location(&self, context: impl AsContextRef<'ctx>, location: DILocation<'ctx>) { use llvm_sys::core::LLVMMetadataAsValue; use llvm_sys::core::LLVMSetCurrentDebugLocation; @@ -3442,7 +3442,7 @@ impl<'ctx> Builder<'ctx> { } /// Set the debug info source location of the instruction currently pointed at by the builder - #[llvm_versions(9.0..=latest)] + #[llvm_versions(9..)] pub fn set_current_debug_location(&self, location: DILocation<'ctx>) { use llvm_sys::core::LLVMSetCurrentDebugLocation2; unsafe { @@ -3452,7 +3452,7 @@ impl<'ctx> Builder<'ctx> { /// Get the debug info source location of the instruction currently pointed at by the builder, /// if available. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_current_debug_location(&self) -> Option> { use llvm_sys::core::LLVMGetCurrentDebugLocation; use llvm_sys::core::LLVMValueAsMetadata; @@ -3468,7 +3468,7 @@ impl<'ctx> Builder<'ctx> { /// Unset the debug info source location of the instruction currently pointed at by the /// builder. If there isn't any debug info, this is a no-op. - #[llvm_versions(7.0..=8.0)] + #[llvm_versions(7..=8)] pub fn unset_current_debug_location(&self) { use llvm_sys::core::LLVMSetCurrentDebugLocation; unsafe { @@ -3478,7 +3478,7 @@ impl<'ctx> Builder<'ctx> { /// Unset the debug info source location of the instruction currently pointed at by the /// builder. If there isn't any debug info, this is a no-op. - #[llvm_versions(9.0..=latest)] + #[llvm_versions(9..)] pub fn unset_current_debug_location(&self) { use llvm_sys::core::LLVMSetCurrentDebugLocation2; unsafe { @@ -3488,7 +3488,7 @@ impl<'ctx> Builder<'ctx> { } /// Used by build_memcpy and build_memmove -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] fn is_alignment_ok(align: u32) -> bool { // This replicates the assertions LLVM runs. // diff --git a/src/context.rs b/src/context.rs index cc7d3b30244..d8043df6272 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,19 +1,19 @@ //! A `Context` is an opaque owner and manager of core global data. -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::InlineAsmDialect; use libc::c_void; -#[llvm_versions(4.0..=6.0)] +#[llvm_versions(..=6)] use llvm_sys::core::LLVMConstInlineAsm; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use llvm_sys::core::LLVMCreateTypeAttribute; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::core::LLVMGetInlineAsm; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use llvm_sys::core::LLVMGetTypeByName2; -#[llvm_versions(6.0..=latest)] +#[llvm_versions(6..)] use llvm_sys::core::LLVMMetadataTypeInContext; -#[llvm_versions(15.0..=latest)] +#[llvm_versions(15..)] use llvm_sys::core::LLVMPointerTypeInContext; use llvm_sys::core::{ LLVMAppendBasicBlockInContext, LLVMConstStringInContext, LLVMConstStructInContext, LLVMContextCreate, @@ -38,9 +38,9 @@ use crate::memory_buffer::MemoryBuffer; use crate::module::Module; use crate::support::{to_c_str, LLVMString}; use crate::targets::TargetData; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use crate::types::AnyTypeEnum; -#[llvm_versions(6.0..=latest)] +#[llvm_versions(6..)] use crate::types::MetadataType; use crate::types::{AsTypeRef, BasicTypeEnum, FloatType, FunctionType, IntType, PointerType, StructType, VoidType}; use crate::values::{ @@ -204,7 +204,7 @@ impl ContextImpl { unsafe { IntType::new(LLVMIntTypeInContext(self.0, bits)) } } - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] fn metadata_type<'ctx>(&self) -> MetadataType<'ctx> { unsafe { MetadataType::new(LLVMMetadataTypeInContext(self.0)) } } @@ -244,7 +244,7 @@ impl ContextImpl { unsafe { FloatType::new(LLVMPPCFP128TypeInContext(self.0)) } } - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] fn ptr_type<'ctx>(&self, address_space: AddressSpace) -> PointerType<'ctx> { unsafe { PointerType::new(LLVMPointerTypeInContext(self.0, address_space.0)) } } @@ -267,7 +267,7 @@ impl ContextImpl { unsafe { StructType::new(LLVMStructCreateNamed(self.0, c_string.as_ptr())) } } - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn get_struct_type<'ctx>(&self, name: &str) -> Option> { let c_string = to_c_str(name); @@ -365,7 +365,7 @@ impl ContextImpl { } } - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute { unsafe { Attribute::new(LLVMCreateTypeAttribute(self.0, kind_id, type_ref.as_type_ref())) } } @@ -785,7 +785,7 @@ impl Context { /// assert_eq!(md_type.get_context(), context); /// ``` #[inline] - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn metadata_type(&self) -> MetadataType { self.context.metadata_type() } @@ -938,7 +938,7 @@ impl Context { /// assert_eq!(ptr_type.get_address_space(), AddressSpace::default()); /// assert_eq!(ptr_type.get_context(), context); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] #[inline] pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType { self.context.ptr_type(address_space) @@ -999,7 +999,7 @@ impl Context { /// assert_eq!(context.get_struct_type("foo").unwrap(), opaque); /// ``` #[inline] - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_struct_type<'ctx>(&self, name: &str) -> Option> { self.context.get_struct_type(name) } @@ -1267,7 +1267,7 @@ impl Context { /// assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum()); /// ``` #[inline] - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute { self.context.create_type_attribute(kind_id, type_ref) } @@ -1653,7 +1653,7 @@ impl<'ctx> ContextRef<'ctx> { /// assert_eq!(md_type.get_context(), context); /// ``` #[inline] - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn metadata_type(&self) -> MetadataType<'ctx> { self.context.metadata_type() } @@ -1806,7 +1806,7 @@ impl<'ctx> ContextRef<'ctx> { /// assert_eq!(ptr_type.get_address_space(), AddressSpace::default()); /// assert_eq!(ptr_type.get_context(), context); /// ``` - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] #[inline] pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'ctx> { self.context.ptr_type(address_space) @@ -1867,7 +1867,7 @@ impl<'ctx> ContextRef<'ctx> { /// assert_eq!(context.get_struct_type("foo").unwrap(), opaque); /// ``` #[inline] - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_struct_type(&self, name: &str) -> Option> { self.context.get_struct_type(name) } @@ -2124,7 +2124,7 @@ impl<'ctx> ContextRef<'ctx> { /// assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum()); /// ``` #[inline] - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute { self.context.create_type_attribute(kind_id, type_ref) } diff --git a/src/debug_info.rs b/src/debug_info.rs index cce7829b0b0..eda78402231 100644 --- a/src/debug_info.rs +++ b/src/debug_info.rs @@ -108,7 +108,7 @@ use crate::values::{AsValueRef, BasicValueEnum, InstructionValue, MetadataValue, use crate::AddressSpace; use llvm_sys::core::LLVMMetadataAsValue; -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use llvm_sys::debuginfo::LLVMDIBuilderCreateTypedef; pub use llvm_sys::debuginfo::LLVMDWARFTypeEncoding; use llvm_sys::debuginfo::LLVMDebugMetadataVersion; @@ -127,7 +127,7 @@ use llvm_sys::debuginfo::{ LLVMDIBuilderInsertDeclareBefore, LLVMDILocationGetColumn, LLVMDILocationGetLine, LLVMDILocationGetScope, LLVMDITypeGetAlignInBits, LLVMDITypeGetOffsetInBits, LLVMDITypeGetSizeInBits, }; -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use llvm_sys::debuginfo::{LLVMDIBuilderCreateConstantValueExpression, LLVMDIBuilderCreateGlobalVariableExpression}; use llvm_sys::prelude::{LLVMDIBuilderRef, LLVMMetadataRef}; use std::convert::TryInto; @@ -510,7 +510,7 @@ impl<'ctx> DebugInfoBuilder<'ctx> { /// Create a primitive basic type. `encoding` is an unsigned int flag (`DW_ATE_*` /// enum) defined by the chosen DWARF standard. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn create_basic_type( &self, name: &str, @@ -541,7 +541,7 @@ impl<'ctx> DebugInfoBuilder<'ctx> { } /// Create a typedef (alias) of `ditype` - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn create_typedef( &self, ditype: DIType<'ctx>, @@ -790,7 +790,7 @@ impl<'ctx> DebugInfoBuilder<'ctx> { } } - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn create_global_variable_expression( &self, scope: DIScope<'ctx>, @@ -829,7 +829,7 @@ impl<'ctx> DebugInfoBuilder<'ctx> { } } - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn create_constant_expression(&self, value: i64) -> DIExpression<'ctx> { let metadata_ref = unsafe { LLVMDIBuilderCreateConstantValueExpression(self.builder, value as _) }; @@ -1388,7 +1388,7 @@ mod flags { const PUBLIC: Self; const FWD_DECL: Self; const APPLE_BLOCK: Self; - //#[llvm_versions(7.0..=9.0)] + //#[llvm_versions(7..=9)] //const BLOCK_BYREF_STRUCT: Self; const VIRTUAL: Self; const ARTIFICIAL: Self; @@ -1407,24 +1407,24 @@ mod flags { const INTRODUCED_VIRTUAL: Self; const BIT_FIELD: Self; const NO_RETURN: Self; - //#[llvm_versions(7.0..=8.0)] + //#[llvm_versions(7..=8)] //const MAIN_SUBPROGRAM: Self; const TYPE_PASS_BY_VALUE: Self; const TYPE_PASS_BY_REFERENCE: Self; - //#[llvm_versions(7.0)] + //#[llvm_versions(7)] //const FIXED_ENUM: Self; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const ENUM_CLASS: Self; const THUNK: Self; - //#[llvm_versions(7.0..=8.0)] + //#[llvm_versions(7..=8)] //const TRIVIAL: Self; - //#[llvm_versions(9.0..=latest)] + //#[llvm_versions(9..)] //const NON_TRIVIAL: Self; - //#[llvm_versions(10.0)] + //#[llvm_versions(10)] //const RESERVED_BIT4: Self; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const BIGE_NDIAN: Self; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const LITTLE_ENDIAN: Self; const INDIRECT_VIRTUAL_BASE: Self; } @@ -1435,7 +1435,7 @@ mod flags { const PUBLIC: DIFlags = llvm_sys::debuginfo::LLVMDIFlagPublic; const FWD_DECL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagFwdDecl; const APPLE_BLOCK: DIFlags = llvm_sys::debuginfo::LLVMDIFlagAppleBlock; - //#[llvm_versions(7.0..=9.0)] + //#[llvm_versions(7..=9)] //const BLOCK_BYREF_STRUCT: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBlockByrefStruct; const VIRTUAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagVirtual; const ARTIFICIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagArtificial; @@ -1454,24 +1454,24 @@ mod flags { const INTRODUCED_VIRTUAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagIntroducedVirtual; const BIT_FIELD: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBitField; const NO_RETURN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagNoReturn; - //#[llvm_versions(7.0..=8.0)] + //#[llvm_versions(7..=8)] //const MAIN_SUBPROGRAM: DIFlags = llvm_sys::debuginfo::LLVMDIFlagMainSubprogram; const TYPE_PASS_BY_VALUE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTypePassByValue; const TYPE_PASS_BY_REFERENCE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTypePassByReference; - //#[llvm_versions(7.0)] + //#[llvm_versions(7)] //const FIXED_ENUM: DIFlags = llvm_sys::debuginfo::LLVMDIFlagFixedEnum; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const ENUM_CLASS: DIFlags = llvm_sys::debuginfo::LLVMDIFlagEnumClass; const THUNK: DIFlags = llvm_sys::debuginfo::LLVMDIFlagThunk; - //#[llvm_versions(7.0..=8.0)] + //#[llvm_versions(7..=8)] //const TRIVIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagTrivial; - //#[llvm_versions(9.0..=latest)] + //#[llvm_versions(9..)] //const NON_TRIVIAL: DIFlags = llvm_sys::debuginfo::LLVMDIFlagNonTrivial; - //#[llvm_versions(10.0)] + //#[llvm_versions(10)] //const RESERVED_BIT4: DIFlags = llvm_sys::debuginfo::LLVMDIFlagReservedBit4; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const BIG_ENDIAN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagBigEndian; - //#[llvm_versions(8.0..=latest)] + //#[llvm_versions(8..)] //const LITTLE_ENDIAN: DIFlags = llvm_sys::debuginfo::LLVMDIFlagLittleEndian; const INDIRECT_VIRTUAL_BASE: DIFlags = llvm_sys::debuginfo::LLVMDIFlagIndirectVirtualBase; } @@ -1572,34 +1572,34 @@ mod flags { GOOGLERenderScript, #[llvm_variant(LLVMDWARFSourceLanguageBORLAND_Delphi)] BORLANDDelphi, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageKotlin)] Kotlin, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageZig)] Zig, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageCrystal)] Crystal, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_17)] CPlusPlus17, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageC_plus_plus_20)] CPlusPlus20, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageC17)] C17, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageFortran18)] Fortran18, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageAda2005)] Ada2005, - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] #[llvm_variant(LLVMDWARFSourceLanguageAda2012)] Ada2012, - #[llvm_versions(17.0..=latest)] + #[llvm_versions(17..)] #[llvm_variant(LLVMDWARFSourceLanguageMojo)] Mojo, } diff --git a/src/intrinsics.rs b/src/intrinsics.rs index fa2a176088e..93dfdd1abca 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -1,4 +1,4 @@ -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] use llvm_sys::core::{LLVMGetIntrinsicDeclaration, LLVMIntrinsicIsOverloaded, LLVMLookupIntrinsicID}; use llvm_sys::prelude::LLVMTypeRef; @@ -14,7 +14,7 @@ pub struct Intrinsic { /// A wrapper around LLVM intrinsic id /// /// To call it you would need to create a declaration inside a module using [`Self::get_declaration()`]. -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] impl Intrinsic { /// Create an Intrinsic object from raw LLVM intrinsic id /// diff --git a/src/lib.rs b/src/lib.rs index 3e8edc9125c..bb7c9c1344e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,7 +78,7 @@ use llvm_sys::{ LLVMThreadLocalMode, LLVMVisibility, }; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::LLVMInlineAsmDialect; #[cfg(feature = "serde")] @@ -361,24 +361,24 @@ pub enum AtomicRMWBinOp { /// Adds to the float-typed value in memory and returns the prior value. // Although this was added in LLVM 9, it wasn't exposed to the C API // until 10.0. - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] #[llvm_variant(LLVMAtomicRMWBinOpFAdd)] FAdd, /// Subtract a float-typed value off the value in memory and returns the prior value. // Although this was added in LLVM 9, it wasn't exposed to the C API // until 10.0. - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] #[llvm_variant(LLVMAtomicRMWBinOpFSub)] FSub, /// Sets memory to the greater of the two float-typed values, one provided and one from memory. Returns the value that was in memory. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] #[llvm_variant(LLVMAtomicRMWBinOpFMax)] FMax, /// Sets memory to the lesser of the two float-typed values, one provided and one from memory. Returns the value that was in memory. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] #[llvm_variant(LLVMAtomicRMWBinOpFMin)] FMin, } @@ -484,7 +484,7 @@ impl Default for DLLStorageClass { } } -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] #[llvm_enum(LLVMInlineAsmDialect)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/src/module.rs b/src/module.rs index f9de70d67f3..e5e543d81f8 100644 --- a/src/module.rs +++ b/src/module.rs @@ -4,7 +4,7 @@ use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyModule}; #[allow(deprecated)] use llvm_sys::bit_reader::LLVMParseBitcodeInContext; use llvm_sys::bit_writer::{LLVMWriteBitcodeToFile, LLVMWriteBitcodeToMemoryBuffer}; -#[llvm_versions(4.0..=14.0)] +#[llvm_versions(..=14)] use llvm_sys::core::LLVMGetTypeByName; use llvm_sys::core::{ @@ -14,18 +14,18 @@ use llvm_sys::core::{ LLVMGetNamedMetadataNumOperands, LLVMGetNamedMetadataOperands, LLVMGetTarget, LLVMPrintModuleToFile, LLVMPrintModuleToString, LLVMSetDataLayout, LLVMSetModuleIdentifier, LLVMSetTarget, }; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::core::{LLVMAddModuleFlag, LLVMGetModuleFlag}; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use llvm_sys::error::LLVMGetErrorMessage; use llvm_sys::execution_engine::{ LLVMCreateExecutionEngineForModule, LLVMCreateInterpreterForModule, LLVMCreateJITCompilerForModule, }; use llvm_sys::prelude::{LLVMModuleRef, LLVMValueRef}; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use llvm_sys::transforms::pass_builder::LLVMRunPasses; use llvm_sys::LLVMLinkage; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::LLVMModuleFlagBehavior; use std::cell::{Cell, Ref, RefCell}; @@ -37,22 +37,22 @@ use std::path::Path; use std::ptr; use std::rc::Rc; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::comdat::Comdat; use crate::context::{AsContextRef, Context, ContextRef}; use crate::data_layout::DataLayout; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::debug_info::{DICompileUnit, DWARFEmissionKind, DWARFSourceLanguage, DebugInfoBuilder}; use crate::execution_engine::ExecutionEngine; use crate::memory_buffer::MemoryBuffer; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use crate::passes::PassBuilderOptions; use crate::support::{to_c_str, LLVMString}; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use crate::targets::TargetMachine; use crate::targets::{InitializationConfig, Target, TargetTriple}; use crate::types::{AsTypeRef, BasicType, FunctionType, StructType}; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::values::BasicValue; use crate::values::{AsValueRef, FunctionValue, GlobalValue, MetadataValue}; use crate::{AddressSpace, OptimizationLevel}; @@ -356,7 +356,7 @@ impl<'ctx> Module<'ctx> { /// assert_eq!(module.get_struct_type("foo").unwrap(), opaque); /// ``` /// - #[llvm_versions(4.0..=11.0)] + #[llvm_versions(..=11)] pub fn get_struct_type(&self, name: &str) -> Option> { let c_string = to_c_str(name); @@ -385,7 +385,7 @@ impl<'ctx> Module<'ctx> { /// /// assert_eq!(module.get_struct_type("foo").unwrap(), opaque); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_struct_type(&self, name: &str) -> Option> { self.get_context().get_struct_type(name) } @@ -1238,7 +1238,7 @@ impl<'ctx> Module<'ctx> { /// assert_eq!(module.get_name().to_str(), Ok("my_mod")); /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod.rs")); /// ``` - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_source_file_name(&self) -> &CStr { use llvm_sys::core::LLVMGetSourceFileName; @@ -1265,7 +1265,7 @@ impl<'ctx> Module<'ctx> { /// assert_eq!(module.get_name().to_str(), Ok("my_mod")); /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod.rs")); /// ``` - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn set_source_file_name(&self, file_name: &str) { use llvm_sys::core::LLVMSetSourceFileName; @@ -1325,7 +1325,7 @@ impl<'ctx> Module<'ctx> { /// Gets the `Comdat` associated with a particular name. If it does not exist, it will be created. /// A new `Comdat` defaults to a kind of `ComdatSelectionKind::Any`. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_or_insert_comdat(&self, name: &str) -> Comdat { use llvm_sys::comdat::LLVMGetOrInsertComdat; @@ -1339,7 +1339,7 @@ impl<'ctx> Module<'ctx> { /// If a `BasicValue` was used to create this flag, it will be wrapped in a `MetadataValue` /// when returned from this function. // SubTypes: Might need to return Option, or MV> - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_flag(&self, key: &str) -> Option> { use llvm_sys::core::LLVMMetadataAsValue; @@ -1356,7 +1356,7 @@ impl<'ctx> Module<'ctx> { /// Append a `MetadataValue` as a module wide flag. Note that using the same key twice /// will likely invalidate the module. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn add_metadata_flag(&self, key: &str, behavior: FlagBehavior, flag: MetadataValue<'ctx>) { let md = flag.as_metadata_ref(); @@ -1374,7 +1374,7 @@ impl<'ctx> Module<'ctx> { /// Append a `BasicValue` as a module wide flag. Note that using the same key twice /// will likely invalidate the module. // REVIEW: What happens if value is not const? - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn add_basic_value_flag>(&self, key: &str, behavior: FlagBehavior, flag: BV) { use llvm_sys::core::LLVMValueAsMetadata; @@ -1392,7 +1392,7 @@ impl<'ctx> Module<'ctx> { } /// Strips and debug info from the module, if it exists. - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn strip_debug_info(&self) -> bool { use llvm_sys::debuginfo::LLVMStripModuleDebugInfo; @@ -1400,7 +1400,7 @@ impl<'ctx> Module<'ctx> { } /// Gets the version of debug metadata contained in this `Module`. - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn get_debug_metadata_version(&self) -> libc::c_uint { use llvm_sys::debuginfo::LLVMGetModuleDebugMetadataVersion; @@ -1408,7 +1408,7 @@ impl<'ctx> Module<'ctx> { } /// Creates a `DebugInfoBuilder` for this `Module`. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn create_debug_info_builder( &self, allow_unresolved: bool, @@ -1493,7 +1493,7 @@ impl<'ctx> Module<'ctx> { /// Individual passes may be specified, separated by commas. /// Full pipelines may also be invoked using default and friends. /// See opt for full reference of the Passes format. - #[llvm_versions(13.0..=latest)] + #[llvm_versions(13..)] pub fn run_passes( &self, passes: &str, @@ -1546,7 +1546,7 @@ impl Drop for Module<'_> { } } -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] #[llvm_enum(LLVMModuleFlagBehavior)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] /// Defines the operational behavior for a module wide flag. This documentation comes directly diff --git a/src/passes.rs b/src/passes.rs index b2318386cff..d0fd073dc7f 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -1,31 +1,31 @@ -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::core::LLVMGetGlobalPassRegistry; use llvm_sys::core::{ LLVMCreateFunctionPassManagerForModule, LLVMCreatePassManager, LLVMDisposePassManager, LLVMFinalizeFunctionPassManager, LLVMInitializeFunctionPassManager, LLVMRunFunctionPassManager, LLVMRunPassManager, }; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::initialization::{ LLVMInitializeAnalysis, LLVMInitializeCodeGen, LLVMInitializeCore, LLVMInitializeIPA, LLVMInitializeIPO, LLVMInitializeInstCombine, LLVMInitializeScalarOpts, LLVMInitializeTarget, LLVMInitializeTransformUtils, LLVMInitializeVectorization, }; -#[llvm_versions(4.0..=15.0)] +#[llvm_versions(..=15)] use llvm_sys::initialization::{LLVMInitializeInstrumentation, LLVMInitializeObjCARCOpts}; use llvm_sys::prelude::LLVMPassManagerRef; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::prelude::LLVMPassRegistryRef; -#[llvm_versions(10.0..=16.0)] +#[llvm_versions(10..=16)] use llvm_sys::transforms::ipo::LLVMAddMergeFunctionsPass; -#[llvm_versions(4.0..=15.0)] +#[llvm_versions(..=15)] use llvm_sys::transforms::ipo::LLVMAddPruneEHPass; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::transforms::ipo::{ LLVMAddAlwaysInlinerPass, LLVMAddConstantMergePass, LLVMAddDeadArgEliminationPass, LLVMAddFunctionAttrsPass, LLVMAddFunctionInliningPass, LLVMAddGlobalDCEPass, LLVMAddGlobalOptimizerPass, LLVMAddIPSCCPPass, LLVMAddInternalizePass, LLVMAddStripDeadPrototypesPass, LLVMAddStripSymbolsPass, }; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::transforms::pass_manager_builder::{ LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderPopulateFunctionPassManager, LLVMPassManagerBuilderPopulateModulePassManager, LLVMPassManagerBuilderRef, @@ -33,7 +33,7 @@ use llvm_sys::transforms::pass_manager_builder::{ LLVMPassManagerBuilderSetDisableUnrollLoops, LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderUseInlinerWithThreshold, }; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::transforms::scalar::{ LLVMAddAggressiveDCEPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddBasicAliasAnalysisPass, LLVMAddBitTrackingDCEPass, LLVMAddCFGSimplificationPass, LLVMAddCorrelatedValuePropagationPass, @@ -46,17 +46,17 @@ use llvm_sys::transforms::scalar::{ LLVMAddScopedNoAliasAAPass, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddVerifierPass, }; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::transforms::vectorize::{LLVMAddLoopVectorizePass, LLVMAddSLPVectorizePass}; // LLVM12 removes the ConstantPropagation pass // Users should use the InstSimplify pass instead. -#[llvm_versions(4.0..=11.0)] +#[llvm_versions(..=11)] use llvm_sys::transforms::ipo::LLVMAddIPConstantPropagationPass; -#[llvm_versions(4.0..=11.0)] +#[llvm_versions(..=11)] use llvm_sys::transforms::scalar::LLVMAddConstantPropagationPass; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use llvm_sys::transforms::pass_builder::{ LLVMCreatePassBuilderOptions, LLVMDisposePassBuilderOptions, LLVMPassBuilderOptionsRef, LLVMPassBuilderOptionsSetCallGraphProfile, LLVMPassBuilderOptionsSetDebugLogging, @@ -66,25 +66,25 @@ use llvm_sys::transforms::pass_builder::{ LLVMPassBuilderOptionsSetMergeFunctions, LLVMPassBuilderOptionsSetSLPVectorization, LLVMPassBuilderOptionsSetVerifyEach, }; -#[llvm_versions(12.0..=16.0)] +#[llvm_versions(12..=16)] use llvm_sys::transforms::scalar::LLVMAddInstructionSimplifyPass; use crate::module::Module; use crate::values::{AsValueRef, FunctionValue}; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use crate::OptimizationLevel; use std::borrow::Borrow; use std::marker::PhantomData; // REVIEW: Opt Level might be identical to targets::Option -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] #[derive(Debug)] pub struct PassManagerBuilder { pass_manager_builder: LLVMPassManagerBuilderRef, } -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] impl PassManagerBuilder { pub unsafe fn new(pass_manager_builder: LLVMPassManagerBuilderRef) -> Self { assert!(!pass_manager_builder.is_null()); @@ -198,7 +198,7 @@ impl PassManagerBuilder { /// /// pass_manager_builder.populate_lto_pass_manager(&lpm, false, false); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn populate_lto_pass_manager(&self, pass_manager: &PassManager, internalize: bool, run_inliner: bool) { use llvm_sys::transforms::pass_manager_builder::LLVMPassManagerBuilderPopulateLTOPassManager; @@ -213,7 +213,7 @@ impl PassManagerBuilder { } } -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] impl Drop for PassManagerBuilder { fn drop(&mut self) { unsafe { LLVMPassManagerBuilderDispose(self.pass_manager_builder) } @@ -324,7 +324,7 @@ impl PassManager { /// only stored to (returning the value instead), but does not currently. /// This case would be best handled when and if LLVM starts supporting multiple /// return values from functions. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn add_argument_promotion_pass(&self) { use llvm_sys::transforms::ipo::LLVMAddArgumentPromotionPass; @@ -335,13 +335,13 @@ impl PassManager { /// shared. This is useful because some passes (i.e., TraceValues) insert a lot /// of string constants into the program, regardless of whether or not an existing /// string is available. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_constant_merge_pass(&self) { unsafe { LLVMAddConstantMergePass(self.pass_manager) } } /// Discovers identical functions and collapses them. - #[llvm_versions(10.0..=16.0)] + #[llvm_versions(10..=16)] pub fn add_merge_functions_pass(&self) { unsafe { LLVMAddMergeFunctionsPass(self.pass_manager) } } @@ -353,7 +353,7 @@ impl PassManager { /// /// This pass is often useful as a cleanup pass to run after aggressive /// interprocedural passes, which add possibly-dead arguments. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_dead_arg_elimination_pass(&self) { unsafe { LLVMAddDeadArgEliminationPass(self.pass_manager) } } @@ -366,19 +366,19 @@ impl PassManager { /// less means that the pointer is only dereferenced, and not returned /// from the function or stored in a global. This pass is implemented /// as a bottom-up traversal of the call-graph. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_function_attrs_pass(&self) { unsafe { LLVMAddFunctionAttrsPass(self.pass_manager) } } /// Bottom-up inlining of functions into callees. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_function_inlining_pass(&self) { unsafe { LLVMAddFunctionInliningPass(self.pass_manager) } } /// A custom inliner that handles only functions that are marked as “always inline”. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_always_inliner_pass(&self) { unsafe { LLVMAddAlwaysInlinerPass(self.pass_manager) } } @@ -389,7 +389,7 @@ impl PassManager { /// finds all of the globals which are needed, it deletes /// whatever is left over. This allows it to delete recursive /// chunks of the program which are unreachable. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_global_dce_pass(&self) { unsafe { LLVMAddGlobalDCEPass(self.pass_manager) } } @@ -397,7 +397,7 @@ impl PassManager { /// This pass transforms simple global variables that never have /// their address taken. If obviously true, it marks read/write /// globals as constant, deletes variables only stored to, etc. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_global_optimizer_pass(&self) { unsafe { LLVMAddGlobalOptimizerPass(self.pass_manager) } } @@ -411,7 +411,7 @@ impl PassManager { /// /// In LLVM 12 and later, this instruction is replaced by the /// [`add_instruction_simplify_pass`]. - #[llvm_versions(4.0..=11.0)] + #[llvm_versions(..=11)] pub fn add_ip_constant_propagation_pass(&self) { unsafe { LLVMAddIPConstantPropagationPass(self.pass_manager) } } @@ -421,14 +421,14 @@ impl PassManager { /// call instructions if and only if the callee cannot throw /// an exception. It implements this as a bottom-up traversal /// of the call-graph. - #[llvm_versions(4.0..=15.0)] + #[llvm_versions(..=15)] pub fn add_prune_eh_pass(&self) { unsafe { LLVMAddPruneEHPass(self.pass_manager) } } /// An interprocedural variant of [Sparse Conditional Constant /// Propagation](https://llvm.org/docs/Passes.html#passes-sccp). - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_ipsccp_pass(&self) { unsafe { LLVMAddIPSCCPPass(self.pass_manager) } } @@ -437,7 +437,7 @@ impl PassManager { /// looking for a main function. If a main function is found, all /// other functions and all global variables with initializers are /// marked as internal. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_internalize_pass(&self, all_but_main: bool) { unsafe { LLVMAddInternalizePass(self.pass_manager, all_but_main as u32) } } @@ -446,7 +446,7 @@ impl PassManager { /// looking for dead declarations and removes them. Dead declarations /// are declarations of functions for which no implementation is available /// (i.e., declarations for unused library functions). - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_strip_dead_prototypes_pass(&self) { unsafe { LLVMAddStripDeadPrototypesPass(self.pass_manager) } } @@ -461,7 +461,7 @@ impl PassManager { /// so it should only be used in situations where the strip utility /// would be used, such as reducing code size or making it harder /// to reverse engineer code. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_strip_symbol_pass(&self) { unsafe { LLVMAddStripSymbolsPass(self.pass_manager) } } @@ -487,13 +487,13 @@ impl PassManager { } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_vectorize_pass(&self) { unsafe { LLVMAddLoopVectorizePass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_slp_vectorize_pass(&self) { unsafe { LLVMAddSLPVectorizePass(self.pass_manager) } } @@ -503,19 +503,19 @@ impl PassManager { /// assumes that values are dead until proven otherwise. This is /// similar to [SCCP](https://llvm.org/docs/Passes.html#passes-sccp), /// except applied to the liveness of values. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_aggressive_dce_pass(&self) { unsafe { LLVMAddAggressiveDCEPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_bit_tracking_dce_pass(&self) { unsafe { LLVMAddBitTrackingDCEPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_alignment_from_assumptions_pass(&self) { unsafe { LLVMAddAlignmentFromAssumptionsPass(self.pass_manager) } } @@ -526,25 +526,25 @@ impl PassManager { /// * Merges a basic block into its predecessor if there is only one and the predecessor only has one successor. /// * Eliminates PHI nodes for basic blocks with a single predecessor. /// * Eliminates a basic block that only contains an unconditional branch. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_cfg_simplification_pass(&self) { unsafe { LLVMAddCFGSimplificationPass(self.pass_manager) } } /// A trivial dead store elimination that only considers basic-block local redundant stores. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_dead_store_elimination_pass(&self) { unsafe { LLVMAddDeadStoreEliminationPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_scalarizer_pass(&self) { unsafe { LLVMAddScalarizerPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_merged_load_store_motion_pass(&self) { unsafe { LLVMAddMergedLoadStoreMotionPass(self.pass_manager) } } @@ -552,7 +552,7 @@ impl PassManager { /// This pass performs global value numbering to eliminate /// fully and partially redundant instructions. It also /// performs redundant load elimination. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_gvn_pass(&self) { unsafe { LLVMAddGVNPass(self.pass_manager) } } @@ -562,7 +562,7 @@ impl PassManager { /// performs redundant load elimination. // REVIEW: Is `LLVMAddGVNPass` deprecated? Should we just seamlessly replace // the old one with this one in 4.0+? - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_new_gvn_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddNewGVNPass; @@ -608,7 +608,7 @@ impl PassManager { /// the desired loop transformations have been performed. Additionally, on /// targets where it is profitable, the loop could be transformed to count /// down to zero (the "do loop" optimization). - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_ind_var_simplify_pass(&self) { unsafe { LLVMAddIndVarSimplifyPass(self.pass_manager) } } @@ -653,7 +653,7 @@ impl PassManager { /// the main() function can be transformed into simply return 3. Whether or not library /// calls are simplified is controlled by the [-functionattrs](https://llvm.org/docs/Passes.html#passes-functionattrs) /// pass and LLVM’s knowledge of library calls on different targets. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_instruction_combining_pass(&self) { unsafe { LLVMAddInstructionCombiningPass(self.pass_manager) } } @@ -677,7 +677,7 @@ impl PassManager { /// /// In this case, the unconditional branch at the end of the first /// if can be revectored to the false side of the second if. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_jump_threading_pass(&self) { unsafe { LLVMAddJumpThreadingPass(self.pass_manager) } } @@ -714,7 +714,7 @@ impl PassManager { /// and stores in the loop of the pointer to use a temporary /// alloca'd variable. We then use the mem2reg functionality /// to construct the appropriate SSA form for the variable. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_licm_pass(&self) { unsafe { LLVMAddLICMPass(self.pass_manager) } } @@ -724,25 +724,25 @@ impl PassManager { /// non-infinite computable trip counts that have no side /// effects or volatile instructions, and do not contribute /// to the computation of the function’s return value. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_deletion_pass(&self) { unsafe { LLVMAddLoopDeletionPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_idiom_pass(&self) { unsafe { LLVMAddLoopIdiomPass(self.pass_manager) } } /// A simple loop rotation transformation. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_rotate_pass(&self) { unsafe { LLVMAddLoopRotatePass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_reroll_pass(&self) { unsafe { LLVMAddLoopRerollPass(self.pass_manager) } } @@ -752,7 +752,7 @@ impl PassManager { /// by the [indvars](https://llvm.org/docs/Passes.html#passes-indvars) /// pass, allowing it to determine the trip counts /// of loops easily. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_loop_unroll_pass(&self) { unsafe { LLVMAddLoopUnrollPass(self.pass_manager) } } @@ -779,7 +779,7 @@ impl PassManager { /// to be run before it to hoist invariant conditions /// out of the loop, to make the unswitching opportunity /// obvious. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn add_loop_unswitch_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddLoopUnswitchPass; @@ -789,14 +789,14 @@ impl PassManager { /// This pass performs various transformations related /// to eliminating memcpy calls, or transforming sets /// of stores into memsets. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_memcpy_optimize_pass(&self) { unsafe { LLVMAddMemCpyOptPass(self.pass_manager) } } /// This pass performs partial inlining, typically by inlining /// an if statement that surrounds the body of the function. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_partially_inline_lib_calls_pass(&self) { unsafe { LLVMAddPartiallyInlineLibCallsPass(self.pass_manager) } } @@ -804,11 +804,11 @@ impl PassManager { /// Rewrites switch instructions with a sequence of branches, /// which allows targets to get away with not implementing the /// switch instruction until it is convenient. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_lower_switch_pass(&self) { - #[llvm_versions(4.0..=6.0)] + #[llvm_versions(..=6)] use llvm_sys::transforms::scalar::LLVMAddLowerSwitchPass; - #[llvm_versions(7.0..=16.0)] + #[llvm_versions(7..=16)] use llvm_sys::transforms::util::LLVMAddLowerSwitchPass; unsafe { LLVMAddLowerSwitchPass(self.pass_manager) } @@ -820,11 +820,11 @@ impl PassManager { /// to place phi nodes, then traversing the function in depth-first /// order to rewrite loads and stores as appropriate. This is just /// the standard SSA construction algorithm to construct "pruned" SSA form. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_promote_memory_to_register_pass(&self) { - #[llvm_versions(4.0..=6.0)] + #[llvm_versions(..=6)] use llvm_sys::transforms::scalar::LLVMAddPromoteMemoryToRegisterPass; - #[llvm_versions(7.0..=16.0)] + #[llvm_versions(7..=16)] use llvm_sys::transforms::util::LLVMAddPromoteMemoryToRegisterPass; unsafe { LLVMAddPromoteMemoryToRegisterPass(self.pass_manager) } @@ -840,7 +840,7 @@ impl PassManager { /// corresponding to the reverse post order traversal of current function /// (starting at 2), which effectively gives values in deep loops higher /// rank than values not in loops. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_reassociate_pass(&self) { unsafe { LLVMAddReassociatePass(self.pass_manager) } } @@ -855,13 +855,13 @@ impl PassManager { /// /// Note that this pass has a habit of making definitions be dead. /// It is a good idea to run a DCE pass sometime after running this pass. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_sccp_pass(&self) { unsafe { LLVMAddSCCPPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_scalar_repl_aggregates_pass(&self) { unsafe { LLVMAddScalarReplAggregatesPass(self.pass_manager) } } @@ -871,19 +871,19 @@ impl PassManager { /// (structure or array) into individual alloca instructions for each /// member if possible. Then, if possible, it transforms the individual /// alloca instructions into nice clean scalar SSA form. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_scalar_repl_aggregates_pass_ssa(&self) { unsafe { LLVMAddScalarReplAggregatesPassSSA(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_scalar_repl_aggregates_pass_with_threshold(&self, threshold: i32) { unsafe { LLVMAddScalarReplAggregatesPassWithThreshold(self.pass_manager, threshold) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_simplify_lib_calls_pass(&self) { unsafe { LLVMAddSimplifyLibCallsPass(self.pass_manager) } } @@ -908,7 +908,7 @@ impl PassManager { /// /// 4. If it can prove that callees do not access theier caller stack frame, /// they are marked as eligible for tail call elimination (by the code generator). - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_tail_call_elimination_pass(&self) { unsafe { LLVMAddTailCallEliminationPass(self.pass_manager) } } @@ -932,7 +932,7 @@ impl PassManager { /// /// In LLVM 12 and later, this instruction is replaced by the /// [`add_instruction_simplify_pass`]. - #[llvm_versions(4.0..=11.0)] + #[llvm_versions(..=11)] pub fn add_constant_propagation_pass(&self) { unsafe { LLVMAddConstantPropagationPass(self.pass_manager) } } @@ -953,7 +953,7 @@ impl PassManager { /// /// NOTE: this pass has a habit of making definitions be dead. It is a good idea to /// run a Dead Instruction Elimination pass sometime after running this pass. - #[llvm_versions(12.0..=16.0)] + #[llvm_versions(12..=16)] pub fn add_instruction_simplify_pass(&self) { unsafe { LLVMAddInstructionSimplifyPass(self.pass_manager) } } @@ -964,7 +964,7 @@ impl PassManager { /// place phi nodes, then traversing the function in depth-first order to /// rewrite loads and stores as appropriate. This is just the standard SSA /// construction algorithm to construct “pruned” SSA form. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_demote_memory_to_register_pass(&self) { unsafe { LLVMAddDemoteMemoryToRegisterPass(self.pass_manager) } } @@ -1020,24 +1020,24 @@ impl PassManager { /// 20. All other things that are tested by asserts spread about the code. /// /// Note that this does not provide full security verification (like Java), but instead just tries to ensure that code is well-formed. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_verifier_pass(&self) { unsafe { LLVMAddVerifierPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_correlated_value_propagation_pass(&self) { unsafe { LLVMAddCorrelatedValuePropagationPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_early_cse_pass(&self) { unsafe { LLVMAddEarlyCSEPass(self.pass_manager) } } - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] /// No LLVM documentation is available at this time. pub fn add_early_cse_mem_ssa_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddEarlyCSEMemSSAPass; @@ -1046,19 +1046,19 @@ impl PassManager { } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_lower_expect_intrinsic_pass(&self) { unsafe { LLVMAddLowerExpectIntrinsicPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_type_based_alias_analysis_pass(&self) { unsafe { LLVMAddTypeBasedAliasAnalysisPass(self.pass_manager) } } /// No LLVM documentation is available at this time. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_scoped_no_alias_aa_pass(&self) { unsafe { LLVMAddScopedNoAliasAAPass(self.pass_manager) } } @@ -1066,12 +1066,12 @@ impl PassManager { /// A basic alias analysis pass that implements identities /// (two different globals cannot alias, etc), but does no /// stateful analysis. - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn add_basic_alias_analysis_pass(&self) { unsafe { LLVMAddBasicAliasAnalysisPass(self.pass_manager) } } - #[llvm_versions(7.0..=15.0)] + #[llvm_versions(7..=15)] pub fn add_aggressive_inst_combiner_pass(&self) { #[cfg(not(feature = "llvm7-0"))] use llvm_sys::transforms::aggressive_instcombine::LLVMAddAggressiveInstCombinerPass; @@ -1081,35 +1081,35 @@ impl PassManager { unsafe { LLVMAddAggressiveInstCombinerPass(self.pass_manager) } } - #[llvm_versions(7.0..=16.0)] + #[llvm_versions(7..=16)] pub fn add_loop_unroll_and_jam_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddLoopUnrollAndJamPass; unsafe { LLVMAddLoopUnrollAndJamPass(self.pass_manager) } } - #[llvm_versions(8.0..15.0)] + #[llvm_versions(8..15)] pub fn add_coroutine_early_pass(&self) { use llvm_sys::transforms::coroutines::LLVMAddCoroEarlyPass; unsafe { LLVMAddCoroEarlyPass(self.pass_manager) } } - #[llvm_versions(8.0..15.0)] + #[llvm_versions(8..15)] pub fn add_coroutine_split_pass(&self) { use llvm_sys::transforms::coroutines::LLVMAddCoroSplitPass; unsafe { LLVMAddCoroSplitPass(self.pass_manager) } } - #[llvm_versions(8.0..15.0)] + #[llvm_versions(8..15)] pub fn add_coroutine_elide_pass(&self) { use llvm_sys::transforms::coroutines::LLVMAddCoroElidePass; unsafe { LLVMAddCoroElidePass(self.pass_manager) } } - #[llvm_versions(8.0..15.0)] + #[llvm_versions(8..15)] pub fn add_coroutine_cleanup_pass(&self) { use llvm_sys::transforms::coroutines::LLVMAddCoroCleanupPass; @@ -1123,13 +1123,13 @@ impl Drop for PassManager { } } -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] #[derive(Debug)] pub struct PassRegistry { pass_registry: LLVMPassRegistryRef, } -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] impl PassRegistry { pub unsafe fn new(pass_registry: LLVMPassRegistryRef) -> PassRegistry { assert!(!pass_registry.is_null()); @@ -1160,7 +1160,7 @@ impl PassRegistry { unsafe { LLVMInitializeScalarOpts(self.pass_registry) } } - #[llvm_versions(4.0..=15.0)] + #[llvm_versions(..=15)] pub fn initialize_obj_carc_opts(&self) { unsafe { LLVMInitializeObjCARCOpts(self.pass_registry) } } @@ -1178,7 +1178,7 @@ impl PassRegistry { unsafe { LLVMInitializeIPO(self.pass_registry) } } - #[llvm_versions(4.0..=15.0)] + #[llvm_versions(..=15)] pub fn initialize_instrumentation(&self) { unsafe { LLVMInitializeInstrumentation(self.pass_registry) } } @@ -1199,7 +1199,7 @@ impl PassRegistry { unsafe { LLVMInitializeTarget(self.pass_registry) } } - #[llvm_versions(7.0..=15.0)] + #[llvm_versions(7..=15)] pub fn initialize_aggressive_inst_combiner(&self) { use llvm_sys::initialization::LLVMInitializeAggressiveInstCombiner; @@ -1207,13 +1207,13 @@ impl PassRegistry { } } -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] #[derive(Debug)] pub struct PassBuilderOptions { pub(crate) options_ref: LLVMPassBuilderOptionsRef, } -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] impl PassBuilderOptions { /// Create a new set of options for a PassBuilder pub fn create() -> Self { @@ -1298,7 +1298,7 @@ impl PassBuilderOptions { } } -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] impl Drop for PassBuilderOptions { fn drop(&mut self) { unsafe { diff --git a/src/support/mod.rs b/src/support/mod.rs index 465e54c4a03..a0852b5903b 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -2,7 +2,7 @@ pub mod error_handling; use libc::c_char; -#[llvm_versions(16.0..=latest)] +#[llvm_versions(16..)] use llvm_sys::core::LLVMGetVersion; use llvm_sys::core::{LLVMCreateMessage, LLVMDisposeMessage}; use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; @@ -127,7 +127,7 @@ pub unsafe fn shutdown_llvm() { } /// Returns the major, minor, and patch version of the LLVM in use -#[llvm_versions(16.0..=latest)] +#[llvm_versions(16..)] pub fn get_llvm_version() -> (u32, u32, u32) { let mut major: u32 = 0; let mut minor: u32 = 0; diff --git a/src/targets.rs b/src/targets.rs index 9bf59355f16..4f672ddae98 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -5,7 +5,6 @@ use llvm_sys::target::{ LLVMPreferredAlignmentOfGlobal, LLVMPreferredAlignmentOfType, LLVMSizeOfTypeInBits, LLVMStoreSizeOfType, LLVMTargetDataRef, }; -#[llvm_versions(4.0..=latest)] use llvm_sys::target_machine::LLVMCreateTargetDataLayout; use llvm_sys::target_machine::{ LLVMAddAnalysisPasses, LLVMCodeGenFileType, LLVMCodeGenOptLevel, LLVMCodeModel, LLVMCreateTargetMachine, @@ -16,7 +15,7 @@ use llvm_sys::target_machine::{ LLVMTargetHasTargetMachine, LLVMTargetMachineEmitToFile, LLVMTargetMachineEmitToMemoryBuffer, LLVMTargetMachineRef, LLVMTargetRef, }; -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] use llvm_sys::target_machine::{ LLVMCreateTargetMachineOptions, LLVMCreateTargetMachineWithOptions, LLVMDisposeTargetMachineOptions, LLVMTargetMachineOptionsRef, LLVMTargetMachineOptionsSetABI, LLVMTargetMachineOptionsSetCPU, @@ -345,7 +344,6 @@ impl Target { } #[cfg(feature = "target-amdgpu")] - #[llvm_versions(4.0..=latest)] pub fn initialize_amd_gpu(config: &InitializationConfig) { use llvm_sys::target::{ LLVMInitializeAMDGPUAsmParser, LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeAMDGPUTarget, @@ -666,7 +664,6 @@ impl Target { } #[cfg(feature = "target-lanai")] - #[llvm_versions(4.0..=latest)] pub fn initialize_lanai(config: &InitializationConfig) { use llvm_sys::target::{ LLVMInitializeLanaiAsmParser, LLVMInitializeLanaiAsmPrinter, LLVMInitializeLanaiDisassembler, @@ -710,7 +707,7 @@ impl Target { // targets we're going to make this 9.0+ only. See // https://lists.llvm.org/pipermail/llvm-dev/2017-August/116347.html for more info. #[cfg(feature = "target-riscv")] - #[llvm_versions(9.0..=latest)] + #[llvm_versions(9..)] pub fn initialize_riscv(config: &InitializationConfig) { use llvm_sys::target::{ LLVMInitializeRISCVAsmParser, LLVMInitializeRISCVAsmPrinter, LLVMInitializeRISCVDisassembler, @@ -749,7 +746,7 @@ impl Target { } #[cfg(feature = "target-loongarch")] - #[llvm_versions(16.0..=latest)] + #[llvm_versions(16..)] pub fn initialize_loongarch(config: &InitializationConfig) { use llvm_sys::target::{ LLVMInitializeLoongArchAsmParser, LLVMInitializeLoongArchAsmPrinter, LLVMInitializeLoongArchDisassembler, @@ -788,7 +785,7 @@ impl Target { } #[cfg(feature = "target-webassembly")] - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn initialize_webassembly(config: &InitializationConfig) { use llvm_sys::target::{ LLVMInitializeWebAssemblyAsmParser, LLVMInitializeWebAssemblyAsmPrinter, @@ -964,7 +961,7 @@ impl Target { /// assert_eq!(target_machine.get_cpu().to_str(), Ok("x86-64")); /// assert_eq!(target_machine.get_feature_string().to_str(), Ok("+avx2")); /// ``` - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn create_target_machine_from_options( &self, triple: &TargetTriple, @@ -1098,7 +1095,7 @@ impl TargetMachine { unsafe { TargetTriple::new(llvm_string) } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn normalize_triple(triple: &TargetTriple) -> TargetTriple { use llvm_sys::target_machine::LLVMNormalizeTargetTriple; @@ -1112,7 +1109,7 @@ impl TargetMachine { /// # Example Output /// /// `x86_64-pc-linux-gnu` - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_host_cpu_name() -> LLVMString { use llvm_sys::target_machine::LLVMGetHostCPUName; @@ -1124,7 +1121,7 @@ impl TargetMachine { /// # Example Output /// /// `+sse2,+cx16,+sahf,-tbm` - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_host_cpu_features() -> LLVMString { use llvm_sys::target_machine::LLVMGetHostCPUFeatures; @@ -1140,7 +1137,6 @@ impl TargetMachine { } /// Create TargetData from this target machine - #[llvm_versions(4.0..=latest)] pub fn get_target_data(&self) -> TargetData { unsafe { TargetData::new(LLVMCreateTargetDataLayout(self.target_machine)) } } @@ -1427,11 +1423,11 @@ impl Drop for TargetData { /// /// The option structure exposes an additional setting (i.e., the target ABI) /// and provides default values for unspecified settings. -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[derive(Default, Debug)] pub struct TargetMachineOptions(Option); -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] impl TargetMachineOptions { pub fn new() -> Self { Default::default() @@ -1496,7 +1492,7 @@ impl TargetMachineOptions { } } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] impl Drop for TargetMachineOptions { fn drop(&mut self) { if let Some(inner) = self.0 { diff --git a/src/types/array_type.rs b/src/types/array_type.rs index 4f62b012c86..ba7172c0f5c 100644 --- a/src/types/array_type.rs +++ b/src/types/array_type.rs @@ -252,7 +252,7 @@ impl<'ctx> ArrayType<'ctx> { /// /// assert!(i8_array_poison.is_poison()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(self) -> ArrayValue<'ctx> { unsafe { ArrayValue::new(self.array_type.get_poison()) } } diff --git a/src/types/float_type.rs b/src/types/float_type.rs index 821d246fe13..c7612c824a3 100644 --- a/src/types/float_type.rs +++ b/src/types/float_type.rs @@ -279,7 +279,7 @@ impl<'ctx> FloatType<'ctx> { /// /// assert!(f32_poison.is_poison()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(&self) -> FloatValue<'ctx> { unsafe { FloatValue::new(self.float_type.get_poison()) } } diff --git a/src/types/int_type.rs b/src/types/int_type.rs index d6b7da9ed0f..a46d6169993 100644 --- a/src/types/int_type.rs +++ b/src/types/int_type.rs @@ -391,7 +391,7 @@ impl<'ctx> IntType<'ctx> { /// /// assert!(i8_poison.is_poison()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(self) -> IntValue<'ctx> { unsafe { IntValue::new(self.int_type.get_poison()) } } diff --git a/src/types/metadata_type.rs b/src/types/metadata_type.rs index e70ac8ba916..db53342187c 100644 --- a/src/types/metadata_type.rs +++ b/src/types/metadata_type.rs @@ -19,7 +19,7 @@ impl<'ctx> MetadataType<'ctx> { /// /// # Safety /// Undefined behavior, if referenced type isn't metadata type - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub unsafe fn new(metadata_type: LLVMTypeRef) -> Self { assert!(!metadata_type.is_null()); @@ -39,7 +39,7 @@ impl<'ctx> MetadataType<'ctx> { /// let md_type = context.metadata_type(); /// let fn_type = md_type.fn_type(&[], false); /// ``` - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn fn_type(self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> { self.metadata_type.fn_type(param_types, is_var_args) } @@ -56,7 +56,7 @@ impl<'ctx> MetadataType<'ctx> { /// /// assert_eq!(md_type.get_context(), context); /// ``` - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] pub fn get_context(self) -> ContextRef<'ctx> { self.metadata_type.get_context() } @@ -68,12 +68,12 @@ impl<'ctx> MetadataType<'ctx> { } unsafe impl AsTypeRef for MetadataType<'_> { - #[llvm_versions(6.0..=latest)] + #[llvm_versions(6..)] fn as_type_ref(&self) -> LLVMTypeRef { self.metadata_type.ty } - #[llvm_versions(4.0..=5.0)] + #[llvm_versions(..=5)] fn as_type_ref(&self) -> LLVMTypeRef { unimplemented!("MetadataType is only available in LLVM > 6.0") } diff --git a/src/types/mod.rs b/src/types/mod.rs index b129a1a22ba..de52ca7278f 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -35,7 +35,7 @@ pub use crate::types::traits::{AnyType, AsTypeRef, BasicType, FloatMathType, Int pub use crate::types::vec_type::VectorType; pub use crate::types::void_type::VoidType; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use llvm_sys::core::LLVMGetPoison; use llvm_sys::core::{ @@ -138,7 +138,7 @@ impl<'ctx> Type<'ctx> { unsafe { LLVMGetUndef(self.ty) } } - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn get_poison(&self) -> LLVMValueRef { unsafe { LLVMGetPoison(self.ty) } } diff --git a/src/types/ptr_type.rs b/src/types/ptr_type.rs index 3f4f53cddd2..50d66c11ebc 100644 --- a/src/types/ptr_type.rs +++ b/src/types/ptr_type.rs @@ -1,4 +1,4 @@ -#[llvm_versions(15.0..=latest)] +#[llvm_versions(15..)] use llvm_sys::core::LLVMPointerTypeIsOpaque; use llvm_sys::core::{LLVMConstArray, LLVMGetPointerAddressSpace}; use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef}; @@ -6,7 +6,7 @@ use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef}; use crate::context::ContextRef; use crate::support::LLVMString; use crate::types::traits::AsTypeRef; -#[llvm_versions(4.0..=14.0)] +#[llvm_versions(..=14)] use crate::types::AnyTypeEnum; use crate::types::{ArrayType, FunctionType, Type, VectorType}; use crate::values::{ArrayValue, AsValueRef, IntValue, PointerValue}; @@ -298,7 +298,7 @@ impl<'ctx> PointerType<'ctx> { /// /// assert!(f32_ptr_undef.is_poison()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(self) -> PointerValue<'ctx> { unsafe { PointerValue::new(self.ptr_type.get_poison()) } } @@ -344,7 +344,7 @@ impl<'ctx> PointerType<'ctx> { /// /// assert_eq!(f32_ptr_type.get_element_type().into_float_type(), f32_type); /// ``` - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn get_element_type(self) -> AnyTypeEnum<'ctx> { self.ptr_type.get_element_type() } @@ -379,7 +379,7 @@ impl<'ctx> PointerType<'ctx> { } /// Determine whether this pointer is opaque. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub fn is_opaque(self) -> bool { unsafe { LLVMPointerTypeIsOpaque(self.ptr_type.ty) != 0 } } diff --git a/src/types/struct_type.rs b/src/types/struct_type.rs index 3745ace8a0a..b58576b8063 100644 --- a/src/types/struct_type.rs +++ b/src/types/struct_type.rs @@ -397,7 +397,7 @@ impl<'ctx> StructType<'ctx> { /// /// assert!(struct_type_poison.is_poison()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(self) -> StructValue<'ctx> { unsafe { StructValue::new(self.struct_type.get_poison()) } } diff --git a/src/types/vec_type.rs b/src/types/vec_type.rs index 1cad416a51c..f701e4b1d10 100644 --- a/src/types/vec_type.rs +++ b/src/types/vec_type.rs @@ -163,7 +163,7 @@ impl<'ctx> VectorType<'ctx> { /// /// assert!(f32_vec_poison.is_undef()); /// ``` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] pub fn get_poison(self) -> VectorValue<'ctx> { unsafe { VectorValue::new(self.vec_type.get_poison()) } } diff --git a/src/values/call_site_value.rs b/src/values/call_site_value.rs index edb3c0d0b7c..833866ce01a 100644 --- a/src/values/call_site_value.rs +++ b/src/values/call_site_value.rs @@ -5,7 +5,7 @@ use llvm_sys::core::{ LLVMGetInstructionCallConv, LLVMGetTypeKind, LLVMIsTailCall, LLVMSetInstrParamAlignment, LLVMSetInstructionCallConv, LLVMSetTailCall, LLVMTypeOf, }; -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] use llvm_sys::core::{LLVMGetTailCallKind, LLVMSetTailCallKind}; use llvm_sys::prelude::LLVMValueRef; use llvm_sys::LLVMTypeKind; @@ -104,7 +104,7 @@ impl<'ctx> CallSiteValue<'ctx> { /// /// assert_eq!(call_site.get_tail_call_kind(), LLVMTailCallKindNone); /// ``` - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn get_tail_call_kind(self) -> super::LLVMTailCallKind { unsafe { LLVMGetTailCallKind(self.as_value_ref()) } } @@ -131,7 +131,7 @@ impl<'ctx> CallSiteValue<'ctx> { /// call_site.set_tail_call_kind(LLVMTailCallKindTail); /// assert_eq!(call_site.get_tail_call_kind(), LLVMTailCallKindTail); /// ``` - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn set_tail_call_kind(self, kind: super::LLVMTailCallKind) { unsafe { LLVMSetTailCallKind(self.as_value_ref(), kind) }; } diff --git a/src/values/callable_value.rs b/src/values/callable_value.rs index a30c34d2545..b7ae7c3a0d8 100644 --- a/src/values/callable_value.rs +++ b/src/values/callable_value.rs @@ -104,7 +104,7 @@ unsafe impl<'ctx> AsTypeRef for CallableValue<'ctx> { } impl<'ctx> CallableValue<'ctx> { - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub(crate) fn returns_void(&self) -> bool { use llvm_sys::core::LLVMGetReturnType; diff --git a/src/values/float_value.rs b/src/values/float_value.rs index 390a317cffb..f4be7fc04d2 100644 --- a/src/values/float_value.rs +++ b/src/values/float_value.rs @@ -1,9 +1,9 @@ -#[llvm_versions(4.0..=17.0)] +#[llvm_versions(..=17)] use crate::types::IntType; -#[llvm_versions(4.0..=15.0)] +#[llvm_versions(..=15)] use llvm_sys::core::LLVMConstFNeg; use llvm_sys::core::{LLVMConstFCmp, LLVMConstRealGetDouble}; -#[llvm_versions(4.0..=17.0)] +#[llvm_versions(..=17)] use llvm_sys::core::{LLVMConstFPCast, LLVMConstFPExt, LLVMConstFPToSI, LLVMConstFPToUI, LLVMConstFPTrunc}; use llvm_sys::prelude::LLVMValueRef; @@ -68,67 +68,67 @@ impl<'ctx> FloatValue<'ctx> { self.float_value.as_instruction() } - #[llvm_versions(4.0..=15.0)] + #[llvm_versions(..=15)] pub fn const_neg(self) -> Self { unsafe { FloatValue::new(LLVMConstFNeg(self.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_add(self, rhs: FloatValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstFAdd; unsafe { FloatValue::new(LLVMConstFAdd(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_sub(self, rhs: FloatValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstFSub; unsafe { FloatValue::new(LLVMConstFSub(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_mul(self, rhs: FloatValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstFMul; unsafe { FloatValue::new(LLVMConstFMul(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_div(self, rhs: FloatValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstFDiv; unsafe { FloatValue::new(LLVMConstFDiv(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_remainder(self, rhs: FloatValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstFRem; unsafe { FloatValue::new(LLVMConstFRem(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_cast(self, float_type: FloatType<'ctx>) -> Self { unsafe { FloatValue::new(LLVMConstFPCast(self.as_value_ref(), float_type.as_type_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_to_unsigned_int(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstFPToUI(self.as_value_ref(), int_type.as_type_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_to_signed_int(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstFPToSI(self.as_value_ref(), int_type.as_type_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_truncate(self, float_type: FloatType<'ctx>) -> FloatValue<'ctx> { unsafe { FloatValue::new(LLVMConstFPTrunc(self.as_value_ref(), float_type.as_type_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_extend(self, float_type: FloatType<'ctx>) -> FloatValue<'ctx> { unsafe { FloatValue::new(LLVMConstFPExt(self.as_value_ref(), float_type.as_type_ref())) } } diff --git a/src/values/fn_value.rs b/src/values/fn_value.rs index 7c529f98ee8..00a5126f135 100644 --- a/src/values/fn_value.rs +++ b/src/values/fn_value.rs @@ -10,7 +10,7 @@ use llvm_sys::core::{ LLVMIsAFunction, LLVMIsConstant, LLVMSetFunctionCallConv, LLVMSetGC, LLVMSetLinkage, LLVMSetParamAlignment, }; use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn}; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::debuginfo::{LLVMGetSubprogram, LLVMSetSubprogram}; use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef}; @@ -21,7 +21,7 @@ use std::mem::forget; use crate::attributes::{Attribute, AttributeLoc}; use crate::basic_block::BasicBlock; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::debug_info::DISubprogram; use crate::module::Linkage; use crate::support::to_c_str; @@ -207,7 +207,7 @@ impl<'ctx> FunctionValue<'ctx> { LLVMDeleteFunction(self.as_value_ref()) } - #[llvm_versions(4.0..=7.0)] + #[llvm_versions(..=7)] pub fn get_type(self) -> FunctionType<'ctx> { use crate::types::PointerType; @@ -216,7 +216,7 @@ impl<'ctx> FunctionValue<'ctx> { ptr_type.get_element_type().into_function_type() } - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn get_type(self) -> FunctionType<'ctx> { unsafe { FunctionType::new(llvm_sys::core::LLVMGlobalGetValueType(self.as_value_ref())) } } @@ -499,13 +499,13 @@ impl<'ctx> FunctionValue<'ctx> { } /// Set the debug info descriptor - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn set_subprogram(self, subprogram: DISubprogram<'ctx>) { unsafe { LLVMSetSubprogram(self.as_value_ref(), subprogram.metadata_ref) } } /// Get the debug info descriptor - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_subprogram(self) -> Option> { let metadata_ref = unsafe { LLVMGetSubprogram(self.as_value_ref()) }; diff --git a/src/values/global_value.rs b/src/values/global_value.rs index dab7fae8da5..1ca9f5c1537 100644 --- a/src/values/global_value.rs +++ b/src/values/global_value.rs @@ -1,6 +1,6 @@ -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use llvm_sys::core::LLVMGlobalSetMetadata; -#[llvm_versions(4.0..=7.0)] +#[llvm_versions(..=7)] use llvm_sys::core::{ LLVMDeleteGlobal, LLVMGetAlignment, LLVMGetDLLStorageClass, LLVMGetInitializer, LLVMGetLinkage, LLVMGetNextGlobal, LLVMGetPreviousGlobal, LLVMGetSection, LLVMGetThreadLocalMode, LLVMGetVisibility, LLVMIsDeclaration, @@ -8,7 +8,7 @@ use llvm_sys::core::{ LLVMSetExternallyInitialized, LLVMSetGlobalConstant, LLVMSetInitializer, LLVMSetLinkage, LLVMSetSection, LLVMSetThreadLocal, LLVMSetThreadLocalMode, LLVMSetVisibility, }; -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use llvm_sys::core::{ LLVMDeleteGlobal, LLVMGetAlignment, LLVMGetDLLStorageClass, LLVMGetInitializer, LLVMGetLinkage, LLVMGetNextGlobal, LLVMGetPreviousGlobal, LLVMGetThreadLocalMode, LLVMGetVisibility, LLVMIsDeclaration, LLVMIsExternallyInitialized, @@ -16,24 +16,24 @@ use llvm_sys::core::{ LLVMSetGlobalConstant, LLVMSetInitializer, LLVMSetLinkage, LLVMSetThreadLocal, LLVMSetThreadLocalMode, LLVMSetVisibility, }; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::core::{LLVMGetUnnamedAddress, LLVMSetUnnamedAddress}; -#[llvm_versions(4.0..=6.0)] +#[llvm_versions(..=6)] use llvm_sys::core::{LLVMHasUnnamedAddr, LLVMSetUnnamedAddr}; use llvm_sys::prelude::LLVMValueRef; use llvm_sys::LLVMThreadLocalMode; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::LLVMUnnamedAddr; use std::ffi::CStr; use std::fmt::{self, Display}; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use crate::comdat::Comdat; use crate::module::Linkage; use crate::types::AnyTypeEnum; use crate::values::traits::AsValueRef; -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] use crate::values::MetadataValue; use crate::values::{BasicValue, BasicValueEnum, PointerValue, Value}; use crate::{DLLStorageClass, GlobalVisibility, ThreadLocalMode}; @@ -167,22 +167,22 @@ impl<'ctx> GlobalValue<'ctx> { unsafe { LLVMIsDeclaration(self.as_value_ref()) == 1 } } - #[llvm_versions(4.0..=6.0)] + #[llvm_versions(..=6)] pub fn has_unnamed_addr(self) -> bool { unsafe { LLVMHasUnnamedAddr(self.as_value_ref()) == 1 } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn has_unnamed_addr(self) -> bool { unsafe { LLVMGetUnnamedAddress(self.as_value_ref()) == LLVMUnnamedAddr::LLVMGlobalUnnamedAddr } } - #[llvm_versions(4.0..=6.0)] + #[llvm_versions(..=6)] pub fn set_unnamed_addr(self, has_unnamed_addr: bool) { unsafe { LLVMSetUnnamedAddr(self.as_value_ref(), has_unnamed_addr as i32) } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn set_unnamed_addr(self, has_unnamed_addr: bool) { unsafe { if has_unnamed_addr { @@ -246,13 +246,13 @@ impl<'ctx> GlobalValue<'ctx> { } /// Sets a metadata of the given type on the GlobalValue - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn set_metadata(self, metadata: MetadataValue<'ctx>, kind_id: u32) { unsafe { LLVMGlobalSetMetadata(self.as_value_ref(), kind_id, metadata.as_metadata_ref()) } } /// Gets a `Comdat` assigned to this `GlobalValue`, if any. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_comdat(self) -> Option { use llvm_sys::comdat::LLVMGetComdat; @@ -266,14 +266,14 @@ impl<'ctx> GlobalValue<'ctx> { } /// Assigns a `Comdat` to this `GlobalValue`. - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn set_comdat(self, comdat: Comdat) { use llvm_sys::comdat::LLVMSetComdat; unsafe { LLVMSetComdat(self.as_value_ref(), comdat.0) } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn get_unnamed_address(self) -> UnnamedAddress { use llvm_sys::core::LLVMGetUnnamedAddress; @@ -282,7 +282,7 @@ impl<'ctx> GlobalValue<'ctx> { UnnamedAddress::new(unnamed_address) } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub fn set_unnamed_address(self, address: UnnamedAddress) { use llvm_sys::core::LLVMSetUnnamedAddress; @@ -297,7 +297,7 @@ impl<'ctx> GlobalValue<'ctx> { unsafe { LLVMSetLinkage(self.as_value_ref(), linkage.into()) } } - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] pub fn get_value_type(self) -> AnyTypeEnum<'ctx> { unsafe { AnyTypeEnum::new(llvm_sys::core::LLVMGlobalGetValueType(self.as_value_ref())) } } @@ -316,7 +316,7 @@ impl Display for GlobalValue<'_> { } /// This enum determines the significance of a `GlobalValue`'s address. -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] #[llvm_enum(LLVMUnnamedAddr)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum UnnamedAddress { diff --git a/src/values/instruction_value.rs b/src/values/instruction_value.rs index 902e968805a..2463ba32d7a 100644 --- a/src/values/instruction_value.rs +++ b/src/values/instruction_value.rs @@ -11,7 +11,7 @@ use llvm_sys::core::{ LLVMSetMetadata, LLVMSetOperand, LLVMSetVolatile, LLVMValueAsBasicBlock, }; use llvm_sys::core::{LLVMGetOrdering, LLVMSetOrdering}; -#[llvm_versions(10.0..=latest)] +#[llvm_versions(10..)] use llvm_sys::core::{LLVMIsAAtomicCmpXchgInst, LLVMIsAAtomicRMWInst}; use llvm_sys::prelude::LLVMValueRef; use llvm_sys::LLVMOpcode; @@ -42,7 +42,7 @@ pub enum InstructionOpcode { BitCast, Br, Call, - #[llvm_versions(9.0..=latest)] + #[llvm_versions(9..)] CallBr, CatchPad, CatchRet, @@ -51,7 +51,7 @@ pub enum InstructionOpcode { CleanupRet, ExtractElement, ExtractValue, - #[llvm_versions(8.0..=latest)] + #[llvm_versions(8..)] FNeg, FAdd, FCmp, @@ -62,7 +62,7 @@ pub enum InstructionOpcode { FPToSI, FPToUI, FPTrunc, - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] Freeze, FRem, FSub, @@ -121,11 +121,11 @@ impl<'ctx> InstructionValue<'ctx> { fn is_a_alloca_inst(self) -> bool { !unsafe { LLVMIsAAllocaInst(self.as_value_ref()) }.is_null() } - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] fn is_a_atomicrmw_inst(self) -> bool { !unsafe { LLVMIsAAtomicRMWInst(self.as_value_ref()) }.is_null() } - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] fn is_a_cmpxchg_inst(self) -> bool { !unsafe { LLVMIsAAtomicCmpXchgInst(self.as_value_ref()) }.is_null() } @@ -214,7 +214,6 @@ impl<'ctx> InstructionValue<'ctx> { } // REVIEW: Potentially unsafe if parent BB or grandparent fn were removed? - #[llvm_versions(4.0..=latest)] pub fn remove_from_basic_block(self) { unsafe { LLVMInstructionRemoveFromParent(self.as_value_ref()) } } @@ -255,7 +254,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Returns the tail call kind on call instructions. /// /// Other instructions return `None`. - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn get_tail_call_kind(self) -> Option { if self.get_opcode() == InstructionOpcode::Call { unsafe { llvm_sys::core::LLVMGetTailCallKind(self.as_value_ref()) }.into() @@ -267,7 +266,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Check whether this instructions supports [fast math flags][0]. /// /// [0]: https://llvm.org/docs/LangRef.html#fast-math-flags - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn can_use_fast_math_flags(self) -> bool { unsafe { llvm_sys::core::LLVMCanValueUseFastMathFlags(self.as_value_ref()) == 1 } } @@ -277,7 +276,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Calling this on unsupported instructions is safe and returns `None`. /// /// [0]: https://llvm.org/docs/LangRef.html#fast-math-flags - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn get_fast_math_flags(self) -> Option { self.can_use_fast_math_flags() .then(|| unsafe { llvm_sys::core::LLVMGetFastMathFlags(self.as_value_ref()) } as u32) @@ -288,7 +287,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Calling this on unsupported instructions is safe and results in a no-op. /// /// [0]: https://llvm.org/docs/LangRef.html#fast-math-flags - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn set_fast_math_flags(self, flags: u32) { if self.can_use_fast_math_flags() { unsafe { llvm_sys::core::LLVMSetFastMathFlags(self.as_value_ref(), flags) }; @@ -298,7 +297,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Check if a `zext` instruction has the non-negative flag set. /// /// Calling this function on other instructions is safe and returns `None`. - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn get_non_negative_flag(self) -> Option { (self.get_opcode() == InstructionOpcode::ZExt) .then(|| unsafe { llvm_sys::core::LLVMGetNNeg(self.as_value_ref()) == 1 }) @@ -307,7 +306,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Set the non-negative flag on `zext` instructions. /// /// Calling this function on other instructions is safe and results in a no-op. - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn set_non_negative_flag(self, flag: bool) { if self.get_opcode() == InstructionOpcode::ZExt { unsafe { llvm_sys::core::LLVMSetNNeg(self.as_value_ref(), flag as i32) }; @@ -317,7 +316,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Checks if an `or` instruction has the `disjoint` flag set. /// /// Calling this function on other instructions is safe and returns `None`. - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn get_disjoint_flag(self) -> Option { (self.get_opcode() == InstructionOpcode::Or) .then(|| unsafe { llvm_sys::core::LLVMGetIsDisjoint(self.as_value_ref()) == 1 }) @@ -326,7 +325,7 @@ impl<'ctx> InstructionValue<'ctx> { /// Set the `disjoint` flag on `or` instructions. /// /// Calling this function on other instructions is safe and results in a no-op. - #[llvm_versions(18.0..=latest)] + #[llvm_versions(18..)] pub fn set_disjoint_flag(self, flag: bool) { if self.get_opcode() == InstructionOpcode::Or { unsafe { llvm_sys::core::LLVMSetIsDisjoint(self.as_value_ref(), flag as i32) }; @@ -339,7 +338,7 @@ impl<'ctx> InstructionValue<'ctx> { // SubTypes: Only apply to memory access instructions /// Returns whether or not a memory access instruction is volatile. - #[llvm_versions(4.0..=9.0)] + #[llvm_versions(..=9)] pub fn get_volatile(self) -> Result { // Although cmpxchg and atomicrmw can have volatile, LLVM's C API // does not export that functionality until 10.0. @@ -351,7 +350,7 @@ impl<'ctx> InstructionValue<'ctx> { // SubTypes: Only apply to memory access instructions /// Returns whether or not a memory access instruction is volatile. - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] pub fn get_volatile(self) -> Result { if !self.is_a_load_inst() && !self.is_a_store_inst() && !self.is_a_atomicrmw_inst() && !self.is_a_cmpxchg_inst() { @@ -362,7 +361,7 @@ impl<'ctx> InstructionValue<'ctx> { // SubTypes: Only apply to memory access instructions /// Sets whether or not a memory access instruction is volatile. - #[llvm_versions(4.0..=9.0)] + #[llvm_versions(..=9)] pub fn set_volatile(self, volatile: bool) -> Result<(), &'static str> { // Although cmpxchg and atomicrmw can have volatile, LLVM's C API // does not export that functionality until 10.0. @@ -374,7 +373,7 @@ impl<'ctx> InstructionValue<'ctx> { // SubTypes: Only apply to memory access instructions /// Sets whether or not a memory access instruction is volatile. - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10..)] pub fn set_volatile(self, volatile: bool) -> Result<(), &'static str> { if !self.is_a_load_inst() && !self.is_a_store_inst() && !self.is_a_atomicrmw_inst() && !self.is_a_cmpxchg_inst() { diff --git a/src/values/int_value.rs b/src/values/int_value.rs index ff153c541b8..c010ef31a57 100644 --- a/src/values/int_value.rs +++ b/src/values/int_value.rs @@ -1,6 +1,6 @@ -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::core::LLVMConstSelect; -#[llvm_versions(4.0..=17.0)] +#[llvm_versions(..=17)] use llvm_sys::core::{ LLVMConstAShr, LLVMConstAnd, LLVMConstIntCast, LLVMConstLShr, LLVMConstOr, LLVMConstSExt, LLVMConstSExtOrBitCast, LLVMConstSIToFP, LLVMConstUIToFP, LLVMConstZExt, LLVMConstZExtOrBitCast, @@ -17,13 +17,13 @@ use std::convert::TryFrom; use std::ffi::CStr; use std::fmt::{self, Display}; -#[llvm_versions(4.0..=17.0)] +#[llvm_versions(..=17)] use crate::types::FloatType; use crate::types::{AsTypeRef, IntType, PointerType}; use crate::values::traits::AsValueRef; -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use crate::values::BasicValueEnum; -#[llvm_versions(4.0..=17.0)] +#[llvm_versions(..=17)] use crate::values::FloatValue; use crate::values::{BasicValue, InstructionValue, PointerValue, Value}; use crate::IntPredicate; @@ -133,54 +133,54 @@ impl<'ctx> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstNUWMul(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_unsigned_div(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstUDiv; unsafe { IntValue::new(LLVMConstUDiv(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_signed_div(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstSDiv; unsafe { IntValue::new(LLVMConstSDiv(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_exact_signed_div(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstExactSDiv; unsafe { IntValue::new(LLVMConstExactSDiv(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_exact_unsigned_div(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstExactUDiv; unsafe { IntValue::new(LLVMConstExactUDiv(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_unsigned_remainder(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstURem; unsafe { IntValue::new(LLVMConstURem(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub fn const_signed_remainder(self, rhs: IntValue<'ctx>) -> Self { use llvm_sys::core::LLVMConstSRem; unsafe { IntValue::new(LLVMConstSRem(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_and(self, rhs: IntValue<'ctx>) -> Self { unsafe { IntValue::new(LLVMConstAnd(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_or(self, rhs: IntValue<'ctx>) -> Self { unsafe { IntValue::new(LLVMConstOr(self.as_value_ref(), rhs.as_value_ref())) } } @@ -190,7 +190,7 @@ impl<'ctx> IntValue<'ctx> { } // TODO: Could infer is_signed from type (one day)? - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_cast(self, int_type: IntType<'ctx>, is_signed: bool) -> Self { unsafe { IntValue::new(LLVMConstIntCast( @@ -206,24 +206,24 @@ impl<'ctx> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstShl(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_rshr(self, rhs: IntValue<'ctx>) -> Self { unsafe { IntValue::new(LLVMConstLShr(self.as_value_ref(), rhs.as_value_ref())) } } - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_ashr(self, rhs: IntValue<'ctx>) -> Self { unsafe { IntValue::new(LLVMConstAShr(self.as_value_ref(), rhs.as_value_ref())) } } // SubType: const_to_float impl only for unsigned types - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_unsigned_to_float(self, float_type: FloatType<'ctx>) -> FloatValue<'ctx> { unsafe { FloatValue::new(LLVMConstUIToFP(self.as_value_ref(), float_type.as_type_ref())) } } // SubType: const_to_float impl only for signed types - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_signed_to_float(self, float_type: FloatType<'ctx>) -> FloatValue<'ctx> { unsafe { FloatValue::new(LLVMConstSIToFP(self.as_value_ref(), float_type.as_type_ref())) } } @@ -237,13 +237,13 @@ impl<'ctx> IntValue<'ctx> { } // TODO: More descriptive name - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_s_extend(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstSExt(self.as_value_ref(), int_type.as_type_ref())) } } // TODO: More descriptive name - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_z_ext(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstZExt(self.as_value_ref(), int_type.as_type_ref())) } } @@ -253,13 +253,13 @@ impl<'ctx> IntValue<'ctx> { } // TODO: More descriptive name - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_s_extend_or_bit_cast(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstSExtOrBitCast(self.as_value_ref(), int_type.as_type_ref())) } } // TODO: More descriptive name - #[llvm_versions(4.0..=17.0)] + #[llvm_versions(..=17)] pub fn const_z_ext_or_bit_cast(self, int_type: IntType<'ctx>) -> IntValue<'ctx> { unsafe { IntValue::new(LLVMConstZExtOrBitCast(self.as_value_ref(), int_type.as_type_ref())) } } @@ -274,7 +274,7 @@ impl<'ctx> IntValue<'ctx> { } // SubTypes: self can only be IntValue - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn const_select>(self, then: BV, else_: BV) -> BasicValueEnum<'ctx> { unsafe { BasicValueEnum::new(LLVMConstSelect( diff --git a/src/values/metadata_value.rs b/src/values/metadata_value.rs index 9ca76c91b61..86aeb098089 100644 --- a/src/values/metadata_value.rs +++ b/src/values/metadata_value.rs @@ -3,9 +3,9 @@ use llvm_sys::core::{ }; use llvm_sys::prelude::LLVMValueRef; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::core::LLVMValueAsMetadata; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use llvm_sys::prelude::LLVMMetadataRef; use crate::values::traits::AsValueRef; @@ -61,7 +61,7 @@ impl<'ctx> MetadataValue<'ctx> { } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] pub(crate) fn as_metadata_ref(self) -> LLVMMetadataRef { unsafe { LLVMValueAsMetadata(self.as_value_ref()) } } diff --git a/src/values/mod.rs b/src/values/mod.rs index 89425fb60a6..1f6cb799f72 100644 --- a/src/values/mod.rs +++ b/src/values/mod.rs @@ -45,7 +45,7 @@ pub use crate::values::float_value::FloatValue; pub use crate::values::fn_value::FunctionValue; pub use crate::values::generic_value::GenericValue; pub use crate::values::global_value::GlobalValue; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] pub use crate::values::global_value::UnnamedAddress; pub use crate::values::instruction_value::{InstructionOpcode, InstructionValue, OperandIter, OperandUseIter}; pub use crate::values::int_value::IntValue; @@ -59,7 +59,7 @@ pub use crate::values::traits::AsValueRef; pub use crate::values::traits::{AggregateValue, AnyValue, BasicValue, FloatMathValue, IntMathValue, PointerMathValue}; pub use crate::values::vec_value::VectorValue; -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] pub use llvm_sys::LLVMTailCallKind; use llvm_sys::core::{ diff --git a/src/values/ptr_value.rs b/src/values/ptr_value.rs index 1e7aa063937..97726f88629 100644 --- a/src/values/ptr_value.rs +++ b/src/values/ptr_value.rs @@ -1,6 +1,6 @@ -#[llvm_versions(4.0..=14.0)] +#[llvm_versions(..=14)] use llvm_sys::core::{LLVMConstGEP, LLVMConstInBoundsGEP}; -#[llvm_versions(15.0..=latest)] +#[llvm_versions(15..)] use llvm_sys::core::{LLVMConstGEP2, LLVMConstInBoundsGEP2}; use llvm_sys::core::{LLVMConstAddrSpaceCast, LLVMConstPointerCast, LLVMConstPtrToInt}; @@ -82,7 +82,7 @@ impl<'ctx> PointerValue<'ctx> { // REVIEW: Should this be on array value too? /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub unsafe fn const_gep(self, ordered_indexes: &[IntValue<'ctx>]) -> PointerValue<'ctx> { let mut index_values: Vec = ordered_indexes.iter().map(|val| val.as_value_ref()).collect(); @@ -99,7 +99,7 @@ impl<'ctx> PointerValue<'ctx> { // REVIEW: Should this be on array value too? /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub unsafe fn const_gep>(self, ty: T, ordered_indexes: &[IntValue<'ctx>]) -> PointerValue<'ctx> { let mut index_values: Vec = ordered_indexes.iter().map(|val| val.as_value_ref()).collect(); @@ -116,7 +116,7 @@ impl<'ctx> PointerValue<'ctx> { } /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] pub unsafe fn const_in_bounds_gep(self, ordered_indexes: &[IntValue<'ctx>]) -> PointerValue<'ctx> { let mut index_values: Vec = ordered_indexes.iter().map(|val| val.as_value_ref()).collect(); @@ -132,7 +132,7 @@ impl<'ctx> PointerValue<'ctx> { } /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future. - #[llvm_versions(15.0..=latest)] + #[llvm_versions(15..)] pub unsafe fn const_in_bounds_gep>( self, ty: T, diff --git a/src/values/traits.rs b/src/values/traits.rs index 47084670538..bd76778471c 100644 --- a/src/values/traits.rs +++ b/src/values/traits.rs @@ -1,6 +1,6 @@ use llvm_sys::prelude::LLVMValueRef; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] use llvm_sys::core::LLVMIsPoison; use std::fmt::Debug; @@ -57,7 +57,7 @@ pub unsafe trait AggregateValue<'ctx>: BasicValue<'ctx> { // REVIEW: How does LLVM treat out of bound index? Maybe we should return an Option? // or is that only in bounds GEP // REVIEW: Should this be AggregatePointerValue? - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] fn const_extract_value(&self, indexes: &mut [u32]) -> BasicValueEnum<'ctx> { use llvm_sys::core::LLVMConstExtractValue; @@ -71,7 +71,7 @@ pub unsafe trait AggregateValue<'ctx>: BasicValue<'ctx> { } // SubTypes: value should really be T in self: VectorValue I think - #[llvm_versions(4.0..=14.0)] + #[llvm_versions(..=14)] fn const_insert_value>(&self, value: BV, indexes: &mut [u32]) -> BasicValueEnum<'ctx> { use llvm_sys::core::LLVMConstInsertValue; @@ -149,7 +149,7 @@ pub unsafe trait AnyValue<'ctx>: AsValueRef + Debug { } /// Returns whether the value is `poison` - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn is_poison(&self) -> bool { unsafe { LLVMIsPoison(self.as_value_ref()) == 1 } } diff --git a/src/values/vec_value.rs b/src/values/vec_value.rs index 9cc0ab1f67b..08c1d181659 100644 --- a/src/values/vec_value.rs +++ b/src/values/vec_value.rs @@ -1,4 +1,4 @@ -#[llvm_versions(4.0..=16.0)] +#[llvm_versions(..=16)] use llvm_sys::core::LLVMConstSelect; use llvm_sys::core::{ LLVMConstExtractElement, LLVMConstInsertElement, LLVMConstShuffleVector, LLVMGetElementAsConstant, @@ -117,7 +117,7 @@ impl<'ctx> VectorValue<'ctx> { } // SubTypes: self can only be VectoValue> - #[llvm_versions(4.0..=16.0)] + #[llvm_versions(..=16)] pub fn const_select>(self, then: BV, else_: BV) -> BasicValueEnum<'ctx> { unsafe { BasicValueEnum::new(LLVMConstSelect( diff --git a/tests/all/test_attributes.rs b/tests/all/test_attributes.rs index 17e8942bc26..016a1d02f7f 100644 --- a/tests/all/test_attributes.rs +++ b/tests/all/test_attributes.rs @@ -40,7 +40,7 @@ fn test_string_attributes() { assert_eq!(string_attribute.get_string_value().to_str(), Ok("my_val")); } -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] #[test] fn test_type_attribute() { use inkwell::types::{AnyType, BasicType}; diff --git a/tests/all/test_builder.rs b/tests/all/test_builder.rs index 8949f23a62e..2e8528e1f9d 100644 --- a/tests/all/test_builder.rs +++ b/tests/all/test_builder.rs @@ -917,7 +917,7 @@ fn test_vector_convert_ops() { assert!(fn_value.verify(true)); } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_vector_convert_ops_respect_target_signedness() { let context = Context::create(); @@ -1202,11 +1202,11 @@ fn test_insert_element() { builder.position_at_end(entry); - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12..)] fn get_empty_vector_of(ty: IntType<'_>) -> VectorValue<'_> { ty.vec_type(4).get_poison() } - #[llvm_versions(4.0..12.0)] + #[llvm_versions(..12)] fn get_empty_vector_of(ty: IntType<'_>) -> VectorValue<'_> { ty.vec_type(4).get_undef() } @@ -1239,7 +1239,7 @@ fn is_alignment_ok(align: u32) -> bool { align > 0 && align.is_power_of_two() && (align as f64).log2() < 64.0 } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_alignment_bytes() { let verify_alignment = |alignment: u32| { @@ -1277,7 +1277,7 @@ fn test_alignment_bytes() { verify_alignment(u32::max_value()); } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] fn run_memcpy_on<'ctx>( context: &'ctx Context, module: &inkwell::module::Module<'ctx>, @@ -1382,7 +1382,7 @@ fn run_memcpy_on<'ctx>( Ok(()) } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_memcpy() { // 1. Allocate an array with a few elements. @@ -1410,7 +1410,7 @@ fn test_memcpy() { } } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] fn run_memmove_on<'ctx>( context: &'ctx Context, module: &inkwell::module::Module<'ctx>, @@ -1515,7 +1515,7 @@ fn run_memmove_on<'ctx>( Ok(()) } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_memmove() { // 1. Allocate an array with a few elements. @@ -1543,7 +1543,7 @@ fn test_memmove() { } } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] fn run_memset_on<'ctx>( context: &'ctx Context, module: &inkwell::module::Module<'ctx>, @@ -1618,7 +1618,7 @@ fn run_memset_on<'ctx>( Ok(()) } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_memset() { // 1. Allocate an array with a few elements. diff --git a/tests/all/test_context.rs b/tests/all/test_context.rs index b486af9b230..003eedf1439 100644 --- a/tests/all/test_context.rs +++ b/tests/all/test_context.rs @@ -81,7 +81,7 @@ fn test_values_get_context() { assert_eq!(struct_type.get_context(), context); } -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] #[test] fn test_get_struct_type() { let context = Context::create(); diff --git a/tests/all/test_debug_info.rs b/tests/all/test_debug_info.rs index 60558cc7e18..43994d3b453 100644 --- a/tests/all/test_debug_info.rs +++ b/tests/all/test_debug_info.rs @@ -276,7 +276,7 @@ fn test_no_explicit_finalize() { assert!(module.verify().is_ok()); } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_replacing_placeholder_with_placeholder() { let context = Context::create(); @@ -395,7 +395,7 @@ fn test_anonymous_basic_type() { ); } -#[llvm_versions(8.0..=latest)] +#[llvm_versions(8..)] #[test] fn test_global_expressions() { let context = Context::create(); diff --git a/tests/all/test_instruction_values.rs b/tests/all/test_instruction_values.rs index 59200ad626d..d3267ca35d9 100644 --- a/tests/all/test_instruction_values.rs +++ b/tests/all/test_instruction_values.rs @@ -362,7 +362,7 @@ fn test_instructions() { assert_eq!(instruction_clone, instruction_clone_copy); } -#[llvm_versions(10.0..=latest)] +#[llvm_versions(10..)] #[test] fn test_volatile_atomicrmw_cmpxchg() { let context = Context::create(); @@ -429,7 +429,7 @@ fn test_volatile_atomicrmw_cmpxchg() { assert_eq!(cmpxchg.get_volatile().unwrap(), false); } -#[llvm_versions(4.0..=10.0)] +#[llvm_versions(..=10)] #[test] fn test_mem_instructions() { let context = Context::create(); @@ -507,7 +507,7 @@ fn test_mem_instructions() { assert!(fadd_instruction.set_alignment(16).is_err()); } -#[llvm_versions(11.0..=latest)] +#[llvm_versions(11..)] #[test] fn test_mem_instructions() { let context = Context::create(); @@ -784,7 +784,7 @@ fn test_find_instruction_with_name() { assert_eq!(some_number.unwrap().get_name().unwrap().to_str(), Ok("some_number")) } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[test] fn test_fast_math_flags() { let context = Context::create(); @@ -828,7 +828,7 @@ fn test_fast_math_flags() { assert_eq!(f32_addition.get_fast_math_flags(), Some(1)); } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[test] fn test_zext_non_negative_flag() { let context = Context::create(); @@ -870,7 +870,7 @@ fn test_zext_non_negative_flag() { assert_eq!(i32_sext.get_non_negative_flag(), None); } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[test] fn test_or_disjoint_flag() { let context = Context::create(); diff --git a/tests/all/test_intrinsics.rs b/tests/all/test_intrinsics.rs index 6529b264b1c..9adb66caa00 100644 --- a/tests/all/test_intrinsics.rs +++ b/tests/all/test_intrinsics.rs @@ -1,19 +1,19 @@ use inkwell::context::Context; use inkwell::intrinsics::Intrinsic; -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] #[test] fn test_get_cos() { Intrinsic::find("llvm.cos").unwrap(); } -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] #[test] fn test_get_nonexistent() { assert!(Intrinsic::find("nonsense").is_none()) } -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] #[test] fn test_get_decl_cos() { let cos = Intrinsic::find("llvm.cos").unwrap(); @@ -31,7 +31,7 @@ fn test_get_decl_cos() { assert_eq!(decl.get_name().to_str().unwrap(), "llvm.cos.f32"); } -#[llvm_versions(9.0..=latest)] +#[llvm_versions(9..)] #[test] fn test_get_decl_va_copy() { let va_copy = Intrinsic::find("llvm.va_copy").unwrap(); diff --git a/tests/all/test_object_file.rs b/tests/all/test_object_file.rs index f6de74c6be6..cb04ebd82c4 100644 --- a/tests/all/test_object_file.rs +++ b/tests/all/test_object_file.rs @@ -5,30 +5,32 @@ use inkwell::types::IntType; use inkwell::values::BasicValue; use inkwell::OptimizationLevel; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] fn get_host_cpu_name() -> String { TargetMachine::get_host_cpu_name().to_string() } -#[llvm_versions(7.0..=latest)] + +#[llvm_versions(7..)] fn get_host_cpu_features() -> String { TargetMachine::get_host_cpu_features().to_string() } -#[llvm_versions(4.0..=latest)] + fn ptr_sized_int_type<'ctx>(target_machine: &TargetMachine, context: &'ctx Context) -> IntType<'ctx> { let target_data = target_machine.get_target_data(); context.ptr_sized_int_type(&target_data, None) } -#[llvm_versions(4.0..=latest)] + fn apply_target_to_module<'ctx>(target_machine: &TargetMachine, module: &Module) { module.set_triple(&target_machine.get_triple()); module.set_data_layout(&target_machine.get_target_data().get_data_layout()); } -#[llvm_versions(4.0..7.0)] +#[llvm_versions(..7)] fn get_host_cpu_name() -> String { "".to_string() } -#[llvm_versions(4.0..7.0)] + +#[llvm_versions(..7)] fn get_host_cpu_features() -> String { "".to_string() } diff --git a/tests/all/test_passes.rs b/tests/all/test_passes.rs index 2212cd3d09f..d1138e61362 100644 --- a/tests/all/test_passes.rs +++ b/tests/all/test_passes.rs @@ -1,9 +1,9 @@ use inkwell::context::Context; use inkwell::passes::{PassManager, PassManagerBuilder, PassRegistry}; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use inkwell::passes::PassBuilderOptions; -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] use inkwell::targets::{CodeModel, InitializationConfig, RelocMode, Target, TargetMachine}; use inkwell::OptimizationLevel; @@ -243,7 +243,7 @@ fn test_pass_registry() { pass_registry.initialize_aggressive_inst_combiner(); } -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] #[test] fn test_run_passes() { let pass_options = PassBuilderOptions::create(); @@ -280,7 +280,7 @@ fn test_run_passes() { module.run_passes("default", &machine, pass_options).unwrap(); } -#[llvm_versions(13.0..=latest)] +#[llvm_versions(13..)] #[test] fn test_run_passes_invalid() { let pass_options = PassBuilderOptions::create(); diff --git a/tests/all/test_targets.rs b/tests/all/test_targets.rs index 75ceaedfe03..6a64f21c800 100644 --- a/tests/all/test_targets.rs +++ b/tests/all/test_targets.rs @@ -428,7 +428,7 @@ fn test_write_target_machine_to_memory_buffer() { write_target_machine_to_memory_buffer(target_machine); } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[test] fn test_create_target_machine_from_default_options() { Target::initialize_x86(&InitializationConfig::default()); @@ -445,7 +445,7 @@ fn test_create_target_machine_from_default_options() { write_target_machine_to_memory_buffer(target_machine); } -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] #[test] fn test_create_target_machine_from_options() { Target::initialize_x86(&InitializationConfig::default()); diff --git a/tests/all/test_types.rs b/tests/all/test_types.rs index f3b374b3cc9..378def2e93b 100644 --- a/tests/all/test_types.rs +++ b/tests/all/test_types.rs @@ -557,7 +557,7 @@ fn test_ptr_address_space() { assert!(AddressSpace::try_from(1u32 << 24).is_err()); } -#[llvm_versions(15.0..=latest)] +#[llvm_versions(15..)] #[test] fn test_ptr_is_opaque() { let context = Context::create(); diff --git a/tests/all/test_values.rs b/tests/all/test_values.rs index 73c89e0e61b..aec98e0cdfb 100644 --- a/tests/all/test_values.rs +++ b/tests/all/test_values.rs @@ -1,5 +1,5 @@ use inkwell::attributes::AttributeLoc; -#[llvm_versions(7.0..=latest)] +#[llvm_versions(7..)] use inkwell::comdat::ComdatSelectionKind; use inkwell::context::Context; use inkwell::module::Linkage::*; @@ -7,7 +7,7 @@ use inkwell::types::{AnyTypeEnum, BasicType, StringRadix, VectorType}; use inkwell::values::{AnyValue, BasicValue, InstructionOpcode::*, FIRST_CUSTOM_METADATA_KIND_ID}; use inkwell::{AddressSpace, DLLStorageClass, GlobalVisibility, ThreadLocalMode}; -#[llvm_versions(18.0..=latest)] +#[llvm_versions(18..)] pub use llvm_sys::LLVMTailCallKind::*; #[cfg(feature = "llvm18-0")] use llvm_sys_180 as llvm_sys; @@ -387,7 +387,7 @@ fn test_undef() { assert!(ppc_f128_undef.is_undef()); } -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12..)] #[test] fn test_poison() { let context = Context::create(); @@ -928,7 +928,7 @@ fn test_global_byte_array() { #[test] fn test_globals() { - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7..)] use inkwell::values::UnnamedAddress; let context = Context::create();