1 //! Cranelift file reader library. 2 //! 3 //! The `cranelift_reader` library supports reading .clif files. This functionality is needed for 4 //! testing Cranelift, but is not essential for a JIT compiler. 5 6 #![deny( 7 missing_docs, 8 trivial_numeric_casts, 9 unused_extern_crates, 10 unstable_features 11 )] 12 #![warn(unused_import_braces)] 13 #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] 14 #![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))] 15 #![cfg_attr( 16 feature = "cargo-clippy", 17 warn( 18 clippy::float_arithmetic, 19 clippy::mut_mut, 20 clippy::nonminimal_bool, 21 clippy::map_unwrap_or, 22 clippy::clippy::print_stdout, 23 clippy::unicode_not_nfc, 24 clippy::use_self 25 ) 26 )] 27 28 pub use crate::error::{Location, ParseError, ParseResult}; 29 pub use crate::isaspec::{parse_option, parse_options, IsaSpec, ParseOptionError}; 30 pub use crate::parser::{parse_functions, parse_run_command, parse_test, ParseOptions}; 31 pub use crate::run_command::{Comparison, Invocation, RunCommand}; 32 pub use crate::sourcemap::SourceMap; 33 pub use crate::testcommand::{TestCommand, TestOption}; 34 pub use crate::testfile::{Comment, Details, Feature, TestFile}; 35 36 mod error; 37 mod isaspec; 38 mod lexer; 39 mod parser; 40 mod run_command; 41 mod sourcemap; 42 mod testcommand; 43 mod testfile; 44 45 use anyhow::{Error, Result}; 46 use cranelift_codegen::isa::{self, OwnedTargetIsa}; 47 use cranelift_codegen::settings::{self, FlagsOrIsa}; 48 use std::str::FromStr; 49 use target_lexicon::Triple; 50 51 /// Like `FlagsOrIsa`, but holds ownership. 52 #[allow(missing_docs)] 53 pub enum OwnedFlagsOrIsa { 54 Flags(settings::Flags), 55 Isa(OwnedTargetIsa), 56 } 57 58 impl OwnedFlagsOrIsa { 59 /// Produce a FlagsOrIsa reference. 60 pub fn as_fisa(&self) -> FlagsOrIsa { 61 match *self { 62 Self::Flags(ref flags) => FlagsOrIsa::from(flags), 63 Self::Isa(ref isa) => FlagsOrIsa::from(&**isa), 64 } 65 } 66 } 67 68 /// Parse "set" and "triple" commands. 69 pub fn parse_sets_and_triple(flag_set: &[String], flag_triple: &str) -> Result<OwnedFlagsOrIsa> { 70 let mut flag_builder = settings::builder(); 71 72 // Collect unknown system-wide settings, so we can try to parse them as target specific 73 // settings, if a target is defined. 74 let mut unknown_settings = Vec::new(); 75 for flag in flag_set { 76 match parse_option(flag, &mut flag_builder, Location { line_number: 0 }) { 77 Err(ParseOptionError::UnknownFlag { name, .. }) => { 78 unknown_settings.push(name); 79 } 80 Err(ParseOptionError::UnknownValue { name, value, .. }) => { 81 unknown_settings.push(format!("{}={}", name, value)); 82 } 83 Err(ParseOptionError::Generic(err)) => return Err(err.into()), 84 Ok(()) => {} 85 } 86 } 87 88 let mut words = flag_triple.trim().split_whitespace(); 89 // Look for `target foo`. 90 if let Some(triple_name) = words.next() { 91 let triple = match Triple::from_str(triple_name) { 92 Ok(triple) => triple, 93 Err(parse_error) => return Err(Error::from(parse_error)), 94 }; 95 96 let mut isa_builder = isa::lookup(triple).map_err(|err| match err { 97 isa::LookupError::SupportDisabled => { 98 anyhow::anyhow!("support for triple '{}' is disabled", triple_name) 99 } 100 isa::LookupError::Unsupported => anyhow::anyhow!( 101 "support for triple '{}' is not implemented yet", 102 triple_name 103 ), 104 })?; 105 106 // Try to parse system-wide unknown settings as target-specific settings. 107 parse_options( 108 unknown_settings.iter().map(|x| x.as_str()), 109 &mut isa_builder, 110 Location { line_number: 0 }, 111 ) 112 .map_err(ParseError::from)?; 113 114 // Apply the ISA-specific settings to `isa_builder`. 115 parse_options(words, &mut isa_builder, Location { line_number: 0 }) 116 .map_err(ParseError::from)?; 117 118 Ok(OwnedFlagsOrIsa::Isa( 119 isa_builder.finish(settings::Flags::new(flag_builder))?, 120 )) 121 } else { 122 if !unknown_settings.is_empty() { 123 anyhow::bail!("unknown settings: '{}'", unknown_settings.join("', '")); 124 } 125 Ok(OwnedFlagsOrIsa::Flags(settings::Flags::new(flag_builder))) 126 } 127 } 128