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_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, TargetIsa}; 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(Box<dyn TargetIsa>), 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 match parse_options( 76 flag_set.iter().map(|x| x.as_str()), 77 &mut flag_builder, 78 Location { line_number: 0 }, 79 ) { 80 Err(ParseOptionError::UnknownFlag { name, .. }) => { 81 unknown_settings.push(name); 82 } 83 Err(ParseOptionError::UnknownValue { name, value, .. }) => { 84 unknown_settings.push(format!("{}={}", name, value)); 85 } 86 Err(ParseOptionError::Generic(err)) => return Err(err.into()), 87 Ok(()) => {} 88 } 89 90 let mut words = flag_triple.trim().split_whitespace(); 91 // Look for `target foo`. 92 if let Some(triple_name) = words.next() { 93 let triple = match Triple::from_str(triple_name) { 94 Ok(triple) => triple, 95 Err(parse_error) => return Err(Error::from(parse_error)), 96 }; 97 98 let mut isa_builder = isa::lookup(triple).map_err(|err| match err { 99 isa::LookupError::SupportDisabled => { 100 anyhow::anyhow!("support for triple '{}' is disabled", triple_name) 101 } 102 isa::LookupError::Unsupported => anyhow::anyhow!( 103 "support for triple '{}' is not implemented yet", 104 triple_name 105 ), 106 })?; 107 108 // Try to parse system-wide unknown settings as target-specific settings. 109 parse_options( 110 unknown_settings.iter().map(|x| x.as_str()), 111 &mut isa_builder, 112 Location { line_number: 0 }, 113 ) 114 .map_err(ParseError::from)?; 115 116 // Apply the ISA-specific settings to `isa_builder`. 117 parse_options(words, &mut isa_builder, Location { line_number: 0 }) 118 .map_err(ParseError::from)?; 119 120 Ok(OwnedFlagsOrIsa::Isa( 121 isa_builder.finish(settings::Flags::new(flag_builder))?, 122 )) 123 } else { 124 if !unknown_settings.is_empty() { 125 anyhow::bail!("unknown settings: '{}'", unknown_settings.join("', '")); 126 } 127 Ok(OwnedFlagsOrIsa::Flags(settings::Flags::new(flag_builder))) 128 } 129 } 130