diff --git a/.travis.yml b/.travis.yml index 65c6e8b083d1a..e90e91499301a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,63 @@ language: rust sudo: false +cache: + - apt + - cargo -rust: - - stable - - beta - - nightly +include_base: &BASE + addons: + apt: + sources: &BASE_SOURCES + - ubuntu-toolchain-r-test + packages: &BASE_PACKAGES + - libelf-dev + - lib32z1-dev + - libedit-dev + - libdw-dev + - binutils-dev + - libiberty-dev + before_install: + - export LLVM_VERSION_DASH=${LLVM_VERSION/./-} + - export LLVM_VERSION_SHORT=${LLVM_VERSION/./} + - export PATH=/usr/lib/llvm-${LLVM_VERSION}/bin/:$HOME/.local/bin:$PATH + - export LLVM_PATH=/usr/share/llvm-${LLVM_VERSION}/cmake/ + - sed -i -e 's/llvm-sys = ".*"/llvm-sys = "'${LLVM_VERSION_SHORT}'"/' Cargo.toml + script: + - cargo test --no-default-features --features "llvm${LLVM_VERSION_DASH}" --verbose matrix: allow_failures: - rust: nightly fast_finish: true + include: + - env: + - LLVM_VERSION="3.6" + <<: *BASE + addons: + apt: + sources: + - *BASE_SOURCES + - llvm-toolchain-precise-3.6 + packages: + - *BASE_PACKAGES + - llvm-3.6-dev + + - env: + - LLVM_VERSION="3.7" + <<: *BASE + addons: + apt: + sources: + - *BASE_SOURCES + - llvm-toolchain-precise-3.7 + packages: + - *BASE_PACKAGES + - llvm-3.7-dev env: global: - - RUSTFLAGS="-C link-dead-code" - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - packages: - - llvm-3.7-dev - - libelf-dev - - lib32z1-dev - - libedit-dev - - libdw-dev - - binutils-dev - - libiberty-dev - -before_install: - - export PATH=/usr/lib/llvm-3.7/bin/:$HOME/.local/bin:$PATH + - RUSTFLAGS="-C link-dead-code -C target-cpu=native" after_success: | wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && diff --git a/Cargo.toml b/Cargo.toml index 7c74dc2fa54c9..a976cda15aaef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,16 @@ keywords = ["llvm", "safe", "wrapper"] license = "Apache-2.0" categories = ["development-tools::ffi"] +[features] +default = [] +llvm3-6 = [] +llvm3-7 = [] + [dependencies] -either = "1.1.0" -enum-methods = "0.0.7" +either = "1.4.0" +enum-methods = "0.0.8" libc = "*" -llvm-sys = "37.0.5" # TODO: Configure based on feature toggle. GH#1 +llvm-sys = "37" [[example]] name = "kaleidoscope" diff --git a/README.md b/README.md index 8f48e436c811a..ca6e0eea29131 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,25 @@ Inkwell aims to help you pen your own programming languages by safely wrapping l * Any Rust version released in the last year or so * Rust Stable, Beta, or Nightly -* LLVM 3.7 (3.6 and 3.8+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1)) +* LLVM 3.6 or 3.7 (3.8+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1)) ## Usage -You'll need to point your Cargo.toml to the master branch of Inkwell like so: +You'll need to point your Cargo.toml to a branch and use a feature flag corresponding to a supported LLVM version: ```toml [dependencies] -inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master" } +inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm3-7", features = ["llvm3-7"] } ``` -In the root of your source code you will likely have to add an extern crate to begin using Inkwell: +Supported versions: + +| GitHub Branch | Feature Flag | +| :-----------: | :----------: | +| llvm3-6 | llvm3-6 | +| llvm3-7 | llvm3-7 | + +In the root of your source code you will have to add an extern crate to begin using Inkwell: ```rust extern crate inkwell; diff --git a/src/lib.rs b/src/lib.rs index f9827418df927..80e7067f7ad0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,9 @@ use llvm_sys::support::LLVMLoadLibraryPermanently; use std::ffi::CString; +#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))] +compile_error!("A LLVM feature flag must be provided. See the README for more details."); + // TODO: Probably move into error handling module pub fn enable_llvm_pretty_stack_trace() { // use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; // v3.8 diff --git a/src/passes.rs b/src/passes.rs index 8f50210c8b45f..9bdbeb445245f 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -1,14 +1,18 @@ use llvm_sys::core::{LLVMDisposePassManager, LLVMInitializeFunctionPassManager, LLVMFinalizeFunctionPassManager, LLVMRunFunctionPassManager, LLVMRunPassManager, LLVMCreatePassManager, LLVMCreateFunctionPassManagerForModule, LLVMGetGlobalPassRegistry}; use llvm_sys::initialization::{LLVMInitializeCore, LLVMInitializeTransformUtils, LLVMInitializeScalarOpts, LLVMInitializeObjCARCOpts, LLVMInitializeVectorization, LLVMInitializeInstCombine, LLVMInitializeIPO, LLVMInitializeInstrumentation, LLVMInitializeAnalysis, LLVMInitializeIPA, LLVMInitializeCodeGen, LLVMInitializeTarget}; use llvm_sys::prelude::{LLVMPassManagerRef, LLVMPassRegistryRef}; +#[cfg(not(feature = "llvm3-6"))] use llvm_sys::target::LLVMAddTargetData; use llvm_sys::transforms::ipo::{LLVMAddArgumentPromotionPass, LLVMAddConstantMergePass, LLVMAddDeadArgEliminationPass, LLVMAddFunctionAttrsPass, LLVMAddFunctionInliningPass, LLVMAddAlwaysInlinerPass, LLVMAddGlobalDCEPass, LLVMAddGlobalOptimizerPass, LLVMAddIPConstantPropagationPass, LLVMAddIPSCCPPass, LLVMAddInternalizePass, LLVMAddStripDeadPrototypesPass, LLVMAddPruneEHPass, LLVMAddStripSymbolsPass}; use llvm_sys::transforms::pass_manager_builder::{LLVMPassManagerBuilderRef, LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderSetDisableUnitAtATime, LLVMPassManagerBuilderSetDisableUnrollLoops, LLVMPassManagerBuilderSetDisableSimplifyLibCalls, LLVMPassManagerBuilderUseInlinerWithThreshold, LLVMPassManagerBuilderPopulateFunctionPassManager, LLVMPassManagerBuilderPopulateModulePassManager, LLVMPassManagerBuilderPopulateLTOPassManager}; -use llvm_sys::transforms::scalar::{LLVMAddAggressiveDCEPass, LLVMAddMemCpyOptPass, LLVMAddBitTrackingDCEPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddCFGSimplificationPass, LLVMAddDeadStoreEliminationPass, LLVMAddScalarizerPass, LLVMAddMergedLoadStoreMotionPass, LLVMAddGVNPass, LLVMAddIndVarSimplifyPass, LLVMAddInstructionCombiningPass, LLVMAddJumpThreadingPass, LLVMAddLICMPass, LLVMAddLoopDeletionPass, LLVMAddLoopIdiomPass, LLVMAddLoopRotatePass, LLVMAddLoopRerollPass, LLVMAddLoopUnrollPass, LLVMAddLoopUnswitchPass, LLVMAddPartiallyInlineLibCallsPass, LLVMAddLowerSwitchPass, LLVMAddPromoteMemoryToRegisterPass, LLVMAddSCCPPass, LLVMAddScalarReplAggregatesPass, LLVMAddScalarReplAggregatesPassSSA, LLVMAddScalarReplAggregatesPassWithThreshold, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddConstantPropagationPass, LLVMAddDemoteMemoryToRegisterPass, LLVMAddVerifierPass, LLVMAddCorrelatedValuePropagationPass, LLVMAddEarlyCSEPass, LLVMAddLowerExpectIntrinsicPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddScopedNoAliasAAPass, LLVMAddBasicAliasAnalysisPass, LLVMAddReassociatePass}; +use llvm_sys::transforms::scalar::{LLVMAddAggressiveDCEPass, LLVMAddMemCpyOptPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddCFGSimplificationPass, LLVMAddDeadStoreEliminationPass, LLVMAddScalarizerPass, LLVMAddMergedLoadStoreMotionPass, LLVMAddGVNPass, LLVMAddIndVarSimplifyPass, LLVMAddInstructionCombiningPass, LLVMAddJumpThreadingPass, LLVMAddLICMPass, LLVMAddLoopDeletionPass, LLVMAddLoopIdiomPass, LLVMAddLoopRotatePass, LLVMAddLoopRerollPass, LLVMAddLoopUnrollPass, LLVMAddLoopUnswitchPass, LLVMAddPartiallyInlineLibCallsPass, LLVMAddLowerSwitchPass, LLVMAddPromoteMemoryToRegisterPass, LLVMAddSCCPPass, LLVMAddScalarReplAggregatesPass, LLVMAddScalarReplAggregatesPassSSA, LLVMAddScalarReplAggregatesPassWithThreshold, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddConstantPropagationPass, LLVMAddDemoteMemoryToRegisterPass, LLVMAddVerifierPass, LLVMAddCorrelatedValuePropagationPass, LLVMAddEarlyCSEPass, LLVMAddLowerExpectIntrinsicPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddScopedNoAliasAAPass, LLVMAddBasicAliasAnalysisPass, LLVMAddReassociatePass}; +#[cfg(not(feature = "llvm3-6"))] +use llvm_sys::transforms::scalar::LLVMAddBitTrackingDCEPass; use llvm_sys::transforms::vectorize::{LLVMAddBBVectorizePass, LLVMAddLoopVectorizePass, LLVMAddSLPVectorizePass}; use OptimizationLevel; use module::Module; +#[cfg(not(feature = "llvm3-6"))] use targets::TargetData; use values::{AsValueRef, FunctionValue}; @@ -159,6 +163,7 @@ impl PassManager { } } + #[cfg(not(feature = "llvm3-6"))] pub fn add_target_data(&self, target_data: &TargetData) { unsafe { LLVMAddTargetData(target_data.target_data, self.pass_manager) @@ -274,7 +279,7 @@ impl PassManager { } } - // TODO: 3.7+ only + #[cfg(not(feature = "llvm3-6"))] pub fn add_bit_tracking_dce_pass(&self) { unsafe { LLVMAddBitTrackingDCEPass(self.pass_manager) diff --git a/src/targets.rs b/src/targets.rs index bf95f3ba2e603..c8c2410a6f2eb 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -210,6 +210,36 @@ impl Target { } } + // TODOC: Called AMDGPU in 3.7+ + #[cfg(feature = "llvm3-6")] + pub fn initialize_r600(config: &InitializationConfig) { + use llvm_sys::target::{LLVMInitializeR600Target, LLVMInitializeR600TargetInfo, LLVMInitializeR600TargetMC, LLVMInitializeR600AsmPrinter, LLVMInitializeR600AsmParser}; + + unsafe { + if config.base { + LLVMInitializeR600Target() + } + + if config.info { + LLVMInitializeR600TargetInfo() + } + + if config.asm_printer { + LLVMInitializeR600AsmPrinter() + } + + if config.asm_parser { + LLVMInitializeR600AsmParser() + } + + if config.machine_code { + LLVMInitializeR600TargetMC() + } + } + } + + // TODOC: Called R600 in 3.6 + #[cfg(not(feature = "llvm3-6"))] pub fn initialize_amd_gpu(config: &InitializationConfig) { use llvm_sys::target::{LLVMInitializeAMDGPUTarget, LLVMInitializeAMDGPUTargetInfo, LLVMInitializeAMDGPUTargetMC, LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeAMDGPUAsmParser}; @@ -314,6 +344,7 @@ impl Target { } } + #[cfg(not(feature = "llvm3-6"))] pub fn initialize_cpp_backend(config: &InitializationConfig) { use llvm_sys::target::{LLVMInitializeCppBackendTarget, LLVMInitializeCppBackendTargetInfo, LLVMInitializeCppBackendTargetMC}; @@ -441,6 +472,7 @@ impl Target { } // TODOC: Disassembler only supported in LLVM 4.0+ + #[cfg(not(feature = "llvm3-6"))] pub fn initialize_bpf(config: &InitializationConfig) { use llvm_sys::target::{LLVMInitializeBPFTarget, LLVMInitializeBPFTargetInfo, LLVMInitializeBPFTargetMC, LLVMInitializeBPFAsmPrinter}; @@ -860,7 +892,7 @@ impl TargetData { TargetData::new(target_data) } - // REVIEW: Maybe this should be pass_manager.add_target_data()? + // REVIEW: Maybe this should be pass_manager.add_target_data(&target_data)? pub fn add_target_data(&self, pass_manager: &PassManager) { unsafe { LLVMAddTargetData(self.target_data, pass_manager.pass_manager) diff --git a/src/types/array_type.rs b/src/types/array_type.rs index 77980eff7df85..de949052b68b7 100644 --- a/src/types/array_type.rs +++ b/src/types/array_type.rs @@ -86,6 +86,7 @@ impl ArrayType { self.array_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.array_type.print_to_stderr() } diff --git a/src/types/float_type.rs b/src/types/float_type.rs index 9b6272c0cd4b7..2491ac505eb19 100644 --- a/src/types/float_type.rs +++ b/src/types/float_type.rs @@ -126,6 +126,7 @@ impl FloatType { self.float_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.float_type.print_to_stderr() } diff --git a/src/types/fn_type.rs b/src/types/fn_type.rs index dffab54f0b9ec..06e0a2ae7c278 100644 --- a/src/types/fn_type.rs +++ b/src/types/fn_type.rs @@ -65,6 +65,7 @@ impl FunctionType { self.fn_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.fn_type.print_to_stderr() } diff --git a/src/types/int_type.rs b/src/types/int_type.rs index de5af5718764b..e2415c8940164 100644 --- a/src/types/int_type.rs +++ b/src/types/int_type.rs @@ -311,6 +311,7 @@ impl IntType { self.int_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.int_type.print_to_stderr() } diff --git a/src/types/mod.rs b/src/types/mod.rs index c767bf372bd62..bc2451b0f99cf 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -21,7 +21,9 @@ pub use types::vec_type::VectorType; pub use types::void_type::VoidType; pub(crate) use types::traits::AsTypeRef; -use llvm_sys::core::{LLVMAlignOf, LLVMGetTypeContext, LLVMFunctionType, LLVMArrayType, LLVMDumpType, LLVMGetTypeKind, LLVMGetUndef, LLVMPointerType, LLVMPrintTypeToString, LLVMTypeIsSized, LLVMSizeOf, LLVMVectorType, LLVMConstPointerNull}; +#[cfg(not(feature = "llvm3-6"))] +use llvm_sys::core::LLVMDumpType; +use llvm_sys::core::{LLVMAlignOf, LLVMGetTypeContext, LLVMFunctionType, LLVMArrayType, LLVMGetTypeKind, LLVMGetUndef, LLVMPointerType, LLVMPrintTypeToString, LLVMTypeIsSized, LLVMSizeOf, LLVMVectorType, LLVMConstPointerNull}; use llvm_sys::LLVMTypeKind; use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef}; @@ -50,6 +52,7 @@ impl Type { } } + #[cfg(not(feature = "llvm3-6"))] fn print_to_stderr(&self) { unsafe { LLVMDumpType(self.type_); diff --git a/src/types/ptr_type.rs b/src/types/ptr_type.rs index 0adc19b6aa008..bc1faebe033b4 100644 --- a/src/types/ptr_type.rs +++ b/src/types/ptr_type.rs @@ -57,6 +57,7 @@ impl PointerType { self.ptr_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.ptr_type.print_to_stderr() } diff --git a/src/types/struct_type.rs b/src/types/struct_type.rs index 29f52084f64a7..3d2292361d67b 100644 --- a/src/types/struct_type.rs +++ b/src/types/struct_type.rs @@ -1,4 +1,6 @@ -use llvm_sys::core::{LLVMStructGetTypeAtIndex, LLVMConstNamedStruct, LLVMConstStruct, LLVMConstNull, LLVMStructType, LLVMCountStructElementTypes, LLVMGetStructElementTypes, LLVMGetStructName, LLVMIsPackedStruct, LLVMIsOpaqueStruct, LLVMStructSetBody}; +use llvm_sys::core::{LLVMConstNamedStruct, LLVMConstStruct, LLVMConstNull, LLVMStructType, LLVMCountStructElementTypes, LLVMGetStructElementTypes, LLVMGetStructName, LLVMIsPackedStruct, LLVMIsOpaqueStruct, LLVMStructSetBody}; +#[cfg(not(feature = "llvm3-6"))] +use llvm_sys::core::LLVMStructGetTypeAtIndex; use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef}; use std::ffi::CStr; @@ -25,7 +27,7 @@ impl StructType { } // TODO: Would be great to be able to smartly be able to do this by field name - // TODO: LLVM 3.7+ only + #[cfg(not(feature = "llvm3-6"))] pub fn get_field_type_at_index(&self, index: u32) -> Option { // LLVM doesn't seem to just return null if opaque. // TODO: One day, with SubTypes (& maybe specialization?) we could just @@ -40,7 +42,7 @@ impl StructType { } let type_ = unsafe { - LLVMStructGetTypeAtIndex(self.struct_type.type_, index) + LLVMStructGetTypeAtIndex(self.as_type_ref(), index) }; Some(BasicTypeEnum::new(type_)) @@ -130,7 +132,7 @@ impl StructType { pub fn is_packed(&self) -> bool { unsafe { - LLVMIsPackedStruct(self.struct_type.type_) == 1 + LLVMIsPackedStruct(self.as_type_ref()) == 1 } } @@ -138,7 +140,7 @@ impl StructType { // yet assigned (empty array to struct_type) pub fn is_opaque(&self) -> bool { unsafe { - LLVMIsOpaqueStruct(self.struct_type.type_) == 1 + LLVMIsOpaqueStruct(self.as_type_ref()) == 1 } } @@ -183,6 +185,7 @@ impl StructType { self.struct_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.struct_type.print_to_stderr() } diff --git a/src/types/vec_type.rs b/src/types/vec_type.rs index 15379c42a97b5..7fea1b4e1449a 100644 --- a/src/types/vec_type.rs +++ b/src/types/vec_type.rs @@ -80,6 +80,7 @@ impl VectorType { self.vec_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.vec_type.print_to_stderr() } diff --git a/src/types/void_type.rs b/src/types/void_type.rs index 436de0b94e19e..4222f7fcdcff6 100644 --- a/src/types/void_type.rs +++ b/src/types/void_type.rs @@ -52,6 +52,7 @@ impl VoidType { self.void_type.print_to_string() } + #[cfg(not(feature = "llvm3-6"))] pub fn print_to_stderr(&self) { self.void_type.print_to_stderr() } diff --git a/src/values/fn_value.rs b/src/values/fn_value.rs index a172352e8b5a3..99a6a4fc7549c 100644 --- a/src/values/fn_value.rs +++ b/src/values/fn_value.rs @@ -1,5 +1,7 @@ use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyFunction, LLVMViewFunctionCFG, LLVMViewFunctionCFGOnly}; -use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetPersonalityFn, LLVMSetPersonalityFn, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC}; +use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC}; +#[cfg(not(feature = "llvm3-6"))] +use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn}; use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef}; use std::ffi::{CStr, CString}; @@ -259,6 +261,7 @@ impl FunctionValue { // } // } + #[cfg(not(feature = "llvm3-6"))] pub fn get_personality_function(&self) -> Option { let value = unsafe { LLVMGetPersonalityFn(self.as_value_ref()) @@ -267,6 +270,7 @@ impl FunctionValue { FunctionValue::new(value) } + #[cfg(not(feature = "llvm3-6"))] pub fn set_personality_function(&self, personality_fn: &FunctionValue) { unsafe { LLVMSetPersonalityFn(self.as_value_ref(), personality_fn.as_value_ref()) diff --git a/src/values/metadata_value.rs b/src/values/metadata_value.rs index 0d8d8320d301f..f66682676b84b 100644 --- a/src/values/metadata_value.rs +++ b/src/values/metadata_value.rs @@ -9,7 +9,11 @@ use std::fmt; use std::mem::forget; use std::slice::from_raw_parts; -pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 14; // TODO: Varies by version +// TODOC: Varies by version +#[cfg(feature = "llvm3-6")] +pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 12; +#[cfg(feature = "llvm3-7")] +pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 14; #[derive(PartialEq, Eq, Clone, Copy)] pub struct MetadataValue { diff --git a/tests/test_passes.rs b/tests/test_passes.rs index 3bf073212aa50..310d4b77b8cc0 100644 --- a/tests/test_passes.rs +++ b/tests/test_passes.rs @@ -28,7 +28,8 @@ fn test_init_all_passes_for_module() { pass_manager.add_loop_vectorize_pass(); pass_manager.add_slp_vectorize_pass(); pass_manager.add_aggressive_dce_pass(); - pass_manager.add_bit_tracking_dce_pass(); // TODO: 3.7+ only + #[cfg(not(feature = "llvm3-6"))] + pass_manager.add_bit_tracking_dce_pass(); pass_manager.add_alignment_from_assumptions_pass(); pass_manager.add_cfg_simplification_pass(); pass_manager.add_dead_store_elimination_pass(); @@ -111,7 +112,11 @@ fn test_pass_manager_builder() { pass_manager_builder.populate_module_pass_manager(&module_pass_manager); - // REVIEW: Seems like no changes were made, why does it return true? + // REVIEW: Seems to return true in 3.7, even though no changes were made. + // In 3.6 it returns false. LLVM bug? + #[cfg(feature = "llvm3-6")] + assert!(!module_pass_manager.run_on_module(&module)); + #[cfg(not(feature = "llvm3-6"))] assert!(module_pass_manager.run_on_module(&module)); // TODO: Populate LTO pass manager? diff --git a/tests/test_types.rs b/tests/test_types.rs index 51a23deb3ef27..67cf0790e036c 100644 --- a/tests/test_types.rs +++ b/tests/test_types.rs @@ -22,14 +22,17 @@ fn test_struct_type() { assert_eq!(*av_struct.get_context(), context); assert_eq!(av_struct.count_fields(), 2); - let field_1 = av_struct.get_field_type_at_index(0).unwrap(); - let field_2 = av_struct.get_field_type_at_index(1).unwrap(); - - assert!(field_1.is_vector_type()); - assert!(field_2.is_array_type()); - assert!(av_struct.get_field_type_at_index(2).is_none()); - assert!(av_struct.get_field_type_at_index(200).is_none()); - assert_eq!(av_struct.get_field_types(), vec![field_1, field_2]); + #[cfg(not(feature = "llvm3-6"))] + { + let field_1 = av_struct.get_field_type_at_index(0).unwrap(); + let field_2 = av_struct.get_field_type_at_index(1).unwrap(); + + assert!(field_1.is_vector_type()); + assert!(field_2.is_array_type()); + assert!(av_struct.get_field_type_at_index(2).is_none()); + assert!(av_struct.get_field_type_at_index(200).is_none()); + assert_eq!(av_struct.get_field_types(), vec![field_1, field_2]); + } let av_struct = context.struct_type(&[&int_vector, &float_array], true); @@ -41,14 +44,18 @@ fn test_struct_type() { assert_eq!(*av_struct.get_context(), context); assert_eq!(av_struct.count_fields(), 2); - let field_1 = av_struct.get_field_type_at_index(0).unwrap(); - let field_2 = av_struct.get_field_type_at_index(1).unwrap(); + #[cfg(not(feature = "llvm3-6"))] + { + let field_1 = av_struct.get_field_type_at_index(0).unwrap(); + let field_2 = av_struct.get_field_type_at_index(1).unwrap(); + + assert!(field_1.is_vector_type()); + assert!(field_2.is_array_type()); + assert!(av_struct.get_field_type_at_index(2).is_none()); + assert!(av_struct.get_field_type_at_index(200).is_none()); + assert_eq!(av_struct.get_field_types(), vec![field_1, field_2]); + } - assert!(field_1.is_vector_type()); - assert!(field_2.is_array_type()); - assert!(av_struct.get_field_type_at_index(2).is_none()); - assert!(av_struct.get_field_type_at_index(200).is_none()); - assert_eq!(av_struct.get_field_types(), vec![field_1, field_2]); let opaque_struct = context.opaque_struct_type("opaque_struct"); @@ -58,11 +65,15 @@ fn test_struct_type() { assert_eq!(opaque_struct.get_name(), Some(&*CString::new("opaque_struct").unwrap())); assert_eq!(*opaque_struct.get_context(), context); assert_eq!(opaque_struct.count_fields(), 0); - assert!(opaque_struct.get_field_type_at_index(0).is_none()); - assert!(opaque_struct.get_field_type_at_index(1).is_none()); - assert!(opaque_struct.get_field_type_at_index(2).is_none()); - assert!(opaque_struct.get_field_type_at_index(200).is_none()); - assert!(opaque_struct.get_field_types().is_empty()); + + #[cfg(not(feature = "llvm3-6"))] + { + assert!(opaque_struct.get_field_type_at_index(0).is_none()); + assert!(opaque_struct.get_field_type_at_index(1).is_none()); + assert!(opaque_struct.get_field_type_at_index(2).is_none()); + assert!(opaque_struct.get_field_type_at_index(200).is_none()); + assert!(opaque_struct.get_field_types().is_empty()); + } assert!(opaque_struct.set_body(&[&int_vector, &float_array], true)); @@ -75,14 +86,17 @@ fn test_struct_type() { assert_eq!(*no_longer_opaque_struct.get_context(), context); assert_eq!(no_longer_opaque_struct.count_fields(), 2); - let field_1 = no_longer_opaque_struct.get_field_type_at_index(0).unwrap(); - let field_2 = no_longer_opaque_struct.get_field_type_at_index(1).unwrap(); - - assert!(field_1.is_vector_type()); - assert!(field_2.is_array_type()); - assert!(no_longer_opaque_struct.get_field_type_at_index(2).is_none()); - assert!(no_longer_opaque_struct.get_field_type_at_index(200).is_none()); - assert_eq!(no_longer_opaque_struct.get_field_types(), vec![field_1, field_2]); + #[cfg(not(feature = "llvm3-6"))] + { + let field_1 = no_longer_opaque_struct.get_field_type_at_index(0).unwrap(); + let field_2 = no_longer_opaque_struct.get_field_type_at_index(1).unwrap(); + + assert!(field_1.is_vector_type()); + assert!(field_2.is_array_type()); + assert!(no_longer_opaque_struct.get_field_type_at_index(2).is_none()); + assert!(no_longer_opaque_struct.get_field_type_at_index(200).is_none()); + assert_eq!(no_longer_opaque_struct.get_field_types(), vec![field_1, field_2]); + } } #[test] diff --git a/tests/test_values.rs b/tests/test_values.rs index 8c2b6da68e6f9..01966f6394e85 100644 --- a/tests/test_values.rs +++ b/tests/test_values.rs @@ -391,10 +391,14 @@ fn test_metadata() { assert_eq!(MetadataValue::get_kind_id("llvm.mem.parallel_loop_access"), 10); assert_eq!(context.get_kind_id("nonnull"), 11); assert_eq!(MetadataValue::get_kind_id("nonnull"), 11); - assert_eq!(context.get_kind_id("dereferenceable"), 12); - assert_eq!(MetadataValue::get_kind_id("dereferenceable"), 12); - assert_eq!(context.get_kind_id("dereferenceable_or_null"), 13); - assert_eq!(MetadataValue::get_kind_id("dereferenceable_or_null"), 13); + + #[cfg(not(feature = "llvm3-6"))] + { + assert_eq!(context.get_kind_id("dereferenceable"), 12); + assert_eq!(MetadataValue::get_kind_id("dereferenceable"), 12); + assert_eq!(context.get_kind_id("dereferenceable_or_null"), 13); + assert_eq!(MetadataValue::get_kind_id("dereferenceable_or_null"), 13); + } // TODO: Predefined, but only newer versions we don't support yet // assert_eq!(context.get_kind_id("make.implicit"), 14); @@ -682,6 +686,7 @@ fn test_function_value_no_params() { assert!(fn_value.get_first_param().is_none()); assert!(fn_value.get_last_param().is_none()); assert!(fn_value.get_nth_param(0).is_none()); + #[cfg(not(feature = "llvm3-6"))] assert!(fn_value.get_personality_function().is_none()); assert!(!fn_value.is_null()); assert!(!fn_value.is_undef());