llvm.org GIT mirror llvm / 9756ca7
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 Eli Bendersky 8 years ago
2 changed file(s) with 56 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
0 // Test for referencing a variable defined on the same line
1 // RUN: FileCheck -input-file %s %s
2
3 op1 r1, r2, r1
4
5 ; CHECK: op1 [[REG:r[0-9]+]], {{r[0-9]+}}, [[REG]]
6
7 op3 r1, r2, r1, r2
8
9 ; CHECK: op3 [[REG1:r[0-9]+]], [[REG2:r[0-9]+]], [[REG1]], [[REG2]]
10
11 op4 g1, g2, g1
12
13 ; Test that parens inside the regex don't confuse FileCheck
14 ; CHECK: {{([a-z]+[0-9])+}} [[REG:g[0-9]+]], {{g[0-9]+}}, [[REG]]
15
2828 #include "llvm/ADT/StringExtras.h"
2929 #include "llvm/ADT/StringMap.h"
3030 #include
31 #include
32 #include
33 #include
3134 using namespace llvm;
3235
3336 static cl::opt
7275 /// value of bar at offset 3.
7376 std::vector > VariableUses;
7477
75 /// VariableDefs - Entries in this vector map to definitions of a variable in
76 /// the pattern, e.g. "foo[[bar:.*]]baz". In this case, the RegExStr will
77 /// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1. The
78 /// index indicates what parenthesized value captures the variable value.
79 std::vector > VariableDefs;
78 /// VariableDefs - Maps definitions of variables to their parenthesized
79 /// capture numbers.
80 /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
81 std::map VariableDefs;
8082
8183 public:
8284
104106
105107 private:
106108 static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
107 bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM);
109 bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
110 void AddBackrefToRegEx(unsigned BackrefNum);
108111
109112 /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
110113 /// matching this pattern at the start of \arg Buffer; a distance of zero
237240
238241 // Handle [[foo]].
239242 if (NameEnd == StringRef::npos) {
240 VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
243 // Handle variables that were defined earlier on the same line by
244 // emitting a backreference.
245 if (VariableDefs.find(Name) != VariableDefs.end()) {
246 unsigned VarParenNum = VariableDefs[Name];
247 if (VarParenNum < 1 || VarParenNum > 9) {
248 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
249 SourceMgr::DK_Error,
250 "Can't back-reference more than 9 variables");
251 return true;
252 }
253 AddBackrefToRegEx(VarParenNum);
254 } else {
255 VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
256 }
241257 continue;
242258 }
243259
244260 // Handle [[foo:.*]].
245 VariableDefs.push_back(std::make_pair(Name, CurParen));
261 VariableDefs[Name] = CurParen;
246262 RegExStr += '(';
247263 ++CurParen;
248264
290306 }
291307 }
292308
293 bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
309 bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
294310 SourceMgr &SM) {
295 Regex R(RegexStr);
311 Regex R(RS);
296312 std::string Error;
297313 if (!R.isValid(Error)) {
298 SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), SourceMgr::DK_Error,
314 SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
299315 "invalid regex: " + Error);
300316 return true;
301317 }
302318
303 RegExStr += RegexStr.str();
319 RegExStr += RS.str();
304320 CurParen += R.getNumMatches();
305321 return false;
322 }
323
324 void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
325 assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
326 std::string Backref = std::string("\\") +
327 std::string(1, '0' + BackrefNum);
328 RegExStr += Backref;
306329 }
307330
308331 bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
387410 StringRef FullMatch = MatchInfo[0];
388411
389412 // If this defines any variables, remember their values.
390 for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) {
391 assert(VariableDefs[i].second < MatchInfo.size() &&
392 "Internal paren error");
393 VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second];
413 for (std::map::const_iterator I = VariableDefs.begin(),
414 E = VariableDefs.end();
415 I != E; ++I) {
416 assert(I->second < MatchInfo.size() && "Internal paren error");
417 VariableTable[I->first] = MatchInfo[I->second];
394418 }
395419
396420 MatchLen = FullMatch.size();