LLVM  10.0.0svn
FileCheck.cpp
Go to the documentation of this file.
1 //===- FileCheck.cpp - Check that File's Contents match what is expected --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // FileCheck does a line-by line check of a file that validates whether it
10 // contains the expected content. This is useful for regression tests etc.
11 //
12 // This file implements most of the API that will be used by the FileCheck utility
13 // as well as various unittests.
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/Support/FileCheck.h"
17 #include "llvm/ADT/StringSet.h"
18 #include "llvm/ADT/Twine.h"
20 #include <cstdint>
21 #include <list>
22 #include <tuple>
23 #include <utility>
24 
25 using namespace llvm;
26 
28  Optional<uint64_t> Value = NumericVariable->getValue();
29  if (Value)
30  return *Value;
31 
32  return make_error<FileCheckUndefVarError>(Name);
33 }
34 
36  Expected<uint64_t> LeftOp = LeftOperand->eval();
37  Expected<uint64_t> RightOp = RightOperand->eval();
38 
39  // Bubble up any error (e.g. undefined variables) in the recursive
40  // evaluation.
41  if (!LeftOp || !RightOp) {
42  Error Err = Error::success();
43  if (!LeftOp)
44  Err = joinErrors(std::move(Err), LeftOp.takeError());
45  if (!RightOp)
46  Err = joinErrors(std::move(Err), RightOp.takeError());
47  return std::move(Err);
48  }
49 
50  return EvalBinop(*LeftOp, *RightOp);
51 }
52 
54  Expected<uint64_t> EvaluatedValue = ExpressionAST->eval();
55  if (!EvaluatedValue)
56  return EvaluatedValue.takeError();
57  return utostr(*EvaluatedValue);
58 }
59 
61  // Look up the value and escape it so that we can put it into the regex.
62  Expected<StringRef> VarVal = Context->getPatternVarValue(FromStr);
63  if (!VarVal)
64  return VarVal.takeError();
65  return Regex::escape(*VarVal);
66 }
67 
69  return C == '_' || isalpha(C);
70 }
71 
74  if (Str.empty())
75  return FileCheckErrorDiagnostic::get(SM, Str, "empty variable name");
76 
77  bool ParsedOneChar = false;
78  unsigned I = 0;
79  bool IsPseudo = Str[0] == '@';
80 
81  // Global vars start with '$'.
82  if (Str[0] == '$' || IsPseudo)
83  ++I;
84 
85  for (unsigned E = Str.size(); I != E; ++I) {
86  if (!ParsedOneChar && !isValidVarNameStart(Str[I]))
87  return FileCheckErrorDiagnostic::get(SM, Str, "invalid variable name");
88 
89  // Variable names are composed of alphanumeric characters and underscores.
90  if (Str[I] != '_' && !isalnum(Str[I]))
91  break;
92  ParsedOneChar = true;
93  }
94 
95  StringRef Name = Str.take_front(I);
96  Str = Str.substr(I);
97  return VariableProperties {Name, IsPseudo};
98 }
99 
100 // StringRef holding all characters considered as horizontal whitespaces by
101 // FileCheck input canonicalization.
102 constexpr StringLiteral SpaceChars = " \t";
103 
104 // Parsing helper function that strips the first character in S and returns it.
105 static char popFront(StringRef &S) {
106  char C = S.front();
107  S = S.drop_front();
108  return C;
109 }
110 
114 
116 FileCheckPattern::parseNumericVariableDefinition(
118  Optional<size_t> LineNumber, const SourceMgr &SM) {
119  Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM);
120  if (!ParseVarResult)
121  return ParseVarResult.takeError();
122  StringRef Name = ParseVarResult->Name;
123 
124  if (ParseVarResult->IsPseudo)
126  SM, Name, "definition of pseudo numeric variable unsupported");
127 
128  // Detect collisions between string and numeric variables when the latter
129  // is created later than the former.
130  if (Context->DefinedVariableTable.find(Name) !=
131  Context->DefinedVariableTable.end())
133  SM, Name, "string variable with name '" + Name + "' already exists");
134 
135  Expr = Expr.ltrim(SpaceChars);
136  if (!Expr.empty())
138  SM, Expr, "unexpected characters after numeric variable name");
139 
140  FileCheckNumericVariable *DefinedNumericVariable;
141  auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
142  if (VarTableIter != Context->GlobalNumericVariableTable.end())
143  DefinedNumericVariable = VarTableIter->second;
144  else
145  DefinedNumericVariable = Context->makeNumericVariable(Name, LineNumber);
146 
147  return DefinedNumericVariable;
148 }
149 
151 FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
152  Optional<size_t> LineNumber,
153  FileCheckPatternContext *Context,
154  const SourceMgr &SM) {
155  if (IsPseudo && !Name.equals("@LINE"))
157  SM, Name, "invalid pseudo numeric variable '" + Name + "'");
158 
159  // Numeric variable definitions and uses are parsed in the order in which
160  // they appear in the CHECK patterns. For each definition, the pointer to the
161  // class instance of the corresponding numeric variable definition is stored
162  // in GlobalNumericVariableTable in parsePattern. Therefore, if the pointer
163  // we get below is null, it means no such variable was defined before. When
164  // that happens, we create a dummy variable so that parsing can continue. All
165  // uses of undefined variables, whether string or numeric, are then diagnosed
166  // in printSubstitutions() after failing to match.
167  auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
168  FileCheckNumericVariable *NumericVariable;
169  if (VarTableIter != Context->GlobalNumericVariableTable.end())
170  NumericVariable = VarTableIter->second;
171  else {
172  NumericVariable = Context->makeNumericVariable(Name);
173  Context->GlobalNumericVariableTable[Name] = NumericVariable;
174  }
175 
176  Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber();
177  if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber)
179  SM, Name,
180  "numeric variable '" + Name +
181  "' defined earlier in the same CHECK directive");
182 
183  return std::make_unique<FileCheckNumericVariableUse>(Name, NumericVariable);
184 }
185 
187 FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO,
188  Optional<size_t> LineNumber,
189  FileCheckPatternContext *Context,
190  const SourceMgr &SM) {
191  if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) {
192  // Try to parse as a numeric variable use.
194  parseVariable(Expr, SM);
195  if (ParseVarResult)
196  return parseNumericVariableUse(ParseVarResult->Name,
197  ParseVarResult->IsPseudo, LineNumber,
198  Context, SM);
199  if (AO == AllowedOperand::LineVar)
200  return ParseVarResult.takeError();
201  // Ignore the error and retry parsing as a literal.
202  consumeError(ParseVarResult.takeError());
203  }
204 
205  // Otherwise, parse it as a literal.
206  uint64_t LiteralValue;
207  if (!Expr.consumeInteger(/*Radix=*/10, LiteralValue))
208  return std::make_unique<FileCheckExpressionLiteral>(LiteralValue);
209 
210  return FileCheckErrorDiagnostic::get(SM, Expr,
211  "invalid operand format '" + Expr + "'");
212 }
213 
214 static uint64_t add(uint64_t LeftOp, uint64_t RightOp) {
215  return LeftOp + RightOp;
216 }
217 
218 static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) {
219  return LeftOp - RightOp;
220 }
221 
222 Expected<std::unique_ptr<FileCheckExpressionAST>> FileCheckPattern::parseBinop(
223  StringRef &Expr, std::unique_ptr<FileCheckExpressionAST> LeftOp,
224  bool IsLegacyLineExpr, Optional<size_t> LineNumber,
225  FileCheckPatternContext *Context, const SourceMgr &SM) {
226  Expr = Expr.ltrim(SpaceChars);
227  if (Expr.empty())
228  return std::move(LeftOp);
229 
230  // Check if this is a supported operation and select a function to perform
231  // it.
232  SMLoc OpLoc = SMLoc::getFromPointer(Expr.data());
233  char Operator = popFront(Expr);
234  binop_eval_t EvalBinop;
235  switch (Operator) {
236  case '+':
237  EvalBinop = add;
238  break;
239  case '-':
240  EvalBinop = sub;
241  break;
242  default:
244  SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'");
245  }
246 
247  // Parse right operand.
248  Expr = Expr.ltrim(SpaceChars);
249  if (Expr.empty())
250  return FileCheckErrorDiagnostic::get(SM, Expr,
251  "missing operand in expression");
252  // The second operand in a legacy @LINE expression is always a literal.
253  AllowedOperand AO =
254  IsLegacyLineExpr ? AllowedOperand::Literal : AllowedOperand::Any;
256  parseNumericOperand(Expr, AO, LineNumber, Context, SM);
257  if (!RightOpResult)
258  return RightOpResult;
259 
260  Expr = Expr.ltrim(SpaceChars);
261  return std::make_unique<FileCheckASTBinop>(EvalBinop, std::move(LeftOp),
262  std::move(*RightOpResult));
263 }
264 
267  StringRef Expr,
268  Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
269  bool IsLegacyLineExpr, Optional<size_t> LineNumber,
270  FileCheckPatternContext *Context, const SourceMgr &SM) {
271  std::unique_ptr<FileCheckExpressionAST> ExpressionAST = nullptr;
272  StringRef DefExpr = StringRef();
273  DefinedNumericVariable = None;
274  // Save variable definition expression if any.
275  size_t DefEnd = Expr.find(':');
276  if (DefEnd != StringRef::npos) {
277  DefExpr = Expr.substr(0, DefEnd);
278  Expr = Expr.substr(DefEnd + 1);
279  }
280 
281  // Parse the expression itself.
282  Expr = Expr.ltrim(SpaceChars);
283  if (!Expr.empty()) {
284  // The first operand in a legacy @LINE expression is always the @LINE
285  // pseudo variable.
286  AllowedOperand AO =
287  IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
289  parseNumericOperand(Expr, AO, LineNumber, Context, SM);
290  while (ParseResult && !Expr.empty()) {
291  ParseResult = parseBinop(Expr, std::move(*ParseResult), IsLegacyLineExpr,
292  LineNumber, Context, SM);
293  // Legacy @LINE expressions only allow 2 operands.
294  if (ParseResult && IsLegacyLineExpr && !Expr.empty())
296  SM, Expr,
297  "unexpected characters at end of expression '" + Expr + "'");
298  }
299  if (!ParseResult)
300  return ParseResult;
301  ExpressionAST = std::move(*ParseResult);
302  }
303 
304  // Parse the numeric variable definition.
305  if (DefEnd != StringRef::npos) {
306  DefExpr = DefExpr.ltrim(SpaceChars);
308  parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM);
309 
310  if (!ParseResult)
311  return ParseResult.takeError();
312  DefinedNumericVariable = *ParseResult;
313  }
314 
315  return std::move(ExpressionAST);
316 }
317 
319  SourceMgr &SM,
320  const FileCheckRequest &Req) {
321  bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot;
322 
323  PatternLoc = SMLoc::getFromPointer(PatternStr.data());
324 
325  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
326  // Ignore trailing whitespace.
327  while (!PatternStr.empty() &&
328  (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
329  PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
330 
331  // Check that there is something on the line.
332  if (PatternStr.empty() && CheckTy != Check::CheckEmpty) {
333  SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
334  "found empty check string with prefix '" + Prefix + ":'");
335  return true;
336  }
337 
338  if (!PatternStr.empty() && CheckTy == Check::CheckEmpty) {
339  SM.PrintMessage(
340  PatternLoc, SourceMgr::DK_Error,
341  "found non-empty check string for empty check with prefix '" + Prefix +
342  ":'");
343  return true;
344  }
345 
346  if (CheckTy == Check::CheckEmpty) {
347  RegExStr = "(\n$)";
348  return false;
349  }
350 
351  // Check to see if this is a fixed string, or if it has regex pieces.
352  if (!MatchFullLinesHere &&
353  (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos &&
354  PatternStr.find("[[") == StringRef::npos))) {
355  FixedStr = PatternStr;
356  return false;
357  }
358 
359  if (MatchFullLinesHere) {
360  RegExStr += '^';
361  if (!Req.NoCanonicalizeWhiteSpace)
362  RegExStr += " *";
363  }
364 
365  // Paren value #0 is for the fully matched string. Any new parenthesized
366  // values add from there.
367  unsigned CurParen = 1;
368 
369  // Otherwise, there is at least one regex piece. Build up the regex pattern
370  // by escaping scary characters in fixed strings, building up one big regex.
371  while (!PatternStr.empty()) {
372  // RegEx matches.
373  if (PatternStr.startswith("{{")) {
374  // This is the start of a regex match. Scan for the }}.
375  size_t End = PatternStr.find("}}");
376  if (End == StringRef::npos) {
377  SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
379  "found start of regex string with no end '}}'");
380  return true;
381  }
382 
383  // Enclose {{}} patterns in parens just like [[]] even though we're not
384  // capturing the result for any purpose. This is required in case the
385  // expression contains an alternation like: CHECK: abc{{x|z}}def. We
386  // want this to turn into: "abc(x|z)def" not "abcx|zdef".
387  RegExStr += '(';
388  ++CurParen;
389 
390  if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM))
391  return true;
392  RegExStr += ')';
393 
394  PatternStr = PatternStr.substr(End + 2);
395  continue;
396  }
397 
398  // String and numeric substitution blocks. Pattern substitution blocks come
399  // in two forms: [[foo:.*]] and [[foo]]. The former matches .* (or some
400  // other regex) and assigns it to the string variable 'foo'. The latter
401  // substitutes foo's value. Numeric substitution blocks recognize the same
402  // form as string ones, but start with a '#' sign after the double
403  // brackets. They also accept a combined form which sets a numeric variable
404  // to the evaluation of an expression. Both string and numeric variable
405  // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be
406  // valid, as this helps catch some common errors.
407  if (PatternStr.startswith("[[")) {
408  StringRef UnparsedPatternStr = PatternStr.substr(2);
409  // Find the closing bracket pair ending the match. End is going to be an
410  // offset relative to the beginning of the match string.
411  size_t End = FindRegexVarEnd(UnparsedPatternStr, SM);
412  StringRef MatchStr = UnparsedPatternStr.substr(0, End);
413  bool IsNumBlock = MatchStr.consume_front("#");
414 
415  if (End == StringRef::npos) {
416  SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
418  "Invalid substitution block, no ]] found");
419  return true;
420  }
421  // Strip the substitution block we are parsing. End points to the start
422  // of the "]]" closing the expression so account for it in computing the
423  // index of the first unparsed character.
424  PatternStr = UnparsedPatternStr.substr(End + 2);
425 
426  bool IsDefinition = false;
427  bool SubstNeeded = false;
428  // Whether the substitution block is a legacy use of @LINE with string
429  // substitution block syntax.
430  bool IsLegacyLineExpr = false;
431  StringRef DefName;
432  StringRef SubstStr;
433  StringRef MatchRegexp;
434  size_t SubstInsertIdx = RegExStr.size();
435 
436  // Parse string variable or legacy @LINE expression.
437  if (!IsNumBlock) {
438  size_t VarEndIdx = MatchStr.find(":");
439  size_t SpacePos = MatchStr.substr(0, VarEndIdx).find_first_of(" \t");
440  if (SpacePos != StringRef::npos) {
441  SM.PrintMessage(SMLoc::getFromPointer(MatchStr.data() + SpacePos),
442  SourceMgr::DK_Error, "unexpected whitespace");
443  return true;
444  }
445 
446  // Get the name (e.g. "foo") and verify it is well formed.
447  StringRef OrigMatchStr = MatchStr;
449  parseVariable(MatchStr, SM);
450  if (!ParseVarResult) {
451  logAllUnhandledErrors(ParseVarResult.takeError(), errs());
452  return true;
453  }
454  StringRef Name = ParseVarResult->Name;
455  bool IsPseudo = ParseVarResult->IsPseudo;
456 
457  IsDefinition = (VarEndIdx != StringRef::npos);
458  SubstNeeded = !IsDefinition;
459  if (IsDefinition) {
460  if ((IsPseudo || !MatchStr.consume_front(":"))) {
463  "invalid name in string variable definition");
464  return true;
465  }
466 
467  // Detect collisions between string and numeric variables when the
468  // former is created later than the latter.
469  if (Context->GlobalNumericVariableTable.find(Name) !=
470  Context->GlobalNumericVariableTable.end()) {
471  SM.PrintMessage(
473  "numeric variable with name '" + Name + "' already exists");
474  return true;
475  }
476  DefName = Name;
477  MatchRegexp = MatchStr;
478  } else {
479  if (IsPseudo) {
480  MatchStr = OrigMatchStr;
481  IsLegacyLineExpr = IsNumBlock = true;
482  } else
483  SubstStr = Name;
484  }
485  }
486 
487  // Parse numeric substitution block.
488  std::unique_ptr<FileCheckExpressionAST> ExpressionAST;
489  Optional<FileCheckNumericVariable *> DefinedNumericVariable;
490  if (IsNumBlock) {
492  parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
493  IsLegacyLineExpr, LineNumber, Context,
494  SM);
495  if (!ParseResult) {
496  logAllUnhandledErrors(ParseResult.takeError(), errs());
497  return true;
498  }
499  ExpressionAST = std::move(*ParseResult);
500  SubstNeeded = ExpressionAST != nullptr;
501  if (DefinedNumericVariable) {
502  IsDefinition = true;
503  DefName = (*DefinedNumericVariable)->getName();
504  }
505  if (SubstNeeded)
506  SubstStr = MatchStr;
507  else
508  MatchRegexp = "[0-9]+";
509  }
510 
511  // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]].
512  if (IsDefinition) {
513  RegExStr += '(';
514  ++SubstInsertIdx;
515 
516  if (IsNumBlock) {
517  FileCheckNumericVariableMatch NumericVariableDefinition = {
518  *DefinedNumericVariable, CurParen};
519  NumericVariableDefs[DefName] = NumericVariableDefinition;
520  // This store is done here rather than in match() to allow
521  // parseNumericVariableUse() to get the pointer to the class instance
522  // of the right variable definition corresponding to a given numeric
523  // variable use.
524  Context->GlobalNumericVariableTable[DefName] =
525  *DefinedNumericVariable;
526  } else {
527  VariableDefs[DefName] = CurParen;
528  // Mark string variable as defined to detect collisions between
529  // string and numeric variables in parseNumericVariableUse() and
530  // defineCmdlineVariables() when the latter is created later than the
531  // former. We cannot reuse GlobalVariableTable for this by populating
532  // it with an empty string since we would then lose the ability to
533  // detect the use of an undefined variable in match().
534  Context->DefinedVariableTable[DefName] = true;
535  }
536 
537  ++CurParen;
538  }
539 
540  if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM))
541  return true;
542 
543  if (IsDefinition)
544  RegExStr += ')';
545 
546  // Handle substitutions: [[foo]] and [[#<foo expr>]].
547  if (SubstNeeded) {
548  // Handle substitution of string variables that were defined earlier on
549  // the same line by emitting a backreference. Expressions do not
550  // support substituting a numeric variable defined on the same line.
551  if (!IsNumBlock && VariableDefs.find(SubstStr) != VariableDefs.end()) {
552  unsigned CaptureParenGroup = VariableDefs[SubstStr];
553  if (CaptureParenGroup < 1 || CaptureParenGroup > 9) {
554  SM.PrintMessage(SMLoc::getFromPointer(SubstStr.data()),
556  "Can't back-reference more than 9 variables");
557  return true;
558  }
559  AddBackrefToRegEx(CaptureParenGroup);
560  } else {
561  // Handle substitution of string variables ([[<var>]]) defined in
562  // previous CHECK patterns, and substitution of expressions.
563  FileCheckSubstitution *Substitution =
564  IsNumBlock
565  ? Context->makeNumericSubstitution(
566  SubstStr, std::move(ExpressionAST), SubstInsertIdx)
567  : Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
568  Substitutions.push_back(Substitution);
569  }
570  }
571  }
572 
573  // Handle fixed string matches.
574  // Find the end, which is the start of the next regex.
575  size_t FixedMatchEnd = PatternStr.find("{{");
576  FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
577  RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
578  PatternStr = PatternStr.substr(FixedMatchEnd);
579  }
580 
581  if (MatchFullLinesHere) {
582  if (!Req.NoCanonicalizeWhiteSpace)
583  RegExStr += " *";
584  RegExStr += '$';
585  }
586 
587  return false;
588 }
589 
590 bool FileCheckPattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
591  Regex R(RS);
592  std::string Error;
593  if (!R.isValid(Error)) {
595  "invalid regex: " + Error);
596  return true;
597  }
598 
599  RegExStr += RS.str();
600  CurParen += R.getNumMatches();
601  return false;
602 }
603 
604 void FileCheckPattern::AddBackrefToRegEx(unsigned BackrefNum) {
605  assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
606  std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
607  RegExStr += Backref;
608 }
609 
611  const SourceMgr &SM) const {
612  // If this is the EOF pattern, match it immediately.
613  if (CheckTy == Check::CheckEOF) {
614  MatchLen = 0;
615  return Buffer.size();
616  }
617 
618  // If this is a fixed string pattern, just match it now.
619  if (!FixedStr.empty()) {
620  MatchLen = FixedStr.size();
621  size_t Pos = Buffer.find(FixedStr);
622  if (Pos == StringRef::npos)
623  return make_error<FileCheckNotFoundError>();
624  return Pos;
625  }
626 
627  // Regex match.
628 
629  // If there are substitutions, we need to create a temporary string with the
630  // actual value.
631  StringRef RegExToMatch = RegExStr;
632  std::string TmpStr;
633  if (!Substitutions.empty()) {
634  TmpStr = RegExStr;
635  if (LineNumber)
636  Context->LineVariable->setValue(*LineNumber);
637 
638  size_t InsertOffset = 0;
639  // Substitute all string variables and expressions whose values are only
640  // now known. Use of string variables defined on the same line are handled
641  // by back-references.
642  for (const auto &Substitution : Substitutions) {
643  // Substitute and check for failure (e.g. use of undefined variable).
644  Expected<std::string> Value = Substitution->getResult();
645  if (!Value)
646  return Value.takeError();
647 
648  // Plop it into the regex at the adjusted offset.
649  TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset,
650  Value->begin(), Value->end());
651  InsertOffset += Value->size();
652  }
653 
654  // Match the newly constructed regex.
655  RegExToMatch = TmpStr;
656  }
657 
658  SmallVector<StringRef, 4> MatchInfo;
659  if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
660  return make_error<FileCheckNotFoundError>();
661 
662  // Successful regex match.
663  assert(!MatchInfo.empty() && "Didn't get any match");
664  StringRef FullMatch = MatchInfo[0];
665 
666  // If this defines any string variables, remember their values.
667  for (const auto &VariableDef : VariableDefs) {
668  assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
669  Context->GlobalVariableTable[VariableDef.first] =
670  MatchInfo[VariableDef.second];
671  }
672 
673  // If this defines any numeric variables, remember their values.
674  for (const auto &NumericVariableDef : NumericVariableDefs) {
675  const FileCheckNumericVariableMatch &NumericVariableMatch =
676  NumericVariableDef.getValue();
677  unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
678  assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
679  FileCheckNumericVariable *DefinedNumericVariable =
680  NumericVariableMatch.DefinedNumericVariable;
681 
682  StringRef MatchedValue = MatchInfo[CaptureParenGroup];
683  uint64_t Val;
684  if (MatchedValue.getAsInteger(10, Val))
685  return FileCheckErrorDiagnostic::get(SM, MatchedValue,
686  "Unable to represent numeric value");
687  DefinedNumericVariable->setValue(Val);
688  }
689 
690  // Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after
691  // the required preceding newline, which is consumed by the pattern in the
692  // case of CHECK-EMPTY but not CHECK-NEXT.
693  size_t MatchStartSkip = CheckTy == Check::CheckEmpty;
694  MatchLen = FullMatch.size() - MatchStartSkip;
695  return FullMatch.data() - Buffer.data() + MatchStartSkip;
696 }
697 
698 unsigned FileCheckPattern::computeMatchDistance(StringRef Buffer) const {
699  // Just compute the number of matching characters. For regular expressions, we
700  // just compare against the regex itself and hope for the best.
701  //
702  // FIXME: One easy improvement here is have the regex lib generate a single
703  // example regular expression which matches, and use that as the example
704  // string.
705  StringRef ExampleString(FixedStr);
706  if (ExampleString.empty())
707  ExampleString = RegExStr;
708 
709  // Only compare up to the first line in the buffer, or the string size.
710  StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
711  BufferPrefix = BufferPrefix.split('\n').first;
712  return BufferPrefix.edit_distance(ExampleString);
713 }
714 
716  SMRange MatchRange) const {
717  // Print what we know about substitutions.
718  if (!Substitutions.empty()) {
719  for (const auto &Substitution : Substitutions) {
720  SmallString<256> Msg;
721  raw_svector_ostream OS(Msg);
722  Expected<std::string> MatchedValue = Substitution->getResult();
723 
724  // Substitution failed or is not known at match time, print the undefined
725  // variables it uses.
726  if (!MatchedValue) {
727  bool UndefSeen = false;
728  handleAllErrors(MatchedValue.takeError(),
729  [](const FileCheckNotFoundError &E) {},
730  // Handled in PrintNoMatch().
731  [](const FileCheckErrorDiagnostic &E) {},
732  [&](const FileCheckUndefVarError &E) {
733  if (!UndefSeen) {
734  OS << "uses undefined variable(s):";
735  UndefSeen = true;
736  }
737  OS << " ";
738  E.log(OS);
739  });
740  } else {
741  // Substitution succeeded. Print substituted value.
742  OS << "with \"";
743  OS.write_escaped(Substitution->getFromString()) << "\" equal to \"";
744  OS.write_escaped(*MatchedValue) << "\"";
745  }
746 
747  if (MatchRange.isValid())
748  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, OS.str(),
749  {MatchRange});
750  else
752  SourceMgr::DK_Note, OS.str());
753  }
754  }
755 }
756 
758  const SourceMgr &SM, SMLoc Loc,
759  Check::FileCheckType CheckTy,
760  StringRef Buffer, size_t Pos, size_t Len,
761  std::vector<FileCheckDiag> *Diags,
762  bool AdjustPrevDiag = false) {
763  SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos);
764  SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len);
765  SMRange Range(Start, End);
766  if (Diags) {
767  if (AdjustPrevDiag)
768  Diags->rbegin()->MatchTy = MatchTy;
769  else
770  Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range);
771  }
772  return Range;
773 }
774 
776  const SourceMgr &SM, StringRef Buffer,
777  std::vector<FileCheckDiag> *Diags) const {
778  // Attempt to find the closest/best fuzzy match. Usually an error happens
779  // because some string in the output didn't exactly match. In these cases, we
780  // would like to show the user a best guess at what "should have" matched, to
781  // save them having to actually check the input manually.
782  size_t NumLinesForward = 0;
783  size_t Best = StringRef::npos;
784  double BestQuality = 0;
785 
786  // Use an arbitrary 4k limit on how far we will search.
787  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
788  if (Buffer[i] == '\n')
789  ++NumLinesForward;
790 
791  // Patterns have leading whitespace stripped, so skip whitespace when
792  // looking for something which looks like a pattern.
793  if (Buffer[i] == ' ' || Buffer[i] == '\t')
794  continue;
795 
796  // Compute the "quality" of this match as an arbitrary combination of the
797  // match distance and the number of lines skipped to get to this match.
798  unsigned Distance = computeMatchDistance(Buffer.substr(i));
799  double Quality = Distance + (NumLinesForward / 100.);
800 
801  if (Quality < BestQuality || Best == StringRef::npos) {
802  Best = i;
803  BestQuality = Quality;
804  }
805  }
806 
807  // Print the "possible intended match here" line if we found something
808  // reasonable and not equal to what we showed in the "scanning from here"
809  // line.
810  if (Best && Best != StringRef::npos && BestQuality < 50) {
811  SMRange MatchRange =
813  getCheckTy(), Buffer, Best, 0, Diags);
814  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note,
815  "possible intended match here");
816 
817  // FIXME: If we wanted to be really friendly we would show why the match
818  // failed, as it can be hard to spot simple one character differences.
819  }
820 }
821 
824  auto VarIter = GlobalVariableTable.find(VarName);
825  if (VarIter == GlobalVariableTable.end())
826  return make_error<FileCheckUndefVarError>(VarName);
827 
828  return VarIter->second;
829 }
830 
831 template <class... Types>
833 FileCheckPatternContext::makeNumericVariable(Types... args) {
834  NumericVariables.push_back(
835  std::make_unique<FileCheckNumericVariable>(args...));
836  return NumericVariables.back().get();
837 }
838 
840 FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
841  size_t InsertIdx) {
842  Substitutions.push_back(
843  std::make_unique<FileCheckStringSubstitution>(this, VarName, InsertIdx));
844  return Substitutions.back().get();
845 }
846 
847 FileCheckSubstitution *FileCheckPatternContext::makeNumericSubstitution(
848  StringRef ExpressionStr,
849  std::unique_ptr<FileCheckExpressionAST> ExpressionAST, size_t InsertIdx) {
850  Substitutions.push_back(std::make_unique<FileCheckNumericSubstitution>(
851  this, ExpressionStr, std::move(ExpressionAST), InsertIdx));
852  return Substitutions.back().get();
853 }
854 
855 size_t FileCheckPattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
856  // Offset keeps track of the current offset within the input Str
857  size_t Offset = 0;
858  // [...] Nesting depth
859  size_t BracketDepth = 0;
860 
861  while (!Str.empty()) {
862  if (Str.startswith("]]") && BracketDepth == 0)
863  return Offset;
864  if (Str[0] == '\\') {
865  // Backslash escapes the next char within regexes, so skip them both.
866  Str = Str.substr(2);
867  Offset += 2;
868  } else {
869  switch (Str[0]) {
870  default:
871  break;
872  case '[':
873  BracketDepth++;
874  break;
875  case ']':
876  if (BracketDepth == 0) {
879  "missing closing \"]\" for regex variable");
880  exit(1);
881  }
882  BracketDepth--;
883  break;
884  }
885  Str = Str.substr(1);
886  Offset++;
887  }
888  }
889 
890  return StringRef::npos;
891 }
892 
894  SmallVectorImpl<char> &OutputBuffer) {
895  OutputBuffer.reserve(MB.getBufferSize());
896 
897  for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
898  Ptr != End; ++Ptr) {
899  // Eliminate trailing dosish \r.
900  if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
901  continue;
902  }
903 
904  // If current char is not a horizontal whitespace or if horizontal
905  // whitespace canonicalization is disabled, dump it to output as is.
906  if (Req.NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) {
907  OutputBuffer.push_back(*Ptr);
908  continue;
909  }
910 
911  // Otherwise, add one space and advance over neighboring space.
912  OutputBuffer.push_back(' ');
913  while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
914  ++Ptr;
915  }
916 
917  // Add a null byte and then return all but that byte.
918  OutputBuffer.push_back('\0');
919  return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
920 }
921 
923  const Check::FileCheckType &CheckTy,
924  SMLoc CheckLoc, MatchType MatchTy,
925  SMRange InputRange)
926  : CheckTy(CheckTy), MatchTy(MatchTy) {
927  auto Start = SM.getLineAndColumn(InputRange.Start);
928  auto End = SM.getLineAndColumn(InputRange.End);
929  InputStartLine = Start.first;
930  InputStartCol = Start.second;
931  InputEndLine = End.first;
932  InputEndCol = End.second;
933  Start = SM.getLineAndColumn(CheckLoc);
934  CheckLine = Start.first;
935  CheckCol = Start.second;
936 }
937 
938 static bool IsPartOfWord(char c) {
939  return (isalnum(c) || c == '-' || c == '_');
940 }
941 
943  assert(Count > 0 && "zero and negative counts are not supported");
944  assert((C == 1 || Kind == CheckPlain) &&
945  "count supported only for plain CHECK directives");
946  Count = C;
947  return *this;
948 }
949 
951  switch (Kind) {
952  case Check::CheckNone:
953  return "invalid";
954  case Check::CheckPlain:
955  if (Count > 1)
956  return Prefix.str() + "-COUNT";
957  return Prefix;
958  case Check::CheckNext:
959  return Prefix.str() + "-NEXT";
960  case Check::CheckSame:
961  return Prefix.str() + "-SAME";
962  case Check::CheckNot:
963  return Prefix.str() + "-NOT";
964  case Check::CheckDAG:
965  return Prefix.str() + "-DAG";
966  case Check::CheckLabel:
967  return Prefix.str() + "-LABEL";
968  case Check::CheckEmpty:
969  return Prefix.str() + "-EMPTY";
970  case Check::CheckEOF:
971  return "implicit EOF";
972  case Check::CheckBadNot:
973  return "bad NOT";
975  return "bad COUNT";
976  }
977  llvm_unreachable("unknown FileCheckType");
978 }
979 
980 static std::pair<Check::FileCheckType, StringRef>
982  if (Buffer.size() <= Prefix.size())
983  return {Check::CheckNone, StringRef()};
984 
985  char NextChar = Buffer[Prefix.size()];
986 
987  StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
988  // Verify that the : is present after the prefix.
989  if (NextChar == ':')
990  return {Check::CheckPlain, Rest};
991 
992  if (NextChar != '-')
993  return {Check::CheckNone, StringRef()};
994 
995  if (Rest.consume_front("COUNT-")) {
996  int64_t Count;
997  if (Rest.consumeInteger(10, Count))
998  // Error happened in parsing integer.
999  return {Check::CheckBadCount, Rest};
1000  if (Count <= 0 || Count > INT32_MAX)
1001  return {Check::CheckBadCount, Rest};
1002  if (!Rest.consume_front(":"))
1003  return {Check::CheckBadCount, Rest};
1004  return {Check::FileCheckType(Check::CheckPlain).setCount(Count), Rest};
1005  }
1006 
1007  if (Rest.consume_front("NEXT:"))
1008  return {Check::CheckNext, Rest};
1009 
1010  if (Rest.consume_front("SAME:"))
1011  return {Check::CheckSame, Rest};
1012 
1013  if (Rest.consume_front("NOT:"))
1014  return {Check::CheckNot, Rest};
1015 
1016  if (Rest.consume_front("DAG:"))
1017  return {Check::CheckDAG, Rest};
1018 
1019  if (Rest.consume_front("LABEL:"))
1020  return {Check::CheckLabel, Rest};
1021 
1022  if (Rest.consume_front("EMPTY:"))
1023  return {Check::CheckEmpty, Rest};
1024 
1025  // You can't combine -NOT with another suffix.
1026  if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
1027  Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
1028  Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") ||
1029  Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:"))
1030  return {Check::CheckBadNot, Rest};
1031 
1032  return {Check::CheckNone, Rest};
1033 }
1034 
1035 // From the given position, find the next character after the word.
1036 static size_t SkipWord(StringRef Str, size_t Loc) {
1037  while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
1038  ++Loc;
1039  return Loc;
1040 }
1041 
1042 /// Searches the buffer for the first prefix in the prefix regular expression.
1043 ///
1044 /// This searches the buffer using the provided regular expression, however it
1045 /// enforces constraints beyond that:
1046 /// 1) The found prefix must not be a suffix of something that looks like
1047 /// a valid prefix.
1048 /// 2) The found prefix must be followed by a valid check type suffix using \c
1049 /// FindCheckType above.
1050 ///
1051 /// \returns a pair of StringRefs into the Buffer, which combines:
1052 /// - the first match of the regular expression to satisfy these two is
1053 /// returned,
1054 /// otherwise an empty StringRef is returned to indicate failure.
1055 /// - buffer rewound to the location right after parsed suffix, for parsing
1056 /// to continue from
1057 ///
1058 /// If this routine returns a valid prefix, it will also shrink \p Buffer to
1059 /// start at the beginning of the returned prefix, increment \p LineNumber for
1060 /// each new line consumed from \p Buffer, and set \p CheckTy to the type of
1061 /// check found by examining the suffix.
1062 ///
1063 /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
1064 /// is unspecified.
1065 static std::pair<StringRef, StringRef>
1067  unsigned &LineNumber, Check::FileCheckType &CheckTy) {
1068  SmallVector<StringRef, 2> Matches;
1069 
1070  while (!Buffer.empty()) {
1071  // Find the first (longest) match using the RE.
1072  if (!PrefixRE.match(Buffer, &Matches))
1073  // No match at all, bail.
1074  return {StringRef(), StringRef()};
1075 
1076  StringRef Prefix = Matches[0];
1077  Matches.clear();
1078 
1079  assert(Prefix.data() >= Buffer.data() &&
1080  Prefix.data() < Buffer.data() + Buffer.size() &&
1081  "Prefix doesn't start inside of buffer!");
1082  size_t Loc = Prefix.data() - Buffer.data();
1083  StringRef Skipped = Buffer.substr(0, Loc);
1084  Buffer = Buffer.drop_front(Loc);
1085  LineNumber += Skipped.count('\n');
1086 
1087  // Check that the matched prefix isn't a suffix of some other check-like
1088  // word.
1089  // FIXME: This is a very ad-hoc check. it would be better handled in some
1090  // other way. Among other things it seems hard to distinguish between
1091  // intentional and unintentional uses of this feature.
1092  if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
1093  // Now extract the type.
1094  StringRef AfterSuffix;
1095  std::tie(CheckTy, AfterSuffix) = FindCheckType(Buffer, Prefix);
1096 
1097  // If we've found a valid check type for this prefix, we're done.
1098  if (CheckTy != Check::CheckNone)
1099  return {Prefix, AfterSuffix};
1100  }
1101 
1102  // If we didn't successfully find a prefix, we need to skip this invalid
1103  // prefix and continue scanning. We directly skip the prefix that was
1104  // matched and any additional parts of that check-like word.
1105  Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size()));
1106  }
1107 
1108  // We ran out of buffer while skipping partial matches so give up.
1109  return {StringRef(), StringRef()};
1110 }
1111 
1113  assert(!LineVariable && "@LINE pseudo numeric variable already created");
1114  StringRef LineName = "@LINE";
1115  LineVariable = makeNumericVariable(LineName);
1116  GlobalNumericVariableTable[LineName] = LineVariable;
1117 }
1118 
1120  std::vector<FileCheckString> &CheckStrings) {
1121  Error DefineError =
1122  PatternContext.defineCmdlineVariables(Req.GlobalDefines, SM);
1123  if (DefineError) {
1124  logAllUnhandledErrors(std::move(DefineError), errs());
1125  return true;
1126  }
1127 
1128  PatternContext.createLineVariable();
1129 
1130  std::vector<FileCheckPattern> ImplicitNegativeChecks;
1131  for (const auto &PatternString : Req.ImplicitCheckNot) {
1132  // Create a buffer with fake command line content in order to display the
1133  // command line option responsible for the specific implicit CHECK-NOT.
1134  std::string Prefix = "-implicit-check-not='";
1135  std::string Suffix = "'";
1136  std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
1137  Prefix + PatternString + Suffix, "command line");
1138 
1139  StringRef PatternInBuffer =
1140  CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
1141  SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
1142 
1143  ImplicitNegativeChecks.push_back(
1144  FileCheckPattern(Check::CheckNot, &PatternContext));
1145  ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
1146  "IMPLICIT-CHECK", SM, Req);
1147  }
1148 
1149  std::vector<FileCheckPattern> DagNotMatches = ImplicitNegativeChecks;
1150 
1151  // LineNumber keeps track of the line on which CheckPrefix instances are
1152  // found.
1153  unsigned LineNumber = 1;
1154 
1155  while (1) {
1157 
1158  // See if a prefix occurs in the memory buffer.
1159  StringRef UsedPrefix;
1160  StringRef AfterSuffix;
1161  std::tie(UsedPrefix, AfterSuffix) =
1162  FindFirstMatchingPrefix(PrefixRE, Buffer, LineNumber, CheckTy);
1163  if (UsedPrefix.empty())
1164  break;
1165  assert(UsedPrefix.data() == Buffer.data() &&
1166  "Failed to move Buffer's start forward, or pointed prefix outside "
1167  "of the buffer!");
1168  assert(AfterSuffix.data() >= Buffer.data() &&
1169  AfterSuffix.data() < Buffer.data() + Buffer.size() &&
1170  "Parsing after suffix doesn't start inside of buffer!");
1171 
1172  // Location to use for error messages.
1173  const char *UsedPrefixStart = UsedPrefix.data();
1174 
1175  // Skip the buffer to the end of parsed suffix (or just prefix, if no good
1176  // suffix was processed).
1177  Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size())
1178  : AfterSuffix;
1179 
1180  // Complain about useful-looking but unsupported suffixes.
1181  if (CheckTy == Check::CheckBadNot) {
1183  "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
1184  return true;
1185  }
1186 
1187  // Complain about invalid count specification.
1188  if (CheckTy == Check::CheckBadCount) {
1190  "invalid count in -COUNT specification on prefix '" +
1191  UsedPrefix + "'");
1192  return true;
1193  }
1194 
1195  // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
1196  // leading whitespace.
1197  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
1198  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
1199 
1200  // Scan ahead to the end of line.
1201  size_t EOL = Buffer.find_first_of("\n\r");
1202 
1203  // Remember the location of the start of the pattern, for diagnostics.
1204  SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
1205 
1206  // Parse the pattern.
1207  FileCheckPattern P(CheckTy, &PatternContext, LineNumber);
1208  if (P.parsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, Req))
1209  return true;
1210 
1211  // Verify that CHECK-LABEL lines do not define or use variables
1212  if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
1213  SM.PrintMessage(
1214  SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
1215  "found '" + UsedPrefix + "-LABEL:'"
1216  " with variable definition or use");
1217  return true;
1218  }
1219 
1220  Buffer = Buffer.substr(EOL);
1221 
1222  // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
1223  if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
1224  CheckTy == Check::CheckEmpty) &&
1225  CheckStrings.empty()) {
1226  StringRef Type = CheckTy == Check::CheckNext
1227  ? "NEXT"
1228  : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
1229  SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
1231  "found '" + UsedPrefix + "-" + Type +
1232  "' without previous '" + UsedPrefix + ": line");
1233  return true;
1234  }
1235 
1236  // Handle CHECK-DAG/-NOT.
1237  if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
1238  DagNotMatches.push_back(P);
1239  continue;
1240  }
1241 
1242  // Okay, add the string we captured to the output vector and move on.
1243  CheckStrings.emplace_back(P, UsedPrefix, PatternLoc);
1244  std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
1245  DagNotMatches = ImplicitNegativeChecks;
1246  }
1247 
1248  // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
1249  // prefix as a filler for the error message.
1250  if (!DagNotMatches.empty()) {
1251  CheckStrings.emplace_back(
1252  FileCheckPattern(Check::CheckEOF, &PatternContext, LineNumber + 1),
1253  *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
1254  std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
1255  }
1256 
1257  if (CheckStrings.empty()) {
1258  errs() << "error: no check strings found with prefix"
1259  << (Req.CheckPrefixes.size() > 1 ? "es " : " ");
1260  auto I = Req.CheckPrefixes.begin();
1261  auto E = Req.CheckPrefixes.end();
1262  if (I != E) {
1263  errs() << "\'" << *I << ":'";
1264  ++I;
1265  }
1266  for (; I != E; ++I)
1267  errs() << ", \'" << *I << ":'";
1268 
1269  errs() << '\n';
1270  return true;
1271  }
1272 
1273  return false;
1274 }
1275 
1276 static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
1277  StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat,
1278  int MatchedCount, StringRef Buffer, size_t MatchPos,
1279  size_t MatchLen, const FileCheckRequest &Req,
1280  std::vector<FileCheckDiag> *Diags) {
1281  bool PrintDiag = true;
1282  if (ExpectedMatch) {
1283  if (!Req.Verbose)
1284  return;
1285  if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF)
1286  return;
1287  // Due to their verbosity, we don't print verbose diagnostics here if we're
1288  // gathering them for a different rendering, but we always print other
1289  // diagnostics.
1290  PrintDiag = !Diags;
1291  }
1292  SMRange MatchRange = ProcessMatchResult(
1293  ExpectedMatch ? FileCheckDiag::MatchFoundAndExpected
1295  SM, Loc, Pat.getCheckTy(), Buffer, MatchPos, MatchLen, Diags);
1296  if (!PrintDiag)
1297  return;
1298 
1299  std::string Message = formatv("{0}: {1} string found in input",
1300  Pat.getCheckTy().getDescription(Prefix),
1301  (ExpectedMatch ? "expected" : "excluded"))
1302  .str();
1303  if (Pat.getCount() > 1)
1304  Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
1305 
1306  SM.PrintMessage(
1307  Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message);
1308  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here",
1309  {MatchRange});
1310  Pat.printSubstitutions(SM, Buffer, MatchRange);
1311 }
1312 
1313 static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
1314  const FileCheckString &CheckStr, int MatchedCount,
1315  StringRef Buffer, size_t MatchPos, size_t MatchLen,
1316  FileCheckRequest &Req,
1317  std::vector<FileCheckDiag> *Diags) {
1318  PrintMatch(ExpectedMatch, SM, CheckStr.Prefix, CheckStr.Loc, CheckStr.Pat,
1319  MatchedCount, Buffer, MatchPos, MatchLen, Req, Diags);
1320 }
1321 
1322 static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
1323  StringRef Prefix, SMLoc Loc,
1324  const FileCheckPattern &Pat, int MatchedCount,
1325  StringRef Buffer, bool VerboseVerbose,
1326  std::vector<FileCheckDiag> *Diags, Error MatchErrors) {
1327  assert(MatchErrors && "Called on successful match");
1328  bool PrintDiag = true;
1329  if (!ExpectedMatch) {
1330  if (!VerboseVerbose) {
1331  consumeError(std::move(MatchErrors));
1332  return;
1333  }
1334  // Due to their verbosity, we don't print verbose diagnostics here if we're
1335  // gathering them for a different rendering, but we always print other
1336  // diagnostics.
1337  PrintDiag = !Diags;
1338  }
1339 
1340  // If the current position is at the end of a line, advance to the start of
1341  // the next line.
1342  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
1343  SMRange SearchRange = ProcessMatchResult(
1344  ExpectedMatch ? FileCheckDiag::MatchNoneButExpected
1346  SM, Loc, Pat.getCheckTy(), Buffer, 0, Buffer.size(), Diags);
1347  if (!PrintDiag) {
1348  consumeError(std::move(MatchErrors));
1349  return;
1350  }
1351 
1352  MatchErrors =
1353  handleErrors(std::move(MatchErrors),
1354  [](const FileCheckErrorDiagnostic &E) { E.log(errs()); });
1355 
1356  // No problem matching the string per se.
1357  if (!MatchErrors)
1358  return;
1359  consumeError(std::move(MatchErrors));
1360 
1361  // Print "not found" diagnostic.
1362  std::string Message = formatv("{0}: {1} string not found in input",
1363  Pat.getCheckTy().getDescription(Prefix),
1364  (ExpectedMatch ? "expected" : "excluded"))
1365  .str();
1366  if (Pat.getCount() > 1)
1367  Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
1368  SM.PrintMessage(
1369  Loc, ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark, Message);
1370 
1371  // Print the "scanning from here" line.
1372  SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note, "scanning from here");
1373 
1374  // Allow the pattern to print additional information if desired.
1375  Pat.printSubstitutions(SM, Buffer);
1376 
1377  if (ExpectedMatch)
1378  Pat.printFuzzyMatch(SM, Buffer, Diags);
1379 }
1380 
1381 static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
1382  const FileCheckString &CheckStr, int MatchedCount,
1383  StringRef Buffer, bool VerboseVerbose,
1384  std::vector<FileCheckDiag> *Diags, Error MatchErrors) {
1385  PrintNoMatch(ExpectedMatch, SM, CheckStr.Prefix, CheckStr.Loc, CheckStr.Pat,
1386  MatchedCount, Buffer, VerboseVerbose, Diags,
1387  std::move(MatchErrors));
1388 }
1389 
1390 /// Counts the number of newlines in the specified range.
1391 static unsigned CountNumNewlinesBetween(StringRef Range,
1392  const char *&FirstNewLine) {
1393  unsigned NumNewLines = 0;
1394  while (1) {
1395  // Scan for newline.
1396  Range = Range.substr(Range.find_first_of("\n\r"));
1397  if (Range.empty())
1398  return NumNewLines;
1399 
1400  ++NumNewLines;
1401 
1402  // Handle \n\r and \r\n as a single newline.
1403  if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
1404  (Range[0] != Range[1]))
1405  Range = Range.substr(1);
1406  Range = Range.substr(1);
1407 
1408  if (NumNewLines == 1)
1409  FirstNewLine = Range.begin();
1410  }
1411 }
1412 
1413 size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
1414  bool IsLabelScanMode, size_t &MatchLen,
1415  FileCheckRequest &Req,
1416  std::vector<FileCheckDiag> *Diags) const {
1417  size_t LastPos = 0;
1418  std::vector<const FileCheckPattern *> NotStrings;
1419 
1420  // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1421  // bounds; we have not processed variable definitions within the bounded block
1422  // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1423  // over the block again (including the last CHECK-LABEL) in normal mode.
1424  if (!IsLabelScanMode) {
1425  // Match "dag strings" (with mixed "not strings" if any).
1426  LastPos = CheckDag(SM, Buffer, NotStrings, Req, Diags);
1427  if (LastPos == StringRef::npos)
1428  return StringRef::npos;
1429  }
1430 
1431  // Match itself from the last position after matching CHECK-DAG.
1432  size_t LastMatchEnd = LastPos;
1433  size_t FirstMatchPos = 0;
1434  // Go match the pattern Count times. Majority of patterns only match with
1435  // count 1 though.
1436  assert(Pat.getCount() != 0 && "pattern count can not be zero");
1437  for (int i = 1; i <= Pat.getCount(); i++) {
1438  StringRef MatchBuffer = Buffer.substr(LastMatchEnd);
1439  size_t CurrentMatchLen;
1440  // get a match at current start point
1441  Expected<size_t> MatchResult = Pat.match(MatchBuffer, CurrentMatchLen, SM);
1442 
1443  // report
1444  if (!MatchResult) {
1445  PrintNoMatch(true, SM, *this, i, MatchBuffer, Req.VerboseVerbose, Diags,
1446  MatchResult.takeError());
1447  return StringRef::npos;
1448  }
1449  size_t MatchPos = *MatchResult;
1450  PrintMatch(true, SM, *this, i, MatchBuffer, MatchPos, CurrentMatchLen, Req,
1451  Diags);
1452  if (i == 1)
1453  FirstMatchPos = LastPos + MatchPos;
1454 
1455  // move start point after the match
1456  LastMatchEnd += MatchPos + CurrentMatchLen;
1457  }
1458  // Full match len counts from first match pos.
1459  MatchLen = LastMatchEnd - FirstMatchPos;
1460 
1461  // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1462  // or CHECK-NOT
1463  if (!IsLabelScanMode) {
1464  size_t MatchPos = FirstMatchPos - LastPos;
1465  StringRef MatchBuffer = Buffer.substr(LastPos);
1466  StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1467 
1468  // If this check is a "CHECK-NEXT", verify that the previous match was on
1469  // the previous line (i.e. that there is one newline between them).
1470  if (CheckNext(SM, SkippedRegion)) {
1472  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
1473  Diags, Req.Verbose);
1474  return StringRef::npos;
1475  }
1476 
1477  // If this check is a "CHECK-SAME", verify that the previous match was on
1478  // the same line (i.e. that there is no newline between them).
1479  if (CheckSame(SM, SkippedRegion)) {
1481  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
1482  Diags, Req.Verbose);
1483  return StringRef::npos;
1484  }
1485 
1486  // If this match had "not strings", verify that they don't exist in the
1487  // skipped region.
1488  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
1489  return StringRef::npos;
1490  }
1491 
1492  return FirstMatchPos;
1493 }
1494 
1495 bool FileCheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
1496  if (Pat.getCheckTy() != Check::CheckNext &&
1497  Pat.getCheckTy() != Check::CheckEmpty)
1498  return false;
1499 
1500  Twine CheckName =
1501  Prefix +
1502  Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT");
1503 
1504  // Count the number of newlines between the previous match and this one.
1505  const char *FirstNewLine = nullptr;
1506  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1507 
1508  if (NumNewLines == 0) {
1510  CheckName + ": is on the same line as previous match");
1512  "'next' match was here");
1514  "previous match ended here");
1515  return true;
1516  }
1517 
1518  if (NumNewLines != 1) {
1520  CheckName +
1521  ": is not on the line after the previous match");
1523  "'next' match was here");
1525  "previous match ended here");
1527  "non-matching line after previous match is here");
1528  return true;
1529  }
1530 
1531  return false;
1532 }
1533 
1534 bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
1535  if (Pat.getCheckTy() != Check::CheckSame)
1536  return false;
1537 
1538  // Count the number of newlines between the previous match and this one.
1539  const char *FirstNewLine = nullptr;
1540  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1541 
1542  if (NumNewLines != 0) {
1544  Prefix +
1545  "-SAME: is not on the same line as the previous match");
1547  "'next' match was here");
1549  "previous match ended here");
1550  return true;
1551  }
1552 
1553  return false;
1554 }
1555 
1557  const SourceMgr &SM, StringRef Buffer,
1558  const std::vector<const FileCheckPattern *> &NotStrings,
1559  const FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) const {
1560  for (const FileCheckPattern *Pat : NotStrings) {
1561  assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
1562 
1563  size_t MatchLen = 0;
1564  Expected<size_t> MatchResult = Pat->match(Buffer, MatchLen, SM);
1565 
1566  if (!MatchResult) {
1567  PrintNoMatch(false, SM, Prefix, Pat->getLoc(), *Pat, 1, Buffer,
1568  Req.VerboseVerbose, Diags, MatchResult.takeError());
1569  continue;
1570  }
1571  size_t Pos = *MatchResult;
1572 
1573  PrintMatch(false, SM, Prefix, Pat->getLoc(), *Pat, 1, Buffer, Pos, MatchLen,
1574  Req, Diags);
1575 
1576  return true;
1577  }
1578 
1579  return false;
1580 }
1581 
1582 size_t
1584  std::vector<const FileCheckPattern *> &NotStrings,
1585  const FileCheckRequest &Req,
1586  std::vector<FileCheckDiag> *Diags) const {
1587  if (DagNotStrings.empty())
1588  return 0;
1589 
1590  // The start of the search range.
1591  size_t StartPos = 0;
1592 
1593  struct MatchRange {
1594  size_t Pos;
1595  size_t End;
1596  };
1597  // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match
1598  // ranges are erased from this list once they are no longer in the search
1599  // range.
1600  std::list<MatchRange> MatchRanges;
1601 
1602  // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG
1603  // group, so we don't use a range-based for loop here.
1604  for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end();
1605  PatItr != PatEnd; ++PatItr) {
1606  const FileCheckPattern &Pat = *PatItr;
1607  assert((Pat.getCheckTy() == Check::CheckDAG ||
1608  Pat.getCheckTy() == Check::CheckNot) &&
1609  "Invalid CHECK-DAG or CHECK-NOT!");
1610 
1611  if (Pat.getCheckTy() == Check::CheckNot) {
1612  NotStrings.push_back(&Pat);
1613  continue;
1614  }
1615 
1616  assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
1617 
1618  // CHECK-DAG always matches from the start.
1619  size_t MatchLen = 0, MatchPos = StartPos;
1620 
1621  // Search for a match that doesn't overlap a previous match in this
1622  // CHECK-DAG group.
1623  for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) {
1624  StringRef MatchBuffer = Buffer.substr(MatchPos);
1625  Expected<size_t> MatchResult = Pat.match(MatchBuffer, MatchLen, SM);
1626  // With a group of CHECK-DAGs, a single mismatching means the match on
1627  // that group of CHECK-DAGs fails immediately.
1628  if (!MatchResult) {
1629  PrintNoMatch(true, SM, Prefix, Pat.getLoc(), Pat, 1, MatchBuffer,
1630  Req.VerboseVerbose, Diags, MatchResult.takeError());
1631  return StringRef::npos;
1632  }
1633  size_t MatchPosBuf = *MatchResult;
1634  // Re-calc it as the offset relative to the start of the original string.
1635  MatchPos += MatchPosBuf;
1636  if (Req.VerboseVerbose)
1637  PrintMatch(true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer, MatchPos,
1638  MatchLen, Req, Diags);
1639  MatchRange M{MatchPos, MatchPos + MatchLen};
1640  if (Req.AllowDeprecatedDagOverlap) {
1641  // We don't need to track all matches in this mode, so we just maintain
1642  // one match range that encompasses the current CHECK-DAG group's
1643  // matches.
1644  if (MatchRanges.empty())
1645  MatchRanges.insert(MatchRanges.end(), M);
1646  else {
1647  auto Block = MatchRanges.begin();
1648  Block->Pos = std::min(Block->Pos, M.Pos);
1649  Block->End = std::max(Block->End, M.End);
1650  }
1651  break;
1652  }
1653  // Iterate previous matches until overlapping match or insertion point.
1654  bool Overlap = false;
1655  for (; MI != ME; ++MI) {
1656  if (M.Pos < MI->End) {
1657  // !Overlap => New match has no overlap and is before this old match.
1658  // Overlap => New match overlaps this old match.
1659  Overlap = MI->Pos < M.End;
1660  break;
1661  }
1662  }
1663  if (!Overlap) {
1664  // Insert non-overlapping match into list.
1665  MatchRanges.insert(MI, M);
1666  break;
1667  }
1668  if (Req.VerboseVerbose) {
1669  // Due to their verbosity, we don't print verbose diagnostics here if
1670  // we're gathering them for a different rendering, but we always print
1671  // other diagnostics.
1672  if (!Diags) {
1673  SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos);
1674  SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End);
1675  SMRange OldRange(OldStart, OldEnd);
1676  SM.PrintMessage(OldStart, SourceMgr::DK_Note,
1677  "match discarded, overlaps earlier DAG match here",
1678  {OldRange});
1679  } else
1680  Diags->rbegin()->MatchTy = FileCheckDiag::MatchFoundButDiscarded;
1681  }
1682  MatchPos = MI->End;
1683  }
1684  if (!Req.VerboseVerbose)
1685  PrintMatch(true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer, MatchPos,
1686  MatchLen, Req, Diags);
1687 
1688  // Handle the end of a CHECK-DAG group.
1689  if (std::next(PatItr) == PatEnd ||
1690  std::next(PatItr)->getCheckTy() == Check::CheckNot) {
1691  if (!NotStrings.empty()) {
1692  // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to
1693  // CHECK-DAG, verify that there are no 'not' strings occurred in that
1694  // region.
1695  StringRef SkippedRegion =
1696  Buffer.slice(StartPos, MatchRanges.begin()->Pos);
1697  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
1698  return StringRef::npos;
1699  // Clear "not strings".
1700  NotStrings.clear();
1701  }
1702  // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the
1703  // end of this CHECK-DAG group's match range.
1704  StartPos = MatchRanges.rbegin()->End;
1705  // Don't waste time checking for (impossible) overlaps before that.
1706  MatchRanges.clear();
1707  }
1708  }
1709 
1710  return StartPos;
1711 }
1712 
1713 // A check prefix must contain only alphanumeric, hyphens and underscores.
1714 static bool ValidateCheckPrefix(StringRef CheckPrefix) {
1715  Regex Validator("^[a-zA-Z0-9_-]*$");
1716  return Validator.match(CheckPrefix);
1717 }
1718 
1720  StringSet<> PrefixSet;
1721 
1722  for (StringRef Prefix : Req.CheckPrefixes) {
1723  // Reject empty prefixes.
1724  if (Prefix == "")
1725  return false;
1726 
1727  if (!PrefixSet.insert(Prefix).second)
1728  return false;
1729 
1730  if (!ValidateCheckPrefix(Prefix))
1731  return false;
1732  }
1733 
1734  return true;
1735 }
1736 
1738  // I don't think there's a way to specify an initial value for cl::list,
1739  // so if nothing was specified, add the default
1740  if (Req.CheckPrefixes.empty())
1741  Req.CheckPrefixes.push_back("CHECK");
1742 
1743  // We already validated the contents of CheckPrefixes so just concatenate
1744  // them as alternatives.
1745  SmallString<32> PrefixRegexStr;
1746  for (StringRef Prefix : Req.CheckPrefixes) {
1747  if (Prefix != Req.CheckPrefixes.front())
1748  PrefixRegexStr.push_back('|');
1749 
1750  PrefixRegexStr.append(Prefix);
1751  }
1752 
1753  return Regex(PrefixRegexStr);
1754 }
1755 
1757  std::vector<std::string> &CmdlineDefines, SourceMgr &SM) {
1758  assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() &&
1759  "Overriding defined variable with command-line variable definitions");
1760 
1761  if (CmdlineDefines.empty())
1762  return Error::success();
1763 
1764  // Create a string representing the vector of command-line definitions. Each
1765  // definition is on its own line and prefixed with a definition number to
1766  // clarify which definition a given diagnostic corresponds to.
1767  unsigned I = 0;
1768  Error Errs = Error::success();
1769  std::string CmdlineDefsDiag;
1770  SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices;
1771  for (StringRef CmdlineDef : CmdlineDefines) {
1772  std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str();
1773  size_t EqIdx = CmdlineDef.find('=');
1774  if (EqIdx == StringRef::npos) {
1775  CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0));
1776  continue;
1777  }
1778  // Numeric variable definition.
1779  if (CmdlineDef[0] == '#') {
1780  // Append a copy of the command-line definition adapted to use the same
1781  // format as in the input file to be able to reuse
1782  // parseNumericSubstitutionBlock.
1783  CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str();
1784  std::string SubstitutionStr = CmdlineDef;
1785  SubstitutionStr[EqIdx] = ':';
1786  CmdlineDefsIndices.push_back(
1787  std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size()));
1788  CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str();
1789  } else {
1790  CmdlineDefsDiag += DefPrefix;
1791  CmdlineDefsIndices.push_back(
1792  std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size()));
1793  CmdlineDefsDiag += (CmdlineDef + "\n").str();
1794  }
1795  }
1796 
1797  // Create a buffer with fake command line content in order to display
1798  // parsing diagnostic with location information and point to the
1799  // global definition with invalid syntax.
1800  std::unique_ptr<MemoryBuffer> CmdLineDefsDiagBuffer =
1801  MemoryBuffer::getMemBufferCopy(CmdlineDefsDiag, "Global defines");
1802  StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer();
1803  SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc());
1804 
1805  for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) {
1806  StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first,
1807  CmdlineDefIndices.second);
1808  if (CmdlineDef.empty()) {
1809  Errs = joinErrors(
1810  std::move(Errs),
1812  SM, CmdlineDef, "missing equal sign in global definition"));
1813  continue;
1814  }
1815 
1816  // Numeric variable definition.
1817  if (CmdlineDef[0] == '#') {
1818  // Now parse the definition both to check that the syntax is correct and
1819  // to create the necessary class instance.
1820  StringRef CmdlineDefExpr = CmdlineDef.substr(1);
1821  Optional<FileCheckNumericVariable *> DefinedNumericVariable;
1824  CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM);
1825  if (!ExpressionASTResult) {
1826  Errs = joinErrors(std::move(Errs), ExpressionASTResult.takeError());
1827  continue;
1828  }
1829  std::unique_ptr<FileCheckExpressionAST> ExpressionAST =
1830  std::move(*ExpressionASTResult);
1831  // Now evaluate the expression whose value this variable should be set
1832  // to, since the expression of a command-line variable definition should
1833  // only use variables defined earlier on the command-line. If not, this
1834  // is an error and we report it.
1835  Expected<uint64_t> Value = ExpressionAST->eval();
1836  if (!Value) {
1837  Errs = joinErrors(std::move(Errs), Value.takeError());
1838  continue;
1839  }
1840 
1841  assert(DefinedNumericVariable && "No variable defined");
1842  (*DefinedNumericVariable)->setValue(*Value);
1843 
1844  // Record this variable definition.
1845  GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] =
1846  *DefinedNumericVariable;
1847  } else {
1848  // String variable definition.
1849  std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
1850  StringRef CmdlineName = CmdlineNameVal.first;
1851  StringRef OrigCmdlineName = CmdlineName;
1853  FileCheckPattern::parseVariable(CmdlineName, SM);
1854  if (!ParseVarResult) {
1855  Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
1856  continue;
1857  }
1858  // Check that CmdlineName does not denote a pseudo variable is only
1859  // composed of the parsed numeric variable. This catches cases like
1860  // "FOO+2" in a "FOO+2=10" definition.
1861  if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
1862  Errs = joinErrors(std::move(Errs),
1864  SM, OrigCmdlineName,
1865  "invalid name in string variable definition '" +
1866  OrigCmdlineName + "'"));
1867  continue;
1868  }
1869  StringRef Name = ParseVarResult->Name;
1870 
1871  // Detect collisions between string and numeric variables when the former
1872  // is created later than the latter.
1873  if (GlobalNumericVariableTable.find(Name) !=
1874  GlobalNumericVariableTable.end()) {
1875  Errs = joinErrors(std::move(Errs), FileCheckErrorDiagnostic::get(
1876  SM, Name,
1877  "numeric variable with name '" +
1878  Name + "' already exists"));
1879  continue;
1880  }
1881  GlobalVariableTable.insert(CmdlineNameVal);
1882  // Mark the string variable as defined to detect collisions between
1883  // string and numeric variables in defineCmdlineVariables when the latter
1884  // is created later than the former. We cannot reuse GlobalVariableTable
1885  // for this by populating it with an empty string since we would then
1886  // lose the ability to detect the use of an undefined variable in
1887  // match().
1888  DefinedVariableTable[Name] = true;
1889  }
1890  }
1891 
1892  return Errs;
1893 }
1894 
1896  SmallVector<StringRef, 16> LocalPatternVars, LocalNumericVars;
1897  for (const StringMapEntry<StringRef> &Var : GlobalVariableTable)
1898  if (Var.first()[0] != '$')
1899  LocalPatternVars.push_back(Var.first());
1900 
1901  // Numeric substitution reads the value of a variable directly, not via
1902  // GlobalNumericVariableTable. Therefore, we clear local variables by
1903  // clearing their value which will lead to a numeric substitution failure. We
1904  // also mark the variable for removal from GlobalNumericVariableTable since
1905  // this is what defineCmdlineVariables checks to decide that no global
1906  // variable has been defined.
1907  for (const auto &Var : GlobalNumericVariableTable)
1908  if (Var.first()[0] != '$') {
1909  Var.getValue()->clearValue();
1910  LocalNumericVars.push_back(Var.first());
1911  }
1912 
1913  for (const auto &Var : LocalPatternVars)
1914  GlobalVariableTable.erase(Var);
1915  for (const auto &Var : LocalNumericVars)
1916  GlobalNumericVariableTable.erase(Var);
1917 }
1918 
1920  ArrayRef<FileCheckString> CheckStrings,
1921  std::vector<FileCheckDiag> *Diags) {
1922  bool ChecksFailed = false;
1923 
1924  unsigned i = 0, j = 0, e = CheckStrings.size();
1925  while (true) {
1926  StringRef CheckRegion;
1927  if (j == e) {
1928  CheckRegion = Buffer;
1929  } else {
1930  const FileCheckString &CheckLabelStr = CheckStrings[j];
1931  if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
1932  ++j;
1933  continue;
1934  }
1935 
1936  // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
1937  size_t MatchLabelLen = 0;
1938  size_t MatchLabelPos =
1939  CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, Req, Diags);
1940  if (MatchLabelPos == StringRef::npos)
1941  // Immediately bail if CHECK-LABEL fails, nothing else we can do.
1942  return false;
1943 
1944  CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
1945  Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
1946  ++j;
1947  }
1948 
1949  // Do not clear the first region as it's the one before the first
1950  // CHECK-LABEL and it would clear variables defined on the command-line
1951  // before they get used.
1952  if (i != 0 && Req.EnableVarScope)
1953  PatternContext.clearLocalVars();
1954 
1955  for (; i != j; ++i) {
1956  const FileCheckString &CheckStr = CheckStrings[i];
1957 
1958  // Check each string within the scanned region, including a second check
1959  // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
1960  size_t MatchLen = 0;
1961  size_t MatchPos =
1962  CheckStr.Check(SM, CheckRegion, false, MatchLen, Req, Diags);
1963 
1964  if (MatchPos == StringRef::npos) {
1965  ChecksFailed = true;
1966  i = j;
1967  break;
1968  }
1969 
1970  CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
1971  }
1972 
1973  if (j == e)
1974  break;
1975  }
1976 
1977  // Success if no checks failed.
1978  return !ChecksFailed;
1979 }
uint64_t CallInst * C
static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat, int MatchedCount, StringRef Buffer, bool VerboseVerbose, std::vector< FileCheckDiag > *Diags, Error MatchErrors)
Definition: FileCheck.cpp:1322
static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg)
Definition: FileCheck.h:395
Represents a range in source code.
Definition: SMLoc.h:48
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with only the first N elements remaining.
Definition: StringRef.h:601
Indicates a good match for an expected pattern.
Definition: FileCheck.h:652
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Indicates no match for an excluded pattern.
Definition: FileCheck.h:661
Parsing information about a variable.
Definition: FileCheck.h:502
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:232
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMap.h:125
Indicates a discarded match for an expected pattern.
Definition: FileCheck.h:659
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:270
void push_back(const T &Elt)
Definition: SmallVector.h:211
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:663
bool CheckSame(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is no newline in the given Buffer.
Definition: FileCheck.cpp:1534
static std::string escape(StringRef String)
Turn String into a regex by escaping its special characters.
Definition: Regex.cpp:200
iterator find(StringRef Key)
Definition: StringMap.h:332
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:530
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::string getDescription(StringRef Prefix) const
Definition: FileCheck.cpp:950
Marks when parsing found a -NOT check combined with another CHECK suffix.
Definition: FileCheck.h:273
size_t getBufferSize() const
Definition: MemoryBuffer.h:61
Regex buildCheckPrefixRegex()
Definition: FileCheck.cpp:1737
LLVM_NODISCARD StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:803
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
void printSubstitutions(const SourceMgr &SM, StringRef Buffer, SMRange MatchRange=None) const
Prints the value of successful substitutions or the name of the undefined string or numeric variables...
Definition: FileCheck.cpp:715
void reserve(size_type N)
Definition: SmallVector.h:369
std::pair< unsigned, unsigned > getLineAndColumn(SMLoc Loc, unsigned BufferID=0) const
Find the line and column number for the specified location in the specified file. ...
Definition: SourceMgr.cpp:125
LLVM_NODISCARD unsigned edit_distance(StringRef Other, bool AllowReplacements=true, unsigned MaxEditDistance=0) const
Determine the edit distance between this string and another string.
Definition: StringRef.cpp:94
size_t CheckDag(const SourceMgr &SM, StringRef Buffer, std::vector< const FileCheckPattern *> &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Matches "dag strings" and their mixed "not strings".
Definition: FileCheck.cpp:1583
bool CheckNext(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is a single line in the given Buffer.
Definition: FileCheck.cpp:1495
SMLoc Start
Definition: SMLoc.h:50
Class representing a numeric variable and its associated current value.
Definition: FileCheck.h:96
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const SmallVectorImpl< std::pair< SDValue, SDNode *>> &RecordedNodes)
CheckSame - Implements OP_CheckSame.
StringRef Prefix
Which prefix name this check matched.
Definition: FileCheck.h:690
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:47
FileCheckPattern Pat
The pattern to match.
Definition: FileCheck.h:687
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:242
Class holding the FileCheckPattern global state, shared by all patterns: tables holding values of var...
Definition: FileCheck.h:302
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:634
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:471
SMLoc Loc
The location in the match file that the check string was specified.
Definition: FileCheck.h:693
Check::FileCheckType CheckTy
What is the FileCheck directive for this diagnostic?
Definition: FileCheck.h:633
Indicates a match for an expected pattern, but the match is on the wrong line.
Definition: FileCheck.h:657
bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM, const FileCheckRequest &Req)
Parses the pattern in PatternStr and initializes this FileCheckPattern instance accordingly.
Definition: FileCheck.cpp:318
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:693
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:53
Class representing a substitution to perform in the RegExStr string.
Definition: FileCheck.h:187
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:592
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
Marks when parsing found a -COUNT directive with invalid count value.
Definition: FileCheck.h:276
void setValue(uint64_t NewValue)
Sets value of this numeric variable to NewValue.
Definition: FileCheck.h:123
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:60
static Expected< std::unique_ptr< FileCheckExpressionAST > > parseNumericSubstitutionBlock(StringRef Expr, Optional< FileCheckNumericVariable *> &DefinedNumericVariable, bool IsLegacyLineExpr, Optional< size_t > LineNumber, FileCheckPatternContext *Context, const SourceMgr &SM)
Parses Expr for a numeric substitution block at line LineNumber, or before input is parsed if LineNum...
Definition: FileCheck.cpp:266
Class to represent an error holding a diagnostic with location information used when printing it...
Definition: FileCheck.h:379
static std::pair< Check::FileCheckType, StringRef > FindCheckType(StringRef Buffer, StringRef Prefix)
Definition: FileCheck.cpp:981
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:526
static unsigned CountNumNewlinesBetween(StringRef Range, const char *&FirstNewLine)
Counts the number of newlines in the specified range.
Definition: FileCheck.cpp:1391
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition: SourceMgr.h:153
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
Contains info about various FileCheck options.
Definition: FileCheck.h:30
static bool ValidateCheckPrefix(StringRef CheckPrefix)
Definition: FileCheck.cpp:1714
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
Expected< uint64_t > eval() const
Definition: FileCheck.cpp:27
size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode, size_t &MatchLen, FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Matches check string and its "not strings" and/or "dag strings".
Definition: FileCheck.cpp:1413
void append(in_iter S, in_iter E)
Append from an iterator pair.
Definition: SmallString.h:74
bool ValidateCheckPrefixes()
Definition: FileCheck.cpp:1719
unsigned InputEndLine
Definition: FileCheck.h:674
#define P(N)
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:852
A check that we found in the input file.
Definition: FileCheck.h:685
void clearLocalVars()
Undefines local variables (variables whose name does not start with a &#39;$&#39; sign), i.e.
Definition: FileCheck.cpp:1895
FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy, SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange)
Definition: FileCheck.cpp:922
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
StringRef CanonicalizeFile(MemoryBuffer &MB, SmallVectorImpl< char > &OutputBuffer)
Canonicalizes whitespaces in the file.
Definition: FileCheck.cpp:893
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:249
Optional< size_t > getDefLineNumber()
Definition: FileCheck.h:131
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:299
unsigned CheckLine
Where is the FileCheck directive for this diagnostic?
Definition: FileCheck.h:635
SMLoc getLoc() const
Definition: FileCheck.h:492
void createLineVariable()
Create pseudo variable.
Definition: FileCheck.cpp:1112
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
Definition: SourceMgr.h:41
Optional< uint64_t > getValue() const
Definition: FileCheck.h:120
Check::FileCheckType getCheckTy() const
Definition: FileCheck.h:564
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
size_t size() const
Definition: SmallVector.h:52
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:155
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:61
Class to represent an undefined variable error, which quotes that variable&#39;s name when printed...
Definition: FileCheck.h:73
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::pair< typename base::iterator, bool > insert(StringRef Key)
Definition: StringSet.h:38
bool ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, std::vector< FileCheckString > &CheckStrings)
Reads the check file from Buffer and records the expected strings it contains in the CheckStrings vec...
Definition: FileCheck.cpp:1119
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:492
Indicates the pattern only matches the end of file.
Definition: FileCheck.h:270
bool isValid() const
Definition: SMLoc.h:59
static size_t SkipWord(StringRef Str, size_t Loc)
Definition: FileCheck.cpp:1036
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:904
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning &#39;\&#39;, &#39;&#39;, &#39; &#39;, &#39;"&#39;, and anything that doesn&#39;t satisfy llvm::isPrint into an escape...
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
Indicates a fuzzy match that serves as a suggestion for the next intended match for an expected patte...
Definition: FileCheck.h:668
static std::pair< StringRef, StringRef > FindFirstMatchingPrefix(Regex &PrefixRE, StringRef &Buffer, unsigned &LineNumber, Check::FileCheckType &CheckTy)
Searches the buffer for the first prefix in the prefix regular expression.
Definition: FileCheck.cpp:1066
constexpr StringLiteral SpaceChars
Definition: FileCheck.cpp:102
void log(raw_ostream &OS) const override
Print diagnostic associated with this error when printing the error.
Definition: FileCheck.h:393
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:214
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
This is a utility class that provides an abstraction for the common functionality between Instruction...
Definition: Operator.h:30
Indicates no match for an expected pattern, but this might follow good matches when multiple matches ...
Definition: FileCheck.h:665
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:710
static Expected< VariableProperties > parseVariable(StringRef &Str, const SourceMgr &SM)
Parses the string at the start of Str for a variable name.
Definition: FileCheck.cpp:73
bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, or matching, if any...
Definition: Regex.cpp:55
StringRef str()
Return a StringRef for the vector contents.
Definition: raw_ostream.h:555
unsigned InputEndCol
Definition: FileCheck.h:675
uint64_t(*)(uint64_t, uint64_t) binop_eval_t
Type of functions evaluating a given binary operation.
Definition: FileCheck.h:154
std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:223
Expected< uint64_t > eval() const
Evaluates the value of the binary operation represented by this AST, using EvalBinop on the result of...
Definition: FileCheck.cpp:35
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:41
static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat, int MatchedCount, StringRef Buffer, size_t MatchPos, size_t MatchLen, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags)
Definition: FileCheck.cpp:1276
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:940
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it...
static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy, const SourceMgr &SM, SMLoc Loc, Check::FileCheckType CheckTy, StringRef Buffer, size_t Pos, size_t Len, std::vector< FileCheckDiag > *Diags, bool AdjustPrevDiag=false)
Definition: FileCheck.cpp:757
bool CheckNot(const SourceMgr &SM, StringRef Buffer, const std::vector< const FileCheckPattern *> &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Verifies that none of the strings in NotStrings are found in the given Buffer.
Definition: FileCheck.cpp:1556
SMLoc End
Definition: SMLoc.h:50
void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, std::vector< FileCheckDiag > *Diags) const
Definition: FileCheck.cpp:775
unsigned getNumMatches() const
getNumMatches - In a valid regex, return the number of parenthesized matches it contains.
Definition: Regex.cpp:68
Expected< StringRef > getPatternVarValue(StringRef VarName)
Definition: FileCheck.cpp:823
iterator begin() const
Definition: StringRef.h:115
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
unsigned InputStartLine
The search range if MatchTy is MatchNoneAndExcluded or MatchNoneButExpected, or the match range other...
Definition: FileCheck.h:672
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:174
bool CheckInput(SourceMgr &SM, StringRef Buffer, ArrayRef< FileCheckString > CheckStrings, std::vector< FileCheckDiag > *Diags=nullptr)
Checks the input to FileCheck provided in the Buffer against the CheckStrings read from the check fil...
Definition: FileCheck.cpp:1919
Indicates a match for an excluded pattern.
Definition: FileCheck.h:654
const char * getBufferEnd() const
Definition: MemoryBuffer.h:60
FileCheckType & setCount(int C)
Definition: FileCheck.cpp:942
pointer data()
Return a pointer to the vector&#39;s buffer, even if empty().
Definition: SmallVector.h:144
static const size_t npos
Definition: StringRef.h:50
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:423
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:394
#define I(x, y, z)
Definition: MD5.cpp:58
const char * getBufferStart() const
Definition: MemoryBuffer.h:59
static bool IsPartOfWord(char c)
Definition: FileCheck.cpp:938
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
unsigned InputStartCol
Definition: FileCheck.h:673
Expected< size_t > match(StringRef Buffer, size_t &MatchLen, const SourceMgr &SM) const
Matches the pattern string against the input buffer Buffer.
Definition: FileCheck.cpp:610
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:148
Error defineCmdlineVariables(std::vector< std::string > &CmdlineDefines, SourceMgr &SM)
Defines string and numeric variables from definitions given on the command line, passed as a vector o...
Definition: FileCheck.cpp:1756
LLVM Value Representation.
Definition: Value.h:73
static char popFront(StringRef &S)
Definition: FileCheck.cpp:105
Compile for newline-sensitive matching.
Definition: Regex.h:38
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:27
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:881
static uint64_t sub(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:218
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr)
matches - Match the regex against a given String.
Definition: Regex.cpp:72
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
MatchType
What type of match result does this diagnostic describe?
Definition: FileCheck.h:650
int getCount() const
Definition: FileCheck.h:566
Represents a location in source code.
Definition: SMLoc.h:23
iterator end() const
Definition: StringRef.h:117
static bool isValidVarNameStart(char C)
Definition: FileCheck.cpp:68
iterator end()
Definition: StringMap.h:317