Skip to content

Turn on FileCheck Variables #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions Tests/LLVMTests/FileCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,21 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
return contents
}

private final class BoxedTable {
var table : [String:String] = [:]

init() {}

subscript(_ i : String) -> String? {
set {
self.table[i] = newValue!
}
get {
return self.table[i]
}
}
}

/// Check the input to FileCheck provided in the \p Buffer against the \p
/// CheckStrings read from the check file.
///
Expand All @@ -416,7 +431,7 @@ private func check(input b : String, against checkStrings : [CheckString]) -> Bo
var failedChecks = false

// This holds all the current filecheck variables.
var variableTable = [String:String]()
var variableTable = BoxedTable()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Box<T>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered it, then realized I only wrote this thing because the C++ just throws a reference to this dictionary everywhere so I only need reference semantics until I can find a way to remove the abstraction altogether.


var i = 0
var j = 0
Expand Down Expand Up @@ -604,7 +619,7 @@ private class Pattern {
///
/// The \p VariableTable StringMap provides the current values of filecheck
/// variables and is updated if this match defines new values.
func match(_ buffer : String, _ variableTable : [String:String]) -> (Int, Int)? {
func match(_ buffer : String, _ variableTable : BoxedTable) -> (Int, Int)? {
var matchLen : Int = 0
// If this is the EOF pattern, match it immediately.
if self.type == .EOF {
Expand All @@ -626,9 +641,9 @@ private class Pattern {
// If there are variable uses, we need to create a temporary string with the
// actual value.
var regExToMatch = self.regExPattern
if !variableUses.isEmpty {
if !self.variableUses.isEmpty {
var insertOffset = 0
for (v, offset) in variableUses {
for (v, offset) in self.variableUses {
var value : String = ""

if let c = v.characters.first, c == "@" {
Expand Down Expand Up @@ -663,9 +678,21 @@ private class Pattern {
}

// If this defines any variables, remember their values.
for (_, index) in self.variableDefs {
assert(index < matchInfo.count, "Internal paren error")
// VariableTable[VariableDef.0] = MatchInfo[VariableDef.second]
for (v, index) in self.variableDefs {
assert(index < fullMatch.numberOfRanges, "Internal paren error")
#if os(macOS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sad!

let r = fullMatch.rangeAt(index)
#else
let r = fullMatch.range(at: index)
#endif
variableTable[v] = buffer.substring(
with: Range<String.Index>(
uncheckedBounds: (
buffer.index(buffer.startIndex, offsetBy: r.location),
buffer.index(buffer.startIndex, offsetBy: NSMaxRange(r))
)
)
)
}

matchLen = fullMatch.range.length
Expand Down Expand Up @@ -829,7 +856,7 @@ private class Pattern {
if let end = nameEnd?.lowerBound {
name = matchStr.substring(to: end)
} else {
name = ""
name = matchStr
}

if name.isEmpty {
Expand Down Expand Up @@ -868,14 +895,14 @@ private class Pattern {
guard let ne = nameEnd else {
// Handle variables that were defined earlier on the same line by
// emitting a backreference.
if let VarParenNum = self.variableDefs[name] {
if VarParenNum < 1 || VarParenNum > 9 {
if let varParenNum = self.variableDefs[name] {
if varParenNum < 1 || varParenNum > 9 {
diagnose(.error, diagLoc, "Can't back-reference more than 9 variables")
return true
}
self.addBackrefToRegEx(VarParenNum)
self.addBackrefToRegEx(varParenNum)
} else {
variableUses.append((name, regExPattern.utf8.count))
variableUses.append((name, regExPattern.characters.count))
}
continue
}
Expand All @@ -899,6 +926,9 @@ private class Pattern {
if let fixedMatchEnd = mino(patternStr.range(of: "{{")?.lowerBound, patternStr.range(of: "[[")?.lowerBound) {
self.regExPattern += NSRegularExpression.escapedPattern(for: patternStr.substring(to: fixedMatchEnd))
patternStr = patternStr.substring(from: fixedMatchEnd)
} else {
// No more matches, time to quit.
break
}
}

Expand Down Expand Up @@ -958,7 +988,7 @@ private struct CheckString {
let dagNotStrings : Array<Pattern> = []

/// Match check string and its "not strings" and/or "dag strings".
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : [String:String]) -> (Int, Int)? {
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : BoxedTable) -> (Int, Int)? {
var lastPos = 0

// IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
Expand Down Expand Up @@ -1092,11 +1122,11 @@ private struct CheckString {
}

/// Verify there's no "not strings" in the given buffer.
private func checkNot(_ buffer : String, _ notStrings : [Pattern], _ VariableTable : [String:String]) -> Bool {
private func checkNot(_ buffer : String, _ notStrings : [Pattern], _ variableTable : BoxedTable) -> Bool {
for pat in notStrings {
assert(pat.type == .not, "Expect CHECK-NOT!")

guard let (Pos, _)/*(Pos, MatchLen)*/ = pat.match(buffer, VariableTable) else {
guard let (Pos, _)/*(Pos, MatchLen)*/ = pat.match(buffer, variableTable) else {
continue
}
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
Expand All @@ -1111,7 +1141,7 @@ private struct CheckString {
}

/// Match "dag strings" and their mixed "not strings".
func checkDAG(_ buffer : String, _ variableTable : [String:String]) -> Int? {
func checkDAG(_ buffer : String, _ variableTable : BoxedTable) -> Int? {
var notStrings = [Pattern]()
if dagNotStrings.isEmpty {
return 0
Expand Down
20 changes: 10 additions & 10 deletions Tests/LLVMTests/IRBuilderSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import Foundation
class IRBuilderSpec : XCTestCase {
func testIRBuilder() {
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["IRBUILDER"]) {
// IRBUILDER: ; ModuleID = 'IRBuilderTest'
// IRBUILDER-NEXT: source_filename = "IRBuilderTest"
// IRBUILDER: ; ModuleID = '[[ModuleName:IRBuilderTest]]'
// IRBUILDER-NEXT: source_filename = "[[ModuleName]]"
let module = Module(name: "IRBuilderTest")
let builder = IRBuilder(module: module)
// IRBUILDER: define void @main() {
Expand All @@ -25,8 +25,8 @@ class IRBuilderSpec : XCTestCase {
// MARK: Arithmetic Instructions

XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["IRBUILDERARITH"]) {
// IRBUILDERARITH: ; ModuleID = 'IRBuilderTest'
// IRBUILDERARITH-NEXT: source_filename = "IRBuilderTest"
// IRBUILDERARITH: ; ModuleID = '[[ModuleName:IRBuilderTest]]'
// IRBUILDERARITH-NEXT: source_filename = "[[ModuleName]]"
let module = Module(name: "IRBuilderTest")
let builder = IRBuilder(module: module)

Expand Down Expand Up @@ -91,8 +91,8 @@ class IRBuilderSpec : XCTestCase {

// MARK: Integer comparisons
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["IRBUILDERCMP"]) {
// IRBUILDERCMP: ; ModuleID = 'IRBuilderTest'
// IRBUILDERCMP-NEXT: source_filename = "IRBuilderTest"
// IRBUILDERCMP: ; ModuleID = '[[ModuleName:IRBuilderTest]]'
// IRBUILDERCMP-NEXT: source_filename = "[[ModuleName]]"
let module = Module(name: "IRBuilderTest")
let builder = IRBuilder(module: module)

Expand Down Expand Up @@ -145,8 +145,8 @@ class IRBuilderSpec : XCTestCase {

// MARK: Float comparisons
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["IRBUILDERFCMP"]) {
// IRBUILDERFCMP: ; ModuleID = 'IRBuilderTest'
// IRBUILDERFCMP-NEXT: source_filename = "IRBuilderTest"
// IRBUILDERFCMP: ; ModuleID = '[[ModuleName:IRBuilderTest]]'
// IRBUILDERFCMP-NEXT: source_filename = "[[ModuleName]]"
let module = Module(name: "IRBuilderTest")
let builder = IRBuilder(module: module)

Expand Down Expand Up @@ -203,8 +203,8 @@ class IRBuilderSpec : XCTestCase {
})

XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["CONTROLFLOW"]) {
// CONTROLFLOW: ; ModuleID = 'IRBuilderTest'
// CONTROLFLOW-NEXT: source_filename = "IRBuilderTest"
// CONTROLFLOW: ; ModuleID = '[[ModuleName:IRBuilderTest]]'
// CONTROLFLOW-NEXT: source_filename = "[[ModuleName]]"
let module = Module(name: "IRBuilderTest")
let builder = IRBuilder(module: module)

Expand Down