mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 06:29:05 +00:00
Support referencing variables defined on the same line.
See http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20121126/157198.html and related discussions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169101 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
16
test/FileCheck/var-ref-same-line.txt
Normal file
16
test/FileCheck/var-ref-same-line.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Test for referencing a variable defined on the same line
|
||||||
|
// RUN: FileCheck -input-file %s %s
|
||||||
|
|
||||||
|
op1 r1, r2, r1
|
||||||
|
|
||||||
|
; CHECK: op1 [[REG:r[0-9]+]], {{r[0-9]+}}, [[REG]]
|
||||||
|
|
||||||
|
op3 r1, r2, r1, r2
|
||||||
|
|
||||||
|
; CHECK: op3 [[REG1:r[0-9]+]], [[REG2:r[0-9]+]], [[REG1]], [[REG2]]
|
||||||
|
|
||||||
|
op4 g1, g2, g1
|
||||||
|
|
||||||
|
; Test that parens inside the regex don't confuse FileCheck
|
||||||
|
; CHECK: {{([a-z]+[0-9])+}} [[REG:g[0-9]+]], {{g[0-9]+}}, [[REG]]
|
||||||
|
|
@@ -29,6 +29,9 @@
|
|||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static cl::opt<std::string>
|
static cl::opt<std::string>
|
||||||
@@ -73,11 +76,10 @@ class Pattern {
|
|||||||
/// value of bar at offset 3.
|
/// value of bar at offset 3.
|
||||||
std::vector<std::pair<StringRef, unsigned> > VariableUses;
|
std::vector<std::pair<StringRef, unsigned> > VariableUses;
|
||||||
|
|
||||||
/// VariableDefs - Entries in this vector map to definitions of a variable in
|
/// VariableDefs - Maps definitions of variables to their parenthesized
|
||||||
/// the pattern, e.g. "foo[[bar:.*]]baz". In this case, the RegExStr will
|
/// capture numbers.
|
||||||
/// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1. The
|
/// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
|
||||||
/// index indicates what parenthesized value captures the variable value.
|
std::map<StringRef, unsigned> VariableDefs;
|
||||||
std::vector<std::pair<StringRef, unsigned> > VariableDefs;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -105,7 +107,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
|
static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
|
||||||
bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM);
|
bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
|
||||||
|
void AddBackrefToRegEx(unsigned BackrefNum);
|
||||||
|
|
||||||
/// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
|
/// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
|
||||||
/// matching this pattern at the start of \arg Buffer; a distance of zero
|
/// matching this pattern at the start of \arg Buffer; a distance of zero
|
||||||
@@ -238,12 +241,25 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM,
|
|||||||
|
|
||||||
// Handle [[foo]].
|
// Handle [[foo]].
|
||||||
if (NameEnd == StringRef::npos) {
|
if (NameEnd == StringRef::npos) {
|
||||||
VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
|
// Handle variables that were defined earlier on the same line by
|
||||||
|
// emitting a backreference.
|
||||||
|
if (VariableDefs.find(Name) != VariableDefs.end()) {
|
||||||
|
unsigned VarParenNum = VariableDefs[Name];
|
||||||
|
if (VarParenNum < 1 || VarParenNum > 9) {
|
||||||
|
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
|
||||||
|
SourceMgr::DK_Error,
|
||||||
|
"Can't back-reference more than 9 variables");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
AddBackrefToRegEx(VarParenNum);
|
||||||
|
} else {
|
||||||
|
VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle [[foo:.*]].
|
// Handle [[foo:.*]].
|
||||||
VariableDefs.push_back(std::make_pair(Name, CurParen));
|
VariableDefs[Name] = CurParen;
|
||||||
RegExStr += '(';
|
RegExStr += '(';
|
||||||
++CurParen;
|
++CurParen;
|
||||||
|
|
||||||
@@ -291,21 +307,28 @@ void Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
|
bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
|
||||||
SourceMgr &SM) {
|
SourceMgr &SM) {
|
||||||
Regex R(RegexStr);
|
Regex R(RS);
|
||||||
std::string Error;
|
std::string Error;
|
||||||
if (!R.isValid(Error)) {
|
if (!R.isValid(Error)) {
|
||||||
SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), SourceMgr::DK_Error,
|
SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
|
||||||
"invalid regex: " + Error);
|
"invalid regex: " + Error);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegExStr += RegexStr.str();
|
RegExStr += RS.str();
|
||||||
CurParen += R.getNumMatches();
|
CurParen += R.getNumMatches();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
|
||||||
|
assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
|
||||||
|
std::string Backref = std::string("\\") +
|
||||||
|
std::string(1, '0' + BackrefNum);
|
||||||
|
RegExStr += Backref;
|
||||||
|
}
|
||||||
|
|
||||||
bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
|
bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
|
||||||
// The only supported expression is @LINE([\+-]\d+)?
|
// The only supported expression is @LINE([\+-]\d+)?
|
||||||
if (!Expr.startswith("@LINE"))
|
if (!Expr.startswith("@LINE"))
|
||||||
@@ -388,10 +411,11 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
|
|||||||
StringRef FullMatch = MatchInfo[0];
|
StringRef FullMatch = MatchInfo[0];
|
||||||
|
|
||||||
// If this defines any variables, remember their values.
|
// If this defines any variables, remember their values.
|
||||||
for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) {
|
for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(),
|
||||||
assert(VariableDefs[i].second < MatchInfo.size() &&
|
E = VariableDefs.end();
|
||||||
"Internal paren error");
|
I != E; ++I) {
|
||||||
VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second];
|
assert(I->second < MatchInfo.size() && "Internal paren error");
|
||||||
|
VariableTable[I->first] = MatchInfo[I->second];
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchLen = FullMatch.size();
|
MatchLen = FullMatch.size();
|
||||||
|
Reference in New Issue
Block a user