Make the source map available as filecheck variables.

This makes it possible to refer to entities defined in the source file,
using the source names prefixed with $.

For example, $v20 refers to the value by that name in the sources, even
if it was renumbered to 'vx0' in the parsed file.
This commit is contained in:
Jakob Stoklund Olesen
2016-09-16 12:49:49 -07:00
parent 77264ead08
commit 88218440a3
2 changed files with 19 additions and 6 deletions

View File

@@ -16,9 +16,9 @@ ebb100(v20: i32):
trap trap
} }
; sameln: function defs() { ; sameln: function defs() {
; nextln: ebb0(vx0: i32): ; nextln: $ebb100($v20: i32):
; nextln: v0 = iconst.i32x8 5 ; nextln: $v1000 = iconst.i32x8 5
; nextln: v1 = f64const 0x1.0000000000000p2 ; nextln: $vx200 = f64const 0x1.0000000000000p2
; nextln: trap ; nextln: trap
; nextln: } ; nextln: }

View File

@@ -4,7 +4,7 @@ use std::result;
use std::borrow::Cow; use std::borrow::Cow;
use cretonne::ir::Function; use cretonne::ir::Function;
use cton_reader::{TestCommand, Details}; use cton_reader::{TestCommand, Details};
use filecheck::{CheckerBuilder, Checker, NO_VARIABLES}; use filecheck::{self, CheckerBuilder, Checker, Value as FCValue};
pub type Result<T> = result::Result<T, String>; pub type Result<T> = result::Result<T, String>;
@@ -51,14 +51,27 @@ pub trait SubTest {
fn run(&self, func: Cow<Function>, context: &Context) -> Result<()>; fn run(&self, func: Cow<Function>, context: &Context) -> Result<()>;
} }
/// Make the parser's source map available as filecheck variables.
///
/// This means that the filecheck directives can refer to entities like `jump $ebb3`, where `$ebb3`
/// will expand to the EBB number that was assigned to `ebb3` in the input source.
///
/// The expanded entity names are wrapped in word boundary regex guards so that 'inst1' doesn't
/// match 'inst10'.
impl<'a> filecheck::VariableMap for Context<'a> {
fn lookup(&self, varname: &str) -> Option<FCValue> {
self.details.map.lookup_str(varname).map(|e| FCValue::Regex(format!(r"\b{}\b", e).into()))
}
}
/// Run filecheck on `text`, using directives extracted from `context`. /// Run filecheck on `text`, using directives extracted from `context`.
pub fn run_filecheck(text: &str, context: &Context) -> Result<()> { pub fn run_filecheck(text: &str, context: &Context) -> Result<()> {
let checker = try!(build_filechecker(&context.details)); let checker = try!(build_filechecker(&context.details));
if try!(checker.check(&text, NO_VARIABLES).map_err(|e| format!("filecheck: {}", e))) { if try!(checker.check(&text, context).map_err(|e| format!("filecheck: {}", e))) {
Ok(()) Ok(())
} else { } else {
// Filecheck mismatch. Emit an explanation as output. // Filecheck mismatch. Emit an explanation as output.
let (_, explain) = try!(checker.explain(&text, NO_VARIABLES) let (_, explain) = try!(checker.explain(&text, context)
.map_err(|e| format!("explain: {}", e))); .map_err(|e| format!("explain: {}", e)));
Err(format!("filecheck failed:\n{}{}", checker, explain)) Err(format!("filecheck failed:\n{}{}", checker, explain))
} }