LLVM  13.0.0git
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 
17 #include "FileCheckImpl.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/StringSet.h"
20 #include "llvm/ADT/Twine.h"
23 #include <cstdint>
24 #include <list>
25 #include <set>
26 #include <tuple>
27 #include <utility>
28 
29 using namespace llvm;
30 
32  switch (Value) {
33  case Kind::NoFormat:
34  return StringRef("<none>");
35  case Kind::Unsigned:
36  return StringRef("%u");
37  case Kind::Signed:
38  return StringRef("%d");
39  case Kind::HexUpper:
40  return StringRef("%X");
41  case Kind::HexLower:
42  return StringRef("%x");
43  }
44  llvm_unreachable("unknown expression format");
45 }
46 
48  StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef();
49 
50  auto CreatePrecisionRegex = [&](StringRef S) {
51  return (Twine(AlternateFormPrefix) + S + Twine('{') + Twine(Precision) +
52  "}")
53  .str();
54  };
55 
56  switch (Value) {
57  case Kind::Unsigned:
58  if (Precision)
59  return CreatePrecisionRegex("([1-9][0-9]*)?[0-9]");
60  return std::string("[0-9]+");
61  case Kind::Signed:
62  if (Precision)
63  return CreatePrecisionRegex("-?([1-9][0-9]*)?[0-9]");
64  return std::string("-?[0-9]+");
65  case Kind::HexUpper:
66  if (Precision)
67  return CreatePrecisionRegex("([1-9A-F][0-9A-F]*)?[0-9A-F]");
68  return (Twine(AlternateFormPrefix) + Twine("[0-9A-F]+")).str();
69  case Kind::HexLower:
70  if (Precision)
71  return CreatePrecisionRegex("([1-9a-f][0-9a-f]*)?[0-9a-f]");
72  return (Twine(AlternateFormPrefix) + Twine("[0-9a-f]+")).str();
73  default:
74  return createStringError(std::errc::invalid_argument,
75  "trying to match value with invalid format");
76  }
77 }
78 
81  uint64_t AbsoluteValue;
82  StringRef SignPrefix = IntegerValue.isNegative() ? "-" : "";
83 
84  if (Value == Kind::Signed) {
85  Expected<int64_t> SignedValue = IntegerValue.getSignedValue();
86  if (!SignedValue)
87  return SignedValue.takeError();
88  if (*SignedValue < 0)
89  AbsoluteValue = cantFail(IntegerValue.getAbsolute().getUnsignedValue());
90  else
91  AbsoluteValue = *SignedValue;
92  } else {
93  Expected<uint64_t> UnsignedValue = IntegerValue.getUnsignedValue();
94  if (!UnsignedValue)
95  return UnsignedValue.takeError();
96  AbsoluteValue = *UnsignedValue;
97  }
98 
99  std::string AbsoluteValueStr;
100  switch (Value) {
101  case Kind::Unsigned:
102  case Kind::Signed:
103  AbsoluteValueStr = utostr(AbsoluteValue);
104  break;
105  case Kind::HexUpper:
106  case Kind::HexLower:
107  AbsoluteValueStr = utohexstr(AbsoluteValue, Value == Kind::HexLower);
108  break;
109  default:
110  return createStringError(std::errc::invalid_argument,
111  "trying to match value with invalid format");
112  }
113 
114  StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef();
115 
116  if (Precision > AbsoluteValueStr.size()) {
117  unsigned LeadingZeros = Precision - AbsoluteValueStr.size();
118  return (Twine(SignPrefix) + Twine(AlternateFormPrefix) +
119  std::string(LeadingZeros, '0') + AbsoluteValueStr)
120  .str();
121  }
122 
123  return (Twine(SignPrefix) + Twine(AlternateFormPrefix) + AbsoluteValueStr)
124  .str();
125 }
126 
129  const SourceMgr &SM) const {
130  bool ValueIsSigned = Value == Kind::Signed;
131  // Both the FileCheck utility and library only call this method with a valid
132  // value in StrVal. This is guaranteed by the regex returned by
133  // getWildcardRegex() above. Only underflow and overflow errors can thus
134  // occur. However new uses of this method could be added in the future so
135  // the error message does not make assumptions about StrVal.
136  StringRef IntegerParseErrorStr = "unable to represent numeric value";
137  if (ValueIsSigned) {
138  int64_t SignedValue;
139 
140  if (StrVal.getAsInteger(10, SignedValue))
141  return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr);
142 
143  return ExpressionValue(SignedValue);
144  }
145 
146  bool Hex = Value == Kind::HexUpper || Value == Kind::HexLower;
147  uint64_t UnsignedValue;
148  bool MissingFormPrefix = AlternateForm && !StrVal.consume_front("0x");
149  if (StrVal.getAsInteger(Hex ? 16 : 10, UnsignedValue))
150  return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr);
151 
152  // Error out for a missing prefix only now that we know we have an otherwise
153  // valid integer. For example, "-0x18" is reported above instead.
154  if (MissingFormPrefix)
155  return ErrorDiagnostic::get(SM, StrVal, "missing alternate form prefix");
156 
157  return ExpressionValue(UnsignedValue);
158 }
159 
160 static int64_t getAsSigned(uint64_t UnsignedValue) {
161  // Use memcpy to reinterpret the bitpattern in Value since casting to
162  // signed is implementation-defined if the unsigned value is too big to be
163  // represented in the signed type and using an union violates type aliasing
164  // rules.
165  int64_t SignedValue;
166  memcpy(&SignedValue, &UnsignedValue, sizeof(SignedValue));
167  return SignedValue;
168 }
169 
171  if (Negative)
172  return getAsSigned(Value);
173 
174  if (Value > (uint64_t)std::numeric_limits<int64_t>::max())
175  return make_error<OverflowError>();
176 
177  // Value is in the representable range of int64_t so we can use cast.
178  return static_cast<int64_t>(Value);
179 }
180 
182  if (Negative)
183  return make_error<OverflowError>();
184 
185  return Value;
186 }
187 
189  if (!Negative)
190  return *this;
191 
192  int64_t SignedValue = getAsSigned(Value);
193  int64_t MaxInt64 = std::numeric_limits<int64_t>::max();
194  // Absolute value can be represented as int64_t.
195  if (SignedValue >= -MaxInt64)
197 
198  // -X == -(max int64_t + Rem), negate each component independently.
199  SignedValue += MaxInt64;
200  uint64_t RemainingValueAbsolute = -SignedValue;
201  return ExpressionValue(MaxInt64 + RemainingValueAbsolute);
202 }
203 
205  const ExpressionValue &RightOperand) {
206  if (LeftOperand.isNegative() && RightOperand.isNegative()) {
207  int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
208  int64_t RightValue = cantFail(RightOperand.getSignedValue());
209  Optional<int64_t> Result = checkedAdd<int64_t>(LeftValue, RightValue);
210  if (!Result)
211  return make_error<OverflowError>();
212 
213  return ExpressionValue(*Result);
214  }
215 
216  // (-A) + B == B - A.
217  if (LeftOperand.isNegative())
218  return RightOperand - LeftOperand.getAbsolute();
219 
220  // A + (-B) == A - B.
221  if (RightOperand.isNegative())
222  return LeftOperand - RightOperand.getAbsolute();
223 
224  // Both values are positive at this point.
225  uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
226  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
227  Optional<uint64_t> Result =
228  checkedAddUnsigned<uint64_t>(LeftValue, RightValue);
229  if (!Result)
230  return make_error<OverflowError>();
231 
232  return ExpressionValue(*Result);
233 }
234 
236  const ExpressionValue &RightOperand) {
237  // Result will be negative and thus might underflow.
238  if (LeftOperand.isNegative() && !RightOperand.isNegative()) {
239  int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
240  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
241  // Result <= -1 - (max int64_t) which overflows on 1- and 2-complement.
242  if (RightValue > (uint64_t)std::numeric_limits<int64_t>::max())
243  return make_error<OverflowError>();
244  Optional<int64_t> Result =
245  checkedSub(LeftValue, static_cast<int64_t>(RightValue));
246  if (!Result)
247  return make_error<OverflowError>();
248 
249  return ExpressionValue(*Result);
250  }
251 
252  // (-A) - (-B) == B - A.
253  if (LeftOperand.isNegative())
254  return RightOperand.getAbsolute() - LeftOperand.getAbsolute();
255 
256  // A - (-B) == A + B.
257  if (RightOperand.isNegative())
258  return LeftOperand + RightOperand.getAbsolute();
259 
260  // Both values are positive at this point.
261  uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
262  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
263  if (LeftValue >= RightValue)
264  return ExpressionValue(LeftValue - RightValue);
265  else {
266  uint64_t AbsoluteDifference = RightValue - LeftValue;
267  uint64_t MaxInt64 = std::numeric_limits<int64_t>::max();
268  // Value might underflow.
269  if (AbsoluteDifference > MaxInt64) {
270  AbsoluteDifference -= MaxInt64;
271  int64_t Result = -MaxInt64;
272  int64_t MinInt64 = std::numeric_limits<int64_t>::min();
273  // Underflow, tested by:
274  // abs(Result + (max int64_t)) > abs((min int64_t) + (max int64_t))
275  if (AbsoluteDifference > static_cast<uint64_t>(-(MinInt64 - Result)))
276  return make_error<OverflowError>();
277  Result -= static_cast<int64_t>(AbsoluteDifference);
278  return ExpressionValue(Result);
279  }
280 
281  return ExpressionValue(-static_cast<int64_t>(AbsoluteDifference));
282  }
283 }
284 
286  const ExpressionValue &RightOperand) {
287  // -A * -B == A * B
288  if (LeftOperand.isNegative() && RightOperand.isNegative())
289  return LeftOperand.getAbsolute() * RightOperand.getAbsolute();
290 
291  // A * -B == -B * A
292  if (RightOperand.isNegative())
293  return RightOperand * LeftOperand;
294 
295  assert(!RightOperand.isNegative() && "Unexpected negative operand!");
296 
297  // Result will be negative and can underflow.
298  if (LeftOperand.isNegative()) {
299  auto Result = LeftOperand.getAbsolute() * RightOperand.getAbsolute();
300  if (!Result)
301  return Result;
302 
303  return ExpressionValue(0) - *Result;
304  }
305 
306  // Result will be positive and can overflow.
307  uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
308  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
309  Optional<uint64_t> Result =
310  checkedMulUnsigned<uint64_t>(LeftValue, RightValue);
311  if (!Result)
312  return make_error<OverflowError>();
313 
314  return ExpressionValue(*Result);
315 }
316 
318  const ExpressionValue &RightOperand) {
319  // -A / -B == A / B
320  if (LeftOperand.isNegative() && RightOperand.isNegative())
321  return LeftOperand.getAbsolute() / RightOperand.getAbsolute();
322 
323  // Check for divide by zero.
324  if (RightOperand == ExpressionValue(0))
325  return make_error<OverflowError>();
326 
327  // Result will be negative and can underflow.
328  if (LeftOperand.isNegative() || RightOperand.isNegative())
329  return ExpressionValue(0) -
330  cantFail(LeftOperand.getAbsolute() / RightOperand.getAbsolute());
331 
332  uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
333  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
334  return ExpressionValue(LeftValue / RightValue);
335 }
336 
338  const ExpressionValue &RightOperand) {
339  if (LeftOperand.isNegative() && RightOperand.isNegative()) {
340  int64_t LeftValue = cantFail(LeftOperand.getSignedValue());
341  int64_t RightValue = cantFail(RightOperand.getSignedValue());
342  return ExpressionValue(std::max(LeftValue, RightValue));
343  }
344 
345  if (!LeftOperand.isNegative() && !RightOperand.isNegative()) {
346  uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
347  uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
348  return ExpressionValue(std::max(LeftValue, RightValue));
349  }
350 
351  if (LeftOperand.isNegative())
352  return RightOperand;
353 
354  return LeftOperand;
355 }
356 
358  const ExpressionValue &RightOperand) {
359  if (cantFail(max(LeftOperand, RightOperand)) == LeftOperand)
360  return RightOperand;
361 
362  return LeftOperand;
363 }
364 
367  if (Value)
368  return *Value;
369 
370  return make_error<UndefVarError>(getExpressionStr());
371 }
372 
374  Expected<ExpressionValue> LeftOp = LeftOperand->eval();
375  Expected<ExpressionValue> RightOp = RightOperand->eval();
376 
377  // Bubble up any error (e.g. undefined variables) in the recursive
378  // evaluation.
379  if (!LeftOp || !RightOp) {
380  Error Err = Error::success();
381  if (!LeftOp)
382  Err = joinErrors(std::move(Err), LeftOp.takeError());
383  if (!RightOp)
384  Err = joinErrors(std::move(Err), RightOp.takeError());
385  return std::move(Err);
386  }
387 
388  return EvalBinop(*LeftOp, *RightOp);
389 }
390 
393  Expected<ExpressionFormat> LeftFormat = LeftOperand->getImplicitFormat(SM);
394  Expected<ExpressionFormat> RightFormat = RightOperand->getImplicitFormat(SM);
395  if (!LeftFormat || !RightFormat) {
396  Error Err = Error::success();
397  if (!LeftFormat)
398  Err = joinErrors(std::move(Err), LeftFormat.takeError());
399  if (!RightFormat)
400  Err = joinErrors(std::move(Err), RightFormat.takeError());
401  return std::move(Err);
402  }
403 
404  if (*LeftFormat != ExpressionFormat::Kind::NoFormat &&
405  *RightFormat != ExpressionFormat::Kind::NoFormat &&
406  *LeftFormat != *RightFormat)
407  return ErrorDiagnostic::get(
408  SM, getExpressionStr(),
409  "implicit format conflict between '" + LeftOperand->getExpressionStr() +
410  "' (" + LeftFormat->toString() + ") and '" +
411  RightOperand->getExpressionStr() + "' (" + RightFormat->toString() +
412  "), need an explicit format specifier");
413 
414  return *LeftFormat != ExpressionFormat::Kind::NoFormat ? *LeftFormat
415  : *RightFormat;
416 }
417 
419  assert(ExpressionPointer->getAST() != nullptr &&
420  "Substituting empty expression");
421  Expected<ExpressionValue> EvaluatedValue =
422  ExpressionPointer->getAST()->eval();
423  if (!EvaluatedValue)
424  return EvaluatedValue.takeError();
425  ExpressionFormat Format = ExpressionPointer->getFormat();
426  return Format.getMatchingString(*EvaluatedValue);
427 }
428 
430  // Look up the value and escape it so that we can put it into the regex.
432  if (!VarVal)
433  return VarVal.takeError();
434  return Regex::escape(*VarVal);
435 }
436 
437 bool Pattern::isValidVarNameStart(char C) { return C == '_' || isAlpha(C); }
438 
441  if (Str.empty())
442  return ErrorDiagnostic::get(SM, Str, "empty variable name");
443 
444  size_t I = 0;
445  bool IsPseudo = Str[0] == '@';
446 
447  // Global vars start with '$'.
448  if (Str[0] == '$' || IsPseudo)
449  ++I;
450 
451  if (!isValidVarNameStart(Str[I++]))
452  return ErrorDiagnostic::get(SM, Str, "invalid variable name");
453 
454  for (size_t E = Str.size(); I != E; ++I)
455  // Variable names are composed of alphanumeric characters and underscores.
456  if (Str[I] != '_' && !isAlnum(Str[I]))
457  break;
458 
459  StringRef Name = Str.take_front(I);
460  Str = Str.substr(I);
461  return VariableProperties {Name, IsPseudo};
462 }
463 
464 // StringRef holding all characters considered as horizontal whitespaces by
465 // FileCheck input canonicalization.
466 constexpr StringLiteral SpaceChars = " \t";
467 
468 // Parsing helper function that strips the first character in S and returns it.
469 static char popFront(StringRef &S) {
470  char C = S.front();
471  S = S.drop_front();
472  return C;
473 }
474 
475 char OverflowError::ID = 0;
476 char UndefVarError::ID = 0;
477 char ErrorDiagnostic::ID = 0;
478 char NotFoundError::ID = 0;
479 char ErrorReported::ID = 0;
480 
481 Expected<NumericVariable *> Pattern::parseNumericVariableDefinition(
483  Optional<size_t> LineNumber, ExpressionFormat ImplicitFormat,
484  const SourceMgr &SM) {
485  Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM);
486  if (!ParseVarResult)
487  return ParseVarResult.takeError();
488  StringRef Name = ParseVarResult->Name;
489 
490  if (ParseVarResult->IsPseudo)
491  return ErrorDiagnostic::get(
492  SM, Name, "definition of pseudo numeric variable unsupported");
493 
494  // Detect collisions between string and numeric variables when the latter
495  // is created later than the former.
496  if (Context->DefinedVariableTable.find(Name) !=
497  Context->DefinedVariableTable.end())
498  return ErrorDiagnostic::get(
499  SM, Name, "string variable with name '" + Name + "' already exists");
500 
501  Expr = Expr.ltrim(SpaceChars);
502  if (!Expr.empty())
503  return ErrorDiagnostic::get(
504  SM, Expr, "unexpected characters after numeric variable name");
505 
506  NumericVariable *DefinedNumericVariable;
507  auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
508  if (VarTableIter != Context->GlobalNumericVariableTable.end()) {
509  DefinedNumericVariable = VarTableIter->second;
510  if (DefinedNumericVariable->getImplicitFormat() != ImplicitFormat)
511  return ErrorDiagnostic::get(
512  SM, Expr, "format different from previous variable definition");
513  } else
514  DefinedNumericVariable =
515  Context->makeNumericVariable(Name, ImplicitFormat, LineNumber);
516 
517  return DefinedNumericVariable;
518 }
519 
520 Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
521  StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
523  if (IsPseudo && !Name.equals("@LINE"))
524  return ErrorDiagnostic::get(
525  SM, Name, "invalid pseudo numeric variable '" + Name + "'");
526 
527  // Numeric variable definitions and uses are parsed in the order in which
528  // they appear in the CHECK patterns. For each definition, the pointer to the
529  // class instance of the corresponding numeric variable definition is stored
530  // in GlobalNumericVariableTable in parsePattern. Therefore, if the pointer
531  // we get below is null, it means no such variable was defined before. When
532  // that happens, we create a dummy variable so that parsing can continue. All
533  // uses of undefined variables, whether string or numeric, are then diagnosed
534  // in printSubstitutions() after failing to match.
535  auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
537  if (VarTableIter != Context->GlobalNumericVariableTable.end())
538  NumericVariable = VarTableIter->second;
539  else {
540  NumericVariable = Context->makeNumericVariable(
542  Context->GlobalNumericVariableTable[Name] = NumericVariable;
543  }
544 
546  if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber)
547  return ErrorDiagnostic::get(
548  SM, Name,
549  "numeric variable '" + Name +
550  "' defined earlier in the same CHECK directive");
551 
552  return std::make_unique<NumericVariableUse>(Name, NumericVariable);
553 }
554 
555 Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
556  StringRef &Expr, AllowedOperand AO, bool MaybeInvalidConstraint,
558  const SourceMgr &SM) {
559  if (Expr.startswith("(")) {
560  if (AO != AllowedOperand::Any)
561  return ErrorDiagnostic::get(
562  SM, Expr, "parenthesized expression not permitted here");
563  return parseParenExpr(Expr, LineNumber, Context, SM);
564  }
565 
566  if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) {
567  // Try to parse as a numeric variable use.
569  parseVariable(Expr, SM);
570  if (ParseVarResult) {
571  // Try to parse a function call.
572  if (Expr.ltrim(SpaceChars).startswith("(")) {
573  if (AO != AllowedOperand::Any)
574  return ErrorDiagnostic::get(SM, ParseVarResult->Name,
575  "unexpected function call");
576 
577  return parseCallExpr(Expr, ParseVarResult->Name, LineNumber, Context,
578  SM);
579  }
580 
581  return parseNumericVariableUse(ParseVarResult->Name,
582  ParseVarResult->IsPseudo, LineNumber,
583  Context, SM);
584  }
585 
586  if (AO == AllowedOperand::LineVar)
587  return ParseVarResult.takeError();
588  // Ignore the error and retry parsing as a literal.
589  consumeError(ParseVarResult.takeError());
590  }
591 
592  // Otherwise, parse it as a literal.
593  int64_t SignedLiteralValue;
594  uint64_t UnsignedLiteralValue;
595  StringRef SaveExpr = Expr;
596  // Accept both signed and unsigned literal, default to signed literal.
597  if (!Expr.consumeInteger((AO == AllowedOperand::LegacyLiteral) ? 10 : 0,
598  UnsignedLiteralValue))
599  return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()),
600  UnsignedLiteralValue);
601  Expr = SaveExpr;
602  if (AO == AllowedOperand::Any && !Expr.consumeInteger(0, SignedLiteralValue))
603  return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()),
604  SignedLiteralValue);
605 
606  return ErrorDiagnostic::get(
607  SM, Expr,
608  Twine("invalid ") +
609  (MaybeInvalidConstraint ? "matching constraint or " : "") +
610  "operand format");
611 }
612 
614 Pattern::parseParenExpr(StringRef &Expr, Optional<size_t> LineNumber,
616  Expr = Expr.ltrim(SpaceChars);
617  assert(Expr.startswith("("));
618 
619  // Parse right operand.
620  Expr.consume_front("(");
621  Expr = Expr.ltrim(SpaceChars);
622  if (Expr.empty())
623  return ErrorDiagnostic::get(SM, Expr, "missing operand in expression");
624 
625  // Note: parseNumericOperand handles nested opening parentheses.
626  Expected<std::unique_ptr<ExpressionAST>> SubExprResult = parseNumericOperand(
627  Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber,
628  Context, SM);
629  Expr = Expr.ltrim(SpaceChars);
630  while (SubExprResult && !Expr.empty() && !Expr.startswith(")")) {
631  StringRef OrigExpr = Expr;
632  SubExprResult = parseBinop(OrigExpr, Expr, std::move(*SubExprResult), false,
633  LineNumber, Context, SM);
634  Expr = Expr.ltrim(SpaceChars);
635  }
636  if (!SubExprResult)
637  return SubExprResult;
638 
639  if (!Expr.consume_front(")")) {
640  return ErrorDiagnostic::get(SM, Expr,
641  "missing ')' at end of nested expression");
642  }
643  return SubExprResult;
644 }
645 
647 Pattern::parseBinop(StringRef Expr, StringRef &RemainingExpr,
648  std::unique_ptr<ExpressionAST> LeftOp,
649  bool IsLegacyLineExpr, Optional<size_t> LineNumber,
651  RemainingExpr = RemainingExpr.ltrim(SpaceChars);
652  if (RemainingExpr.empty())
653  return std::move(LeftOp);
654 
655  // Check if this is a supported operation and select a function to perform
656  // it.
657  SMLoc OpLoc = SMLoc::getFromPointer(RemainingExpr.data());
658  char Operator = popFront(RemainingExpr);
659  binop_eval_t EvalBinop;
660  switch (Operator) {
661  case '+':
662  EvalBinop = operator+;
663  break;
664  case '-':
665  EvalBinop = operator-;
666  break;
667  default:
668  return ErrorDiagnostic::get(
669  SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'");
670  }
671 
672  // Parse right operand.
673  RemainingExpr = RemainingExpr.ltrim(SpaceChars);
674  if (RemainingExpr.empty())
675  return ErrorDiagnostic::get(SM, RemainingExpr,
676  "missing operand in expression");
677  // The second operand in a legacy @LINE expression is always a literal.
678  AllowedOperand AO =
679  IsLegacyLineExpr ? AllowedOperand::LegacyLiteral : AllowedOperand::Any;
681  parseNumericOperand(RemainingExpr, AO, /*MaybeInvalidConstraint=*/false,
682  LineNumber, Context, SM);
683  if (!RightOpResult)
684  return RightOpResult;
685 
686  Expr = Expr.drop_back(RemainingExpr.size());
687  return std::make_unique<BinaryOperation>(Expr, EvalBinop, std::move(LeftOp),
688  std::move(*RightOpResult));
689 }
690 
692 Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName,
693  Optional<size_t> LineNumber,
695  Expr = Expr.ltrim(SpaceChars);
696  assert(Expr.startswith("("));
697 
698  auto OptFunc = StringSwitch<Optional<binop_eval_t>>(FuncName)
699  .Case("add", operator+)
700  .Case("div", operator/)
701  .Case("max", max)
702  .Case("min", min)
703  .Case("mul", operator*)
704  .Case("sub", operator-)
705  .Default(None);
706 
707  if (!OptFunc)
708  return ErrorDiagnostic::get(
709  SM, FuncName, Twine("call to undefined function '") + FuncName + "'");
710 
711  Expr.consume_front("(");
712  Expr = Expr.ltrim(SpaceChars);
713 
714  // Parse call arguments, which are comma separated.
716  while (!Expr.empty() && !Expr.startswith(")")) {
717  if (Expr.startswith(","))
718  return ErrorDiagnostic::get(SM, Expr, "missing argument");
719 
720  // Parse the argument, which is an arbitary expression.
721  StringRef OuterBinOpExpr = Expr;
722  Expected<std::unique_ptr<ExpressionAST>> Arg = parseNumericOperand(
723  Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber,
724  Context, SM);
725  while (Arg && !Expr.empty()) {
726  Expr = Expr.ltrim(SpaceChars);
727  // Have we reached an argument terminator?
728  if (Expr.startswith(",") || Expr.startswith(")"))
729  break;
730 
731  // Arg = Arg <op> <expr>
732  Arg = parseBinop(OuterBinOpExpr, Expr, std::move(*Arg), false, LineNumber,
733  Context, SM);
734  }
735 
736  // Prefer an expression error over a generic invalid argument message.
737  if (!Arg)
738  return Arg.takeError();
739  Args.push_back(std::move(*Arg));
740 
741  // Have we parsed all available arguments?
742  Expr = Expr.ltrim(SpaceChars);
743  if (!Expr.consume_front(","))
744  break;
745 
746  Expr = Expr.ltrim(SpaceChars);
747  if (Expr.startswith(")"))
748  return ErrorDiagnostic::get(SM, Expr, "missing argument");
749  }
750 
751  if (!Expr.consume_front(")"))
752  return ErrorDiagnostic::get(SM, Expr,
753  "missing ')' at end of call expression");
754 
755  const unsigned NumArgs = Args.size();
756  if (NumArgs == 2)
757  return std::make_unique<BinaryOperation>(Expr, *OptFunc, std::move(Args[0]),
758  std::move(Args[1]));
759 
760  // TODO: Support more than binop_eval_t.
761  return ErrorDiagnostic::get(SM, FuncName,
762  Twine("function '") + FuncName +
763  Twine("' takes 2 arguments but ") +
764  Twine(NumArgs) + " given");
765 }
766 
768  StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable,
769  bool IsLegacyLineExpr, Optional<size_t> LineNumber,
771  std::unique_ptr<ExpressionAST> ExpressionASTPointer = nullptr;
772  StringRef DefExpr = StringRef();
773  DefinedNumericVariable = None;
774  ExpressionFormat ExplicitFormat = ExpressionFormat();
775  unsigned Precision = 0;
776 
777  // Parse format specifier (NOTE: ',' is also an argument seperator).
778  size_t FormatSpecEnd = Expr.find(',');
779  size_t FunctionStart = Expr.find('(');
780  if (FormatSpecEnd != StringRef::npos && FormatSpecEnd < FunctionStart) {
781  StringRef FormatExpr = Expr.take_front(FormatSpecEnd);
782  Expr = Expr.drop_front(FormatSpecEnd + 1);
783  FormatExpr = FormatExpr.trim(SpaceChars);
784  if (!FormatExpr.consume_front("%"))
785  return ErrorDiagnostic::get(
786  SM, FormatExpr,
787  "invalid matching format specification in expression");
788 
789  // Parse alternate form flag.
790  SMLoc AlternateFormFlagLoc = SMLoc::getFromPointer(FormatExpr.data());
791  bool AlternateForm = FormatExpr.consume_front("#");
792 
793  // Parse precision.
794  if (FormatExpr.consume_front(".")) {
795  if (FormatExpr.consumeInteger(10, Precision))
796  return ErrorDiagnostic::get(SM, FormatExpr,
797  "invalid precision in format specifier");
798  }
799 
800  if (!FormatExpr.empty()) {
801  // Check for unknown matching format specifier and set matching format in
802  // class instance representing this expression.
803  SMLoc FmtLoc = SMLoc::getFromPointer(FormatExpr.data());
804  switch (popFront(FormatExpr)) {
805  case 'u':
806  ExplicitFormat =
808  break;
809  case 'd':
810  ExplicitFormat =
812  break;
813  case 'x':
815  Precision, AlternateForm);
816  break;
817  case 'X':
819  Precision, AlternateForm);
820  break;
821  default:
822  return ErrorDiagnostic::get(SM, FmtLoc,
823  "invalid format specifier in expression");
824  }
825  }
826 
827  if (AlternateForm && ExplicitFormat != ExpressionFormat::Kind::HexLower &&
828  ExplicitFormat != ExpressionFormat::Kind::HexUpper)
829  return ErrorDiagnostic::get(
830  SM, AlternateFormFlagLoc,
831  "alternate form only supported for hex values");
832 
833  FormatExpr = FormatExpr.ltrim(SpaceChars);
834  if (!FormatExpr.empty())
835  return ErrorDiagnostic::get(
836  SM, FormatExpr,
837  "invalid matching format specification in expression");
838  }
839 
840  // Save variable definition expression if any.
841  size_t DefEnd = Expr.find(':');
842  if (DefEnd != StringRef::npos) {
843  DefExpr = Expr.substr(0, DefEnd);
844  Expr = Expr.substr(DefEnd + 1);
845  }
846 
847  // Parse matching constraint.
848  Expr = Expr.ltrim(SpaceChars);
849  bool HasParsedValidConstraint = false;
850  if (Expr.consume_front("=="))
851  HasParsedValidConstraint = true;
852 
853  // Parse the expression itself.
854  Expr = Expr.ltrim(SpaceChars);
855  if (Expr.empty()) {
856  if (HasParsedValidConstraint)
857  return ErrorDiagnostic::get(
858  SM, Expr, "empty numeric expression should not have a constraint");
859  } else {
860  Expr = Expr.rtrim(SpaceChars);
861  StringRef OuterBinOpExpr = Expr;
862  // The first operand in a legacy @LINE expression is always the @LINE
863  // pseudo variable.
864  AllowedOperand AO =
865  IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
866  Expected<std::unique_ptr<ExpressionAST>> ParseResult = parseNumericOperand(
867  Expr, AO, !HasParsedValidConstraint, LineNumber, Context, SM);
868  while (ParseResult && !Expr.empty()) {
869  ParseResult = parseBinop(OuterBinOpExpr, Expr, std::move(*ParseResult),
870  IsLegacyLineExpr, LineNumber, Context, SM);
871  // Legacy @LINE expressions only allow 2 operands.
872  if (ParseResult && IsLegacyLineExpr && !Expr.empty())
873  return ErrorDiagnostic::get(
874  SM, Expr,
875  "unexpected characters at end of expression '" + Expr + "'");
876  }
877  if (!ParseResult)
878  return ParseResult.takeError();
879  ExpressionASTPointer = std::move(*ParseResult);
880  }
881 
882  // Select format of the expression, i.e. (i) its explicit format, if any,
883  // otherwise (ii) its implicit format, if any, otherwise (iii) the default
884  // format (unsigned). Error out in case of conflicting implicit format
885  // without explicit format.
886  ExpressionFormat Format;
887  if (ExplicitFormat)
888  Format = ExplicitFormat;
889  else if (ExpressionASTPointer) {
890  Expected<ExpressionFormat> ImplicitFormat =
891  ExpressionASTPointer->getImplicitFormat(SM);
892  if (!ImplicitFormat)
893  return ImplicitFormat.takeError();
894  Format = *ImplicitFormat;
895  }
896  if (!Format)
898 
899  std::unique_ptr<Expression> ExpressionPointer =
900  std::make_unique<Expression>(std::move(ExpressionASTPointer), Format);
901 
902  // Parse the numeric variable definition.
903  if (DefEnd != StringRef::npos) {
904  DefExpr = DefExpr.ltrim(SpaceChars);
905  Expected<NumericVariable *> ParseResult = parseNumericVariableDefinition(
906  DefExpr, Context, LineNumber, ExpressionPointer->getFormat(), SM);
907 
908  if (!ParseResult)
909  return ParseResult.takeError();
910  DefinedNumericVariable = *ParseResult;
911  }
912 
913  return std::move(ExpressionPointer);
914 }
915 
917  SourceMgr &SM, const FileCheckRequest &Req) {
918  bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot;
919  IgnoreCase = Req.IgnoreCase;
920 
921  PatternLoc = SMLoc::getFromPointer(PatternStr.data());
922 
923  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
924  // Ignore trailing whitespace.
925  while (!PatternStr.empty() &&
926  (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
927  PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
928 
929  // Check that there is something on the line.
930  if (PatternStr.empty() && CheckTy != Check::CheckEmpty) {
931  SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
932  "found empty check string with prefix '" + Prefix + ":'");
933  return true;
934  }
935 
936  if (!PatternStr.empty() && CheckTy == Check::CheckEmpty) {
937  SM.PrintMessage(
938  PatternLoc, SourceMgr::DK_Error,
939  "found non-empty check string for empty check with prefix '" + Prefix +
940  ":'");
941  return true;
942  }
943 
944  if (CheckTy == Check::CheckEmpty) {
945  RegExStr = "(\n$)";
946  return false;
947  }
948 
949  // If literal check, set fixed string.
950  if (CheckTy.isLiteralMatch()) {
951  FixedStr = PatternStr;
952  return false;
953  }
954 
955  // Check to see if this is a fixed string, or if it has regex pieces.
956  if (!MatchFullLinesHere &&
957  (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos &&
958  PatternStr.find("[[") == StringRef::npos))) {
959  FixedStr = PatternStr;
960  return false;
961  }
962 
963  if (MatchFullLinesHere) {
964  RegExStr += '^';
965  if (!Req.NoCanonicalizeWhiteSpace)
966  RegExStr += " *";
967  }
968 
969  // Paren value #0 is for the fully matched string. Any new parenthesized
970  // values add from there.
971  unsigned CurParen = 1;
972 
973  // Otherwise, there is at least one regex piece. Build up the regex pattern
974  // by escaping scary characters in fixed strings, building up one big regex.
975  while (!PatternStr.empty()) {
976  // RegEx matches.
977  if (PatternStr.startswith("{{")) {
978  // This is the start of a regex match. Scan for the }}.
979  size_t End = PatternStr.find("}}");
980  if (End == StringRef::npos) {
981  SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
983  "found start of regex string with no end '}}'");
984  return true;
985  }
986 
987  // Enclose {{}} patterns in parens just like [[]] even though we're not
988  // capturing the result for any purpose. This is required in case the
989  // expression contains an alternation like: CHECK: abc{{x|z}}def. We
990  // want this to turn into: "abc(x|z)def" not "abcx|zdef".
991  RegExStr += '(';
992  ++CurParen;
993 
994  if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM))
995  return true;
996  RegExStr += ')';
997 
998  PatternStr = PatternStr.substr(End + 2);
999  continue;
1000  }
1001 
1002  // String and numeric substitution blocks. Pattern substitution blocks come
1003  // in two forms: [[foo:.*]] and [[foo]]. The former matches .* (or some
1004  // other regex) and assigns it to the string variable 'foo'. The latter
1005  // substitutes foo's value. Numeric substitution blocks recognize the same
1006  // form as string ones, but start with a '#' sign after the double
1007  // brackets. They also accept a combined form which sets a numeric variable
1008  // to the evaluation of an expression. Both string and numeric variable
1009  // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be
1010  // valid, as this helps catch some common errors.
1011  if (PatternStr.startswith("[[")) {
1012  StringRef UnparsedPatternStr = PatternStr.substr(2);
1013  // Find the closing bracket pair ending the match. End is going to be an
1014  // offset relative to the beginning of the match string.
1015  size_t End = FindRegexVarEnd(UnparsedPatternStr, SM);
1016  StringRef MatchStr = UnparsedPatternStr.substr(0, End);
1017  bool IsNumBlock = MatchStr.consume_front("#");
1018 
1019  if (End == StringRef::npos) {
1020  SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
1022  "Invalid substitution block, no ]] found");
1023  return true;
1024  }
1025  // Strip the substitution block we are parsing. End points to the start
1026  // of the "]]" closing the expression so account for it in computing the
1027  // index of the first unparsed character.
1028  PatternStr = UnparsedPatternStr.substr(End + 2);
1029 
1030  bool IsDefinition = false;
1031  bool SubstNeeded = false;
1032  // Whether the substitution block is a legacy use of @LINE with string
1033  // substitution block syntax.
1034  bool IsLegacyLineExpr = false;
1035  StringRef DefName;
1036  StringRef SubstStr;
1037  std::string MatchRegexp;
1038  size_t SubstInsertIdx = RegExStr.size();
1039 
1040  // Parse string variable or legacy @LINE expression.
1041  if (!IsNumBlock) {
1042  size_t VarEndIdx = MatchStr.find(':');
1043  size_t SpacePos = MatchStr.substr(0, VarEndIdx).find_first_of(" \t");
1044  if (SpacePos != StringRef::npos) {
1045  SM.PrintMessage(SMLoc::getFromPointer(MatchStr.data() + SpacePos),
1046  SourceMgr::DK_Error, "unexpected whitespace");
1047  return true;
1048  }
1049 
1050  // Get the name (e.g. "foo") and verify it is well formed.
1051  StringRef OrigMatchStr = MatchStr;
1052  Expected<Pattern::VariableProperties> ParseVarResult =
1053  parseVariable(MatchStr, SM);
1054  if (!ParseVarResult) {
1055  logAllUnhandledErrors(ParseVarResult.takeError(), errs());
1056  return true;
1057  }
1058  StringRef Name = ParseVarResult->Name;
1059  bool IsPseudo = ParseVarResult->IsPseudo;
1060 
1061  IsDefinition = (VarEndIdx != StringRef::npos);
1062  SubstNeeded = !IsDefinition;
1063  if (IsDefinition) {
1064  if ((IsPseudo || !MatchStr.consume_front(":"))) {
1067  "invalid name in string variable definition");
1068  return true;
1069  }
1070 
1071  // Detect collisions between string and numeric variables when the
1072  // former is created later than the latter.
1073  if (Context->GlobalNumericVariableTable.find(Name) !=
1074  Context->GlobalNumericVariableTable.end()) {
1075  SM.PrintMessage(
1077  "numeric variable with name '" + Name + "' already exists");
1078  return true;
1079  }
1080  DefName = Name;
1081  MatchRegexp = MatchStr.str();
1082  } else {
1083  if (IsPseudo) {
1084  MatchStr = OrigMatchStr;
1085  IsLegacyLineExpr = IsNumBlock = true;
1086  } else {
1087  if (!MatchStr.empty()) {
1090  "invalid name in string variable use");
1091  return true;
1092  }
1093  SubstStr = Name;
1094  }
1095  }
1096  }
1097 
1098  // Parse numeric substitution block.
1099  std::unique_ptr<Expression> ExpressionPointer;
1100  Optional<NumericVariable *> DefinedNumericVariable;
1101  if (IsNumBlock) {
1103  parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
1104  IsLegacyLineExpr, LineNumber, Context,
1105  SM);
1106  if (!ParseResult) {
1107  logAllUnhandledErrors(ParseResult.takeError(), errs());
1108  return true;
1109  }
1110  ExpressionPointer = std::move(*ParseResult);
1111  SubstNeeded = ExpressionPointer->getAST() != nullptr;
1112  if (DefinedNumericVariable) {
1113  IsDefinition = true;
1114  DefName = (*DefinedNumericVariable)->getName();
1115  }
1116  if (SubstNeeded)
1117  SubstStr = MatchStr;
1118  else {
1119  ExpressionFormat Format = ExpressionPointer->getFormat();
1120  MatchRegexp = cantFail(Format.getWildcardRegex());
1121  }
1122  }
1123 
1124  // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]].
1125  if (IsDefinition) {
1126  RegExStr += '(';
1127  ++SubstInsertIdx;
1128 
1129  if (IsNumBlock) {
1130  NumericVariableMatch NumericVariableDefinition = {
1131  *DefinedNumericVariable, CurParen};
1132  NumericVariableDefs[DefName] = NumericVariableDefinition;
1133  // This store is done here rather than in match() to allow
1134  // parseNumericVariableUse() to get the pointer to the class instance
1135  // of the right variable definition corresponding to a given numeric
1136  // variable use.
1137  Context->GlobalNumericVariableTable[DefName] =
1138  *DefinedNumericVariable;
1139  } else {
1140  VariableDefs[DefName] = CurParen;
1141  // Mark string variable as defined to detect collisions between
1142  // string and numeric variables in parseNumericVariableUse() and
1143  // defineCmdlineVariables() when the latter is created later than the
1144  // former. We cannot reuse GlobalVariableTable for this by populating
1145  // it with an empty string since we would then lose the ability to
1146  // detect the use of an undefined variable in match().
1147  Context->DefinedVariableTable[DefName] = true;
1148  }
1149 
1150  ++CurParen;
1151  }
1152 
1153  if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM))
1154  return true;
1155 
1156  if (IsDefinition)
1157  RegExStr += ')';
1158 
1159  // Handle substitutions: [[foo]] and [[#<foo expr>]].
1160  if (SubstNeeded) {
1161  // Handle substitution of string variables that were defined earlier on
1162  // the same line by emitting a backreference. Expressions do not
1163  // support substituting a numeric variable defined on the same line.
1164  if (!IsNumBlock && VariableDefs.find(SubstStr) != VariableDefs.end()) {
1165  unsigned CaptureParenGroup = VariableDefs[SubstStr];
1166  if (CaptureParenGroup < 1 || CaptureParenGroup > 9) {
1167  SM.PrintMessage(SMLoc::getFromPointer(SubstStr.data()),
1169  "Can't back-reference more than 9 variables");
1170  return true;
1171  }
1172  AddBackrefToRegEx(CaptureParenGroup);
1173  } else {
1174  // Handle substitution of string variables ([[<var>]]) defined in
1175  // previous CHECK patterns, and substitution of expressions.
1177  IsNumBlock
1178  ? Context->makeNumericSubstitution(
1179  SubstStr, std::move(ExpressionPointer), SubstInsertIdx)
1180  : Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
1181  Substitutions.push_back(Substitution);
1182  }
1183  }
1184  }
1185 
1186  // Handle fixed string matches.
1187  // Find the end, which is the start of the next regex.
1188  size_t FixedMatchEnd = PatternStr.find("{{");
1189  FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
1190  RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
1191  PatternStr = PatternStr.substr(FixedMatchEnd);
1192  }
1193 
1194  if (MatchFullLinesHere) {
1195  if (!Req.NoCanonicalizeWhiteSpace)
1196  RegExStr += " *";
1197  RegExStr += '$';
1198  }
1199 
1200  return false;
1201 }
1202 
1203 bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
1204  Regex R(RS);
1205  std::string Error;
1206  if (!R.isValid(Error)) {
1208  "invalid regex: " + Error);
1209  return true;
1210  }
1211 
1212  RegExStr += RS.str();
1213  CurParen += R.getNumMatches();
1214  return false;
1215 }
1216 
1217 void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
1218  assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
1219  std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
1220  RegExStr += Backref;
1221 }
1222 
1224  const SourceMgr &SM) const {
1225  // If this is the EOF pattern, match it immediately.
1226  if (CheckTy == Check::CheckEOF)
1227  return MatchResult(Buffer.size(), 0, Error::success());
1228 
1229  // If this is a fixed string pattern, just match it now.
1230  if (!FixedStr.empty()) {
1231  size_t Pos =
1232  IgnoreCase ? Buffer.find_lower(FixedStr) : Buffer.find(FixedStr);
1233  if (Pos == StringRef::npos)
1234  return make_error<NotFoundError>();
1235  return MatchResult(Pos, /*MatchLen=*/FixedStr.size(), Error::success());
1236  }
1237 
1238  // Regex match.
1239 
1240  // If there are substitutions, we need to create a temporary string with the
1241  // actual value.
1242  StringRef RegExToMatch = RegExStr;
1243  std::string TmpStr;
1244  if (!Substitutions.empty()) {
1245  TmpStr = RegExStr;
1246  if (LineNumber)
1247  Context->LineVariable->setValue(ExpressionValue(*LineNumber));
1248 
1249  size_t InsertOffset = 0;
1250  // Substitute all string variables and expressions whose values are only
1251  // now known. Use of string variables defined on the same line are handled
1252  // by back-references.
1253  for (const auto &Substitution : Substitutions) {
1254  // Substitute and check for failure (e.g. use of undefined variable).
1256  if (!Value) {
1257  // Convert to an ErrorDiagnostic to get location information. This is
1258  // done here rather than printMatch/printNoMatch since now we know which
1259  // substitution block caused the overflow.
1260  Error Err =
1261  handleErrors(Value.takeError(), [&](const OverflowError &E) {
1262  return ErrorDiagnostic::get(SM, Substitution->getFromString(),
1263  "unable to substitute variable or "
1264  "numeric expression: overflow error");
1265  });
1266  return std::move(Err);
1267  }
1268 
1269  // Plop it into the regex at the adjusted offset.
1270  TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset,
1271  Value->begin(), Value->end());
1272  InsertOffset += Value->size();
1273  }
1274 
1275  // Match the newly constructed regex.
1276  RegExToMatch = TmpStr;
1277  }
1278 
1279  SmallVector<StringRef, 4> MatchInfo;
1280  unsigned int Flags = Regex::Newline;
1281  if (IgnoreCase)
1282  Flags |= Regex::IgnoreCase;
1283  if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo))
1284  return make_error<NotFoundError>();
1285 
1286  // Successful regex match.
1287  assert(!MatchInfo.empty() && "Didn't get any match");
1288  StringRef FullMatch = MatchInfo[0];
1289 
1290  // If this defines any string variables, remember their values.
1291  for (const auto &VariableDef : VariableDefs) {
1292  assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
1293  Context->GlobalVariableTable[VariableDef.first] =
1294  MatchInfo[VariableDef.second];
1295  }
1296 
1297  // Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after
1298  // the required preceding newline, which is consumed by the pattern in the
1299  // case of CHECK-EMPTY but not CHECK-NEXT.
1300  size_t MatchStartSkip = CheckTy == Check::CheckEmpty;
1301  Match TheMatch;
1302  TheMatch.Pos = FullMatch.data() - Buffer.data() + MatchStartSkip;
1303  TheMatch.Len = FullMatch.size() - MatchStartSkip;
1304 
1305  // If this defines any numeric variables, remember their values.
1306  for (const auto &NumericVariableDef : NumericVariableDefs) {
1307  const NumericVariableMatch &NumericVariableMatch =
1308  NumericVariableDef.getValue();
1309  unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
1310  assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
1311  NumericVariable *DefinedNumericVariable =
1312  NumericVariableMatch.DefinedNumericVariable;
1313 
1314  StringRef MatchedValue = MatchInfo[CaptureParenGroup];
1315  ExpressionFormat Format = DefinedNumericVariable->getImplicitFormat();
1317  Format.valueFromStringRepr(MatchedValue, SM);
1318  if (!Value)
1319  return MatchResult(TheMatch, Value.takeError());
1320  DefinedNumericVariable->setValue(*Value, MatchedValue);
1321  }
1322 
1323  return MatchResult(TheMatch, Error::success());
1324 }
1325 
1326 unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
1327  // Just compute the number of matching characters. For regular expressions, we
1328  // just compare against the regex itself and hope for the best.
1329  //
1330  // FIXME: One easy improvement here is have the regex lib generate a single
1331  // example regular expression which matches, and use that as the example
1332  // string.
1333  StringRef ExampleString(FixedStr);
1334  if (ExampleString.empty())
1335  ExampleString = RegExStr;
1336 
1337  // Only compare up to the first line in the buffer, or the string size.
1338  StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
1339  BufferPrefix = BufferPrefix.split('\n').first;
1340  return BufferPrefix.edit_distance(ExampleString);
1341 }
1342 
1343 void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
1344  SMRange Range,
1345  FileCheckDiag::MatchType MatchTy,
1346  std::vector<FileCheckDiag> *Diags) const {
1347  // Print what we know about substitutions.
1348  if (!Substitutions.empty()) {
1349  for (const auto &Substitution : Substitutions) {
1350  SmallString<256> Msg;
1351  raw_svector_ostream OS(Msg);
1352  Expected<std::string> MatchedValue = Substitution->getResult();
1353 
1354  // Substitution failed or is not known at match time, print the undefined
1355  // variables it uses.
1356  if (!MatchedValue) {
1357  bool UndefSeen = false;
1359  MatchedValue.takeError(), [](const NotFoundError &E) {},
1360  // Handled in printMatch and printNoMatch().
1361  [](const ErrorDiagnostic &E) {},
1362  // Handled in match().
1363  [](const OverflowError &E) {},
1364  [&](const UndefVarError &E) {
1365  if (!UndefSeen) {
1366  OS << "uses undefined variable(s):";
1367  UndefSeen = true;
1368  }
1369  OS << " ";
1370  E.log(OS);
1371  });
1372  if (!OS.tell())
1373  continue;
1374  } else {
1375  // Substitution succeeded. Print substituted value.
1376  OS << "with \"";
1377  OS.write_escaped(Substitution->getFromString()) << "\" equal to \"";
1378  OS.write_escaped(*MatchedValue) << "\"";
1379  }
1380 
1381  // We report only the start of the match/search range to suggest we are
1382  // reporting the substitutions as set at the start of the match/search.
1383  // Indicating a non-zero-length range might instead seem to imply that the
1384  // substitution matches or was captured from exactly that range.
1385  if (Diags)
1386  Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy,
1387  SMRange(Range.Start, Range.Start), OS.str());
1388  else
1389  SM.PrintMessage(Range.Start, SourceMgr::DK_Note, OS.str());
1390  }
1391  }
1392 }
1393 
1394 void Pattern::printVariableDefs(const SourceMgr &SM,
1395  FileCheckDiag::MatchType MatchTy,
1396  std::vector<FileCheckDiag> *Diags) const {
1397  if (VariableDefs.empty() && NumericVariableDefs.empty())
1398  return;
1399  // Build list of variable captures.
1400  struct VarCapture {
1401  StringRef Name;
1402  SMRange Range;
1403  };
1404  SmallVector<VarCapture, 2> VarCaptures;
1405  for (const auto &VariableDef : VariableDefs) {
1406  VarCapture VC;
1407  VC.Name = VariableDef.first;
1408  StringRef Value = Context->GlobalVariableTable[VC.Name];
1409  SMLoc Start = SMLoc::getFromPointer(Value.data());
1410  SMLoc End = SMLoc::getFromPointer(Value.data() + Value.size());
1411  VC.Range = SMRange(Start, End);
1412  VarCaptures.push_back(VC);
1413  }
1414  for (const auto &VariableDef : NumericVariableDefs) {
1415  VarCapture VC;
1416  VC.Name = VariableDef.getKey();
1417  Optional<StringRef> StrValue =
1418  VariableDef.getValue().DefinedNumericVariable->getStringValue();
1419  if (!StrValue)
1420  continue;
1421  SMLoc Start = SMLoc::getFromPointer(StrValue->data());
1422  SMLoc End = SMLoc::getFromPointer(StrValue->data() + StrValue->size());
1423  VC.Range = SMRange(Start, End);
1424  VarCaptures.push_back(VC);
1425  }
1426  // Sort variable captures by the order in which they matched the input.
1427  // Ranges shouldn't be overlapping, so we can just compare the start.
1428  llvm::sort(VarCaptures, [](const VarCapture &A, const VarCapture &B) {
1429  assert(A.Range.Start != B.Range.Start &&
1430  "unexpected overlapping variable captures");
1431  return A.Range.Start.getPointer() < B.Range.Start.getPointer();
1432  });
1433  // Create notes for the sorted captures.
1434  for (const VarCapture &VC : VarCaptures) {
1435  SmallString<256> Msg;
1436  raw_svector_ostream OS(Msg);
1437  OS << "captured var \"" << VC.Name << "\"";
1438  if (Diags)
1439  Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, VC.Range, OS.str());
1440  else
1441  SM.PrintMessage(VC.Range.Start, SourceMgr::DK_Note, OS.str(), VC.Range);
1442  }
1443 }
1444 
1445 static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
1446  const SourceMgr &SM, SMLoc Loc,
1447  Check::FileCheckType CheckTy,
1448  StringRef Buffer, size_t Pos, size_t Len,
1449  std::vector<FileCheckDiag> *Diags,
1450  bool AdjustPrevDiags = false) {
1451  SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos);
1452  SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len);
1453  SMRange Range(Start, End);
1454  if (Diags) {
1455  if (AdjustPrevDiags) {
1456  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
1457  for (auto I = Diags->rbegin(), E = Diags->rend();
1458  I != E && I->CheckLoc == CheckLoc; ++I)
1459  I->MatchTy = MatchTy;
1460  } else
1461  Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range);
1462  }
1463  return Range;
1464 }
1465 
1466 void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
1467  std::vector<FileCheckDiag> *Diags) const {
1468  // Attempt to find the closest/best fuzzy match. Usually an error happens
1469  // because some string in the output didn't exactly match. In these cases, we
1470  // would like to show the user a best guess at what "should have" matched, to
1471  // save them having to actually check the input manually.
1472  size_t NumLinesForward = 0;
1473  size_t Best = StringRef::npos;
1474  double BestQuality = 0;
1475 
1476  // Use an arbitrary 4k limit on how far we will search.
1477  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
1478  if (Buffer[i] == '\n')
1479  ++NumLinesForward;
1480 
1481  // Patterns have leading whitespace stripped, so skip whitespace when
1482  // looking for something which looks like a pattern.
1483  if (Buffer[i] == ' ' || Buffer[i] == '\t')
1484  continue;
1485 
1486  // Compute the "quality" of this match as an arbitrary combination of the
1487  // match distance and the number of lines skipped to get to this match.
1488  unsigned Distance = computeMatchDistance(Buffer.substr(i));
1489  double Quality = Distance + (NumLinesForward / 100.);
1490 
1491  if (Quality < BestQuality || Best == StringRef::npos) {
1492  Best = i;
1493  BestQuality = Quality;
1494  }
1495  }
1496 
1497  // Print the "possible intended match here" line if we found something
1498  // reasonable and not equal to what we showed in the "scanning from here"
1499  // line.
1500  if (Best && Best != StringRef::npos && BestQuality < 50) {
1501  SMRange MatchRange =
1502  ProcessMatchResult(FileCheckDiag::MatchFuzzy, SM, getLoc(),
1503  getCheckTy(), Buffer, Best, 0, Diags);
1504  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note,
1505  "possible intended match here");
1506 
1507  // FIXME: If we wanted to be really friendly we would show why the match
1508  // failed, as it can be hard to spot simple one character differences.
1509  }
1510 }
1511 
1514  auto VarIter = GlobalVariableTable.find(VarName);
1515  if (VarIter == GlobalVariableTable.end())
1516  return make_error<UndefVarError>(VarName);
1517 
1518  return VarIter->second;
1519 }
1520 
1521 template <class... Types>
1522 NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) {
1523  NumericVariables.push_back(std::make_unique<NumericVariable>(args...));
1524  return NumericVariables.back().get();
1525 }
1526 
1527 Substitution *
1528 FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
1529  size_t InsertIdx) {
1530  Substitutions.push_back(
1531  std::make_unique<StringSubstitution>(this, VarName, InsertIdx));
1532  return Substitutions.back().get();
1533 }
1534 
1535 Substitution *FileCheckPatternContext::makeNumericSubstitution(
1536  StringRef ExpressionStr, std::unique_ptr<Expression> Expression,
1537  size_t InsertIdx) {
1538  Substitutions.push_back(std::make_unique<NumericSubstitution>(
1539  this, ExpressionStr, std::move(Expression), InsertIdx));
1540  return Substitutions.back().get();
1541 }
1542 
1543 size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
1544  // Offset keeps track of the current offset within the input Str
1545  size_t Offset = 0;
1546  // [...] Nesting depth
1547  size_t BracketDepth = 0;
1548 
1549  while (!Str.empty()) {
1550  if (Str.startswith("]]") && BracketDepth == 0)
1551  return Offset;
1552  if (Str[0] == '\\') {
1553  // Backslash escapes the next char within regexes, so skip them both.
1554  Str = Str.substr(2);
1555  Offset += 2;
1556  } else {
1557  switch (Str[0]) {
1558  default:
1559  break;
1560  case '[':
1561  BracketDepth++;
1562  break;
1563  case ']':
1564  if (BracketDepth == 0) {
1567  "missing closing \"]\" for regex variable");
1568  exit(1);
1569  }
1570  BracketDepth--;
1571  break;
1572  }
1573  Str = Str.substr(1);
1574  Offset++;
1575  }
1576  }
1577 
1578  return StringRef::npos;
1579 }
1580 
1582  SmallVectorImpl<char> &OutputBuffer) {
1583  OutputBuffer.reserve(MB.getBufferSize());
1584 
1585  for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
1586  Ptr != End; ++Ptr) {
1587  // Eliminate trailing dosish \r.
1588  if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
1589  continue;
1590  }
1591 
1592  // If current char is not a horizontal whitespace or if horizontal
1593  // whitespace canonicalization is disabled, dump it to output as is.
1594  if (Req.NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) {
1595  OutputBuffer.push_back(*Ptr);
1596  continue;
1597  }
1598 
1599  // Otherwise, add one space and advance over neighboring space.
1600  OutputBuffer.push_back(' ');
1601  while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
1602  ++Ptr;
1603  }
1604 
1605  // Add a null byte and then return all but that byte.
1606  OutputBuffer.push_back('\0');
1607  return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
1608 }
1609 
1611  const Check::FileCheckType &CheckTy,
1612  SMLoc CheckLoc, MatchType MatchTy,
1613  SMRange InputRange, StringRef Note)
1614  : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy), Note(Note) {
1615  auto Start = SM.getLineAndColumn(InputRange.Start);
1616  auto End = SM.getLineAndColumn(InputRange.End);
1617  InputStartLine = Start.first;
1618  InputStartCol = Start.second;
1619  InputEndLine = End.first;
1620  InputEndCol = End.second;
1621 }
1622 
1623 static bool IsPartOfWord(char c) {
1624  return (isAlnum(c) || c == '-' || c == '_');
1625 }
1626 
1628  assert(Count > 0 && "zero and negative counts are not supported");
1629  assert((C == 1 || Kind == CheckPlain) &&
1630  "count supported only for plain CHECK directives");
1631  Count = C;
1632  return *this;
1633 }
1634 
1636  if (Modifiers.none())
1637  return "";
1638  std::string Ret;
1639  raw_string_ostream OS(Ret);
1640  OS << '{';
1641  if (isLiteralMatch())
1642  OS << "LITERAL";
1643  OS << '}';
1644  return OS.str();
1645 }
1646 
1648  // Append directive modifiers.
1649  auto WithModifiers = [this, Prefix](StringRef Str) -> std::string {
1650  return (Prefix + Str + getModifiersDescription()).str();
1651  };
1652 
1653  switch (Kind) {
1654  case Check::CheckNone:
1655  return "invalid";
1656  case Check::CheckPlain:
1657  if (Count > 1)
1658  return WithModifiers("-COUNT");
1659  return WithModifiers("");
1660  case Check::CheckNext:
1661  return WithModifiers("-NEXT");
1662  case Check::CheckSame:
1663  return WithModifiers("-SAME");
1664  case Check::CheckNot:
1665  return WithModifiers("-NOT");
1666  case Check::CheckDAG:
1667  return WithModifiers("-DAG");
1668  case Check::CheckLabel:
1669  return WithModifiers("-LABEL");
1670  case Check::CheckEmpty:
1671  return WithModifiers("-EMPTY");
1672  case Check::CheckComment:
1673  return std::string(Prefix);
1674  case Check::CheckEOF:
1675  return "implicit EOF";
1676  case Check::CheckBadNot:
1677  return "bad NOT";
1678  case Check::CheckBadCount:
1679  return "bad COUNT";
1680  }
1681  llvm_unreachable("unknown FileCheckType");
1682 }
1683 
1684 static std::pair<Check::FileCheckType, StringRef>
1685 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix) {
1686  if (Buffer.size() <= Prefix.size())
1687  return {Check::CheckNone, StringRef()};
1688 
1689  StringRef Rest = Buffer.drop_front(Prefix.size());
1690  // Check for comment.
1692  if (Rest.consume_front(":"))
1693  return {Check::CheckComment, Rest};
1694  // Ignore a comment prefix if it has a suffix like "-NOT".
1695  return {Check::CheckNone, StringRef()};
1696  }
1697 
1698  auto ConsumeModifiers = [&](Check::FileCheckType Ret)
1699  -> std::pair<Check::FileCheckType, StringRef> {
1700  if (Rest.consume_front(":"))
1701  return {Ret, Rest};
1702  if (!Rest.consume_front("{"))
1703  return {Check::CheckNone, StringRef()};
1704 
1705  // Parse the modifiers, speparated by commas.
1706  do {
1707  // Allow whitespace in modifiers list.
1708  Rest = Rest.ltrim();
1709  if (Rest.consume_front("LITERAL"))
1710  Ret.setLiteralMatch();
1711  else
1712  return {Check::CheckNone, Rest};
1713  // Allow whitespace in modifiers list.
1714  Rest = Rest.ltrim();
1715  } while (Rest.consume_front(","));
1716  if (!Rest.consume_front("}:"))
1717  return {Check::CheckNone, Rest};
1718  return {Ret, Rest};
1719  };
1720 
1721  // Verify that the prefix is followed by directive modifiers or a colon.
1722  if (Rest.consume_front(":"))
1723  return {Check::CheckPlain, Rest};
1724  if (Rest.front() == '{')
1725  return ConsumeModifiers(Check::CheckPlain);
1726 
1727  if (!Rest.consume_front("-"))
1728  return {Check::CheckNone, StringRef()};
1729 
1730  if (Rest.consume_front("COUNT-")) {
1731  int64_t Count;
1732  if (Rest.consumeInteger(10, Count))
1733  // Error happened in parsing integer.
1734  return {Check::CheckBadCount, Rest};
1735  if (Count <= 0 || Count > INT32_MAX)
1736  return {Check::CheckBadCount, Rest};
1737  if (Rest.front() != ':' && Rest.front() != '{')
1738  return {Check::CheckBadCount, Rest};
1739  return ConsumeModifiers(
1740  Check::FileCheckType(Check::CheckPlain).setCount(Count));
1741  }
1742 
1743  // You can't combine -NOT with another suffix.
1744  if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
1745  Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
1746  Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") ||
1747  Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:"))
1748  return {Check::CheckBadNot, Rest};
1749 
1750  if (Rest.consume_front("NEXT"))
1751  return ConsumeModifiers(Check::CheckNext);
1752 
1753  if (Rest.consume_front("SAME"))
1754  return ConsumeModifiers(Check::CheckSame);
1755 
1756  if (Rest.consume_front("NOT"))
1757  return ConsumeModifiers(Check::CheckNot);
1758 
1759  if (Rest.consume_front("DAG"))
1760  return ConsumeModifiers(Check::CheckDAG);
1761 
1762  if (Rest.consume_front("LABEL"))
1763  return ConsumeModifiers(Check::CheckLabel);
1764 
1765  if (Rest.consume_front("EMPTY"))
1766  return ConsumeModifiers(Check::CheckEmpty);
1767 
1768  return {Check::CheckNone, Rest};
1769 }
1770 
1771 // From the given position, find the next character after the word.
1772 static size_t SkipWord(StringRef Str, size_t Loc) {
1773  while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
1774  ++Loc;
1775  return Loc;
1776 }
1777 
1778 /// Searches the buffer for the first prefix in the prefix regular expression.
1779 ///
1780 /// This searches the buffer using the provided regular expression, however it
1781 /// enforces constraints beyond that:
1782 /// 1) The found prefix must not be a suffix of something that looks like
1783 /// a valid prefix.
1784 /// 2) The found prefix must be followed by a valid check type suffix using \c
1785 /// FindCheckType above.
1786 ///
1787 /// \returns a pair of StringRefs into the Buffer, which combines:
1788 /// - the first match of the regular expression to satisfy these two is
1789 /// returned,
1790 /// otherwise an empty StringRef is returned to indicate failure.
1791 /// - buffer rewound to the location right after parsed suffix, for parsing
1792 /// to continue from
1793 ///
1794 /// If this routine returns a valid prefix, it will also shrink \p Buffer to
1795 /// start at the beginning of the returned prefix, increment \p LineNumber for
1796 /// each new line consumed from \p Buffer, and set \p CheckTy to the type of
1797 /// check found by examining the suffix.
1798 ///
1799 /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
1800 /// is unspecified.
1801 static std::pair<StringRef, StringRef>
1802 FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE,
1803  StringRef &Buffer, unsigned &LineNumber,
1804  Check::FileCheckType &CheckTy) {
1805  SmallVector<StringRef, 2> Matches;
1806 
1807  while (!Buffer.empty()) {
1808  // Find the first (longest) match using the RE.
1809  if (!PrefixRE.match(Buffer, &Matches))
1810  // No match at all, bail.
1811  return {StringRef(), StringRef()};
1812 
1813  StringRef Prefix = Matches[0];
1814  Matches.clear();
1815 
1816  assert(Prefix.data() >= Buffer.data() &&
1817  Prefix.data() < Buffer.data() + Buffer.size() &&
1818  "Prefix doesn't start inside of buffer!");
1819  size_t Loc = Prefix.data() - Buffer.data();
1820  StringRef Skipped = Buffer.substr(0, Loc);
1821  Buffer = Buffer.drop_front(Loc);
1822  LineNumber += Skipped.count('\n');
1823 
1824  // Check that the matched prefix isn't a suffix of some other check-like
1825  // word.
1826  // FIXME: This is a very ad-hoc check. it would be better handled in some
1827  // other way. Among other things it seems hard to distinguish between
1828  // intentional and unintentional uses of this feature.
1829  if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
1830  // Now extract the type.
1831  StringRef AfterSuffix;
1832  std::tie(CheckTy, AfterSuffix) = FindCheckType(Req, Buffer, Prefix);
1833 
1834  // If we've found a valid check type for this prefix, we're done.
1835  if (CheckTy != Check::CheckNone)
1836  return {Prefix, AfterSuffix};
1837  }
1838 
1839  // If we didn't successfully find a prefix, we need to skip this invalid
1840  // prefix and continue scanning. We directly skip the prefix that was
1841  // matched and any additional parts of that check-like word.
1842  Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size()));
1843  }
1844 
1845  // We ran out of buffer while skipping partial matches so give up.
1846  return {StringRef(), StringRef()};
1847 }
1848 
1850  assert(!LineVariable && "@LINE pseudo numeric variable already created");
1851  StringRef LineName = "@LINE";
1852  LineVariable = makeNumericVariable(
1854  GlobalNumericVariableTable[LineName] = LineVariable;
1855 }
1856 
1858  : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()),
1859  CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {}
1860 
1861 FileCheck::~FileCheck() = default;
1862 
1864  SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
1865  std::pair<unsigned, unsigned> *ImpPatBufferIDRange) {
1866  if (ImpPatBufferIDRange)
1867  ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0;
1868 
1869  Error DefineError =
1870  PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM);
1871  if (DefineError) {
1872  logAllUnhandledErrors(std::move(DefineError), errs());
1873  return true;
1874  }
1875 
1876  PatternContext->createLineVariable();
1877 
1878  std::vector<Pattern> ImplicitNegativeChecks;
1879  for (StringRef PatternString : Req.ImplicitCheckNot) {
1880  // Create a buffer with fake command line content in order to display the
1881  // command line option responsible for the specific implicit CHECK-NOT.
1882  std::string Prefix = "-implicit-check-not='";
1883  std::string Suffix = "'";
1884  std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
1885  (Prefix + PatternString + Suffix).str(), "command line");
1886 
1887  StringRef PatternInBuffer =
1888  CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
1889  unsigned BufferID = SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
1890  if (ImpPatBufferIDRange) {
1891  if (ImpPatBufferIDRange->first == ImpPatBufferIDRange->second) {
1892  ImpPatBufferIDRange->first = BufferID;
1893  ImpPatBufferIDRange->second = BufferID + 1;
1894  } else {
1895  assert(BufferID == ImpPatBufferIDRange->second &&
1896  "expected consecutive source buffer IDs");
1897  ++ImpPatBufferIDRange->second;
1898  }
1899  }
1900 
1901  ImplicitNegativeChecks.push_back(
1902  Pattern(Check::CheckNot, PatternContext.get()));
1903  ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
1904  "IMPLICIT-CHECK", SM, Req);
1905  }
1906 
1907  std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
1908 
1909  // LineNumber keeps track of the line on which CheckPrefix instances are
1910  // found.
1911  unsigned LineNumber = 1;
1912 
1913  std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(),
1914  Req.CheckPrefixes.end());
1915  const size_t DistinctPrefixes = PrefixesNotFound.size();
1916  while (true) {
1917  Check::FileCheckType CheckTy;
1918 
1919  // See if a prefix occurs in the memory buffer.
1920  StringRef UsedPrefix;
1921  StringRef AfterSuffix;
1922  std::tie(UsedPrefix, AfterSuffix) =
1923  FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy);
1924  if (UsedPrefix.empty())
1925  break;
1926  if (CheckTy != Check::CheckComment)
1927  PrefixesNotFound.erase(UsedPrefix);
1928 
1929  assert(UsedPrefix.data() == Buffer.data() &&
1930  "Failed to move Buffer's start forward, or pointed prefix outside "
1931  "of the buffer!");
1932  assert(AfterSuffix.data() >= Buffer.data() &&
1933  AfterSuffix.data() < Buffer.data() + Buffer.size() &&
1934  "Parsing after suffix doesn't start inside of buffer!");
1935 
1936  // Location to use for error messages.
1937  const char *UsedPrefixStart = UsedPrefix.data();
1938 
1939  // Skip the buffer to the end of parsed suffix (or just prefix, if no good
1940  // suffix was processed).
1941  Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size())
1942  : AfterSuffix;
1943 
1944  // Complain about useful-looking but unsupported suffixes.
1945  if (CheckTy == Check::CheckBadNot) {
1947  "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
1948  return true;
1949  }
1950 
1951  // Complain about invalid count specification.
1952  if (CheckTy == Check::CheckBadCount) {
1954  "invalid count in -COUNT specification on prefix '" +
1955  UsedPrefix + "'");
1956  return true;
1957  }
1958 
1959  // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
1960  // leading whitespace.
1961  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
1962  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
1963 
1964  // Scan ahead to the end of line.
1965  size_t EOL = Buffer.find_first_of("\n\r");
1966 
1967  // Remember the location of the start of the pattern, for diagnostics.
1968  SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
1969 
1970  // Extract the pattern from the buffer.
1971  StringRef PatternBuffer = Buffer.substr(0, EOL);
1972  Buffer = Buffer.substr(EOL);
1973 
1974  // If this is a comment, we're done.
1975  if (CheckTy == Check::CheckComment)
1976  continue;
1977 
1978  // Parse the pattern.
1979  Pattern P(CheckTy, PatternContext.get(), LineNumber);
1980  if (P.parsePattern(PatternBuffer, UsedPrefix, SM, Req))
1981  return true;
1982 
1983  // Verify that CHECK-LABEL lines do not define or use variables
1984  if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
1985  SM.PrintMessage(
1986  SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
1987  "found '" + UsedPrefix + "-LABEL:'"
1988  " with variable definition or use");
1989  return true;
1990  }
1991 
1992  // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
1993  if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
1994  CheckTy == Check::CheckEmpty) &&
1995  CheckStrings->empty()) {
1996  StringRef Type = CheckTy == Check::CheckNext
1997  ? "NEXT"
1998  : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
1999  SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
2001  "found '" + UsedPrefix + "-" + Type +
2002  "' without previous '" + UsedPrefix + ": line");
2003  return true;
2004  }
2005 
2006  // Handle CHECK-DAG/-NOT.
2007  if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
2008  DagNotMatches.push_back(P);
2009  continue;
2010  }
2011 
2012  // Okay, add the string we captured to the output vector and move on.
2013  CheckStrings->emplace_back(P, UsedPrefix, PatternLoc);
2014  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2015  DagNotMatches = ImplicitNegativeChecks;
2016  }
2017 
2018  // When there are no used prefixes we report an error except in the case that
2019  // no prefix is specified explicitly but -implicit-check-not is specified.
2020  const bool NoPrefixesFound = PrefixesNotFound.size() == DistinctPrefixes;
2021  const bool SomePrefixesUnexpectedlyNotUsed =
2022  !Req.AllowUnusedPrefixes && !PrefixesNotFound.empty();
2023  if ((NoPrefixesFound || SomePrefixesUnexpectedlyNotUsed) &&
2024  (ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) {
2025  errs() << "error: no check strings found with prefix"
2026  << (PrefixesNotFound.size() > 1 ? "es " : " ");
2027  bool First = true;
2028  for (StringRef MissingPrefix : PrefixesNotFound) {
2029  if (!First)
2030  errs() << ", ";
2031  errs() << "\'" << MissingPrefix << ":'";
2032  First = false;
2033  }
2034  errs() << '\n';
2035  return true;
2036  }
2037 
2038  // Add an EOF pattern for any trailing --implicit-check-not/CHECK-DAG/-NOTs,
2039  // and use the first prefix as a filler for the error message.
2040  if (!DagNotMatches.empty()) {
2041  CheckStrings->emplace_back(
2042  Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
2043  *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
2044  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2045  }
2046 
2047  return false;
2048 }
2049 
2050 /// Returns either (1) \c ErrorSuccess if there was no error or (2)
2051 /// \c ErrorReported if an error was reported, such as an unexpected match.
2052 static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
2053  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2054  int MatchedCount, StringRef Buffer,
2055  Pattern::MatchResult MatchResult,
2056  const FileCheckRequest &Req,
2057  std::vector<FileCheckDiag> *Diags) {
2058  // Suppress some verbosity if there's no error.
2059  bool HasError = !ExpectedMatch || MatchResult.TheError;
2060  bool PrintDiag = true;
2061  if (!HasError) {
2062  if (!Req.Verbose)
2063  return ErrorReported::reportedOrSuccess(HasError);
2064  if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF)
2065  return ErrorReported::reportedOrSuccess(HasError);
2066  // Due to their verbosity, we don't print verbose diagnostics here if we're
2067  // gathering them for Diags to be rendered elsewhere, but we always print
2068  // other diagnostics.
2069  PrintDiag = !Diags;
2070  }
2071 
2072  // Add "found" diagnostic, substitutions, and variable definitions to Diags.
2073  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2076  SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2077  Buffer, MatchResult.TheMatch->Pos,
2078  MatchResult.TheMatch->Len, Diags);
2079  if (Diags) {
2080  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags);
2081  Pat.printVariableDefs(SM, MatchTy, Diags);
2082  }
2083  if (!PrintDiag) {
2084  assert(!HasError && "expected to report more diagnostics for error");
2085  return ErrorReported::reportedOrSuccess(HasError);
2086  }
2087 
2088  // Print the match.
2089  std::string Message = formatv("{0}: {1} string found in input",
2091  (ExpectedMatch ? "expected" : "excluded"))
2092  .str();
2093  if (Pat.getCount() > 1)
2094  Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2095  SM.PrintMessage(
2096  Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message);
2097  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here",
2098  {MatchRange});
2099 
2100  // Print additional information, which can be useful even if there are errors.
2101  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, nullptr);
2102  Pat.printVariableDefs(SM, MatchTy, nullptr);
2103 
2104  // Print errors and add them to Diags. We report these errors after the match
2105  // itself because we found them after the match. If we had found them before
2106  // the match, we'd be in printNoMatch.
2107  handleAllErrors(std::move(MatchResult.TheError),
2108  [&](const ErrorDiagnostic &E) {
2109  E.log(errs());
2110  if (Diags) {
2111  Diags->emplace_back(SM, Pat.getCheckTy(), Loc,
2112  FileCheckDiag::MatchFoundErrorNote,
2113  E.getRange(), E.getMessage().str());
2114  }
2115  });
2116  return ErrorReported::reportedOrSuccess(HasError);
2117 }
2118 
2119 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2120 /// \c ErrorReported if an error was reported, such as an expected match not
2121 /// found.
2122 static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM,
2123  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2124  int MatchedCount, StringRef Buffer, Error MatchError,
2125  bool VerboseVerbose,
2126  std::vector<FileCheckDiag> *Diags) {
2127  // Print any pattern errors, and record them to be added to Diags later.
2128  bool HasError = ExpectedMatch;
2129  bool HasPatternError = false;
2130  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2133  SmallVector<std::string, 4> ErrorMsgs;
2135  std::move(MatchError),
2136  [&](const ErrorDiagnostic &E) {
2137  HasError = HasPatternError = true;
2139  E.log(errs());
2140  if (Diags)
2141  ErrorMsgs.push_back(E.getMessage().str());
2142  },
2143  // UndefVarError is reported in printSubstitutions below.
2144  // FIXME: It probably should be handled as a pattern error and actually
2145  // change the exit status to 1, even if !ExpectedMatch. To do so, we
2146  // could stop calling printSubstitutions and actually report the error
2147  // here as we do ErrorDiagnostic above.
2148  [](const UndefVarError &E) {},
2149  // NotFoundError is why printNoMatch was invoked.
2150  [](const NotFoundError &E) {});
2151 
2152  // Suppress some verbosity if there's no error.
2153  bool PrintDiag = true;
2154  if (!HasError) {
2155  if (!VerboseVerbose)
2156  return ErrorReported::reportedOrSuccess(HasError);
2157  // Due to their verbosity, we don't print verbose diagnostics here if we're
2158  // gathering them for Diags to be rendered elsewhere, but we always print
2159  // other diagnostics.
2160  PrintDiag = !Diags;
2161  }
2162 
2163  // Add "not found" diagnostic, substitutions, and pattern errors to Diags.
2164  //
2165  // We handle Diags a little differently than the errors we print directly:
2166  // we add the "not found" diagnostic to Diags even if there are pattern
2167  // errors. The reason is that we need to attach pattern errors as notes
2168  // somewhere in the input, and the input search range from the "not found"
2169  // diagnostic is all we have to anchor them.
2170  SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2171  Buffer, 0, Buffer.size(), Diags);
2172  if (Diags) {
2173  SMRange NoteRange = SMRange(SearchRange.Start, SearchRange.Start);
2174  for (StringRef ErrorMsg : ErrorMsgs)
2175  Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, NoteRange,
2176  ErrorMsg);
2177  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, Diags);
2178  }
2179  if (!PrintDiag) {
2180  assert(!HasError && "expected to report more diagnostics for error");
2181  return ErrorReported::reportedOrSuccess(HasError);
2182  }
2183 
2184  // Print "not found" diagnostic, except that's implied if we already printed a
2185  // pattern error.
2186  if (!HasPatternError) {
2187  std::string Message = formatv("{0}: {1} string not found in input",
2189  (ExpectedMatch ? "expected" : "excluded"))
2190  .str();
2191  if (Pat.getCount() > 1)
2192  Message +=
2193  formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2194  SM.PrintMessage(Loc,
2195  ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark,
2196  Message);
2197  SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note,
2198  "scanning from here");
2199  }
2200 
2201  // Print additional information, which can be useful even after a pattern
2202  // error.
2203  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, nullptr);
2204  if (ExpectedMatch)
2205  Pat.printFuzzyMatch(SM, Buffer, Diags);
2206  return ErrorReported::reportedOrSuccess(HasError);
2207 }
2208 
2209 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2210 /// \c ErrorReported if an error was reported.
2211 static Error reportMatchResult(bool ExpectedMatch, const SourceMgr &SM,
2212  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2213  int MatchedCount, StringRef Buffer,
2214  Pattern::MatchResult MatchResult,
2215  const FileCheckRequest &Req,
2216  std::vector<FileCheckDiag> *Diags) {
2217  if (MatchResult.TheMatch)
2218  return printMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2219  std::move(MatchResult), Req, Diags);
2220  return printNoMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2221  std::move(MatchResult.TheError), Req.VerboseVerbose,
2222  Diags);
2223 }
2224 
2225 /// Counts the number of newlines in the specified range.
2226 static unsigned CountNumNewlinesBetween(StringRef Range,
2227  const char *&FirstNewLine) {
2228  unsigned NumNewLines = 0;
2229  while (1) {
2230  // Scan for newline.
2231  Range = Range.substr(Range.find_first_of("\n\r"));
2232  if (Range.empty())
2233  return NumNewLines;
2234 
2235  ++NumNewLines;
2236 
2237  // Handle \n\r and \r\n as a single newline.
2238  if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
2239  (Range[0] != Range[1]))
2240  Range = Range.substr(1);
2241  Range = Range.substr(1);
2242 
2243  if (NumNewLines == 1)
2244  FirstNewLine = Range.begin();
2245  }
2246 }
2247 
2248 size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
2249  bool IsLabelScanMode, size_t &MatchLen,
2250  FileCheckRequest &Req,
2251  std::vector<FileCheckDiag> *Diags) const {
2252  size_t LastPos = 0;
2253  std::vector<const Pattern *> NotStrings;
2254 
2255  // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
2256  // bounds; we have not processed variable definitions within the bounded block
2257  // yet so cannot handle any final CHECK-DAG yet; this is handled when going
2258  // over the block again (including the last CHECK-LABEL) in normal mode.
2259  if (!IsLabelScanMode) {
2260  // Match "dag strings" (with mixed "not strings" if any).
2261  LastPos = CheckDag(SM, Buffer, NotStrings, Req, Diags);
2262  if (LastPos == StringRef::npos)
2263  return StringRef::npos;
2264  }
2265 
2266  // Match itself from the last position after matching CHECK-DAG.
2267  size_t LastMatchEnd = LastPos;
2268  size_t FirstMatchPos = 0;
2269  // Go match the pattern Count times. Majority of patterns only match with
2270  // count 1 though.
2271  assert(Pat.getCount() != 0 && "pattern count can not be zero");
2272  for (int i = 1; i <= Pat.getCount(); i++) {
2273  StringRef MatchBuffer = Buffer.substr(LastMatchEnd);
2274  // get a match at current start point
2275  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2276 
2277  // report
2278  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix, Loc,
2279  Pat, i, MatchBuffer,
2280  std::move(MatchResult), Req, Diags)) {
2281  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2282  return StringRef::npos;
2283  }
2284 
2285  size_t MatchPos = MatchResult.TheMatch->Pos;
2286  if (i == 1)
2287  FirstMatchPos = LastPos + MatchPos;
2288 
2289  // move start point after the match
2290  LastMatchEnd += MatchPos + MatchResult.TheMatch->Len;
2291  }
2292  // Full match len counts from first match pos.
2293  MatchLen = LastMatchEnd - FirstMatchPos;
2294 
2295  // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
2296  // or CHECK-NOT
2297  if (!IsLabelScanMode) {
2298  size_t MatchPos = FirstMatchPos - LastPos;
2299  StringRef MatchBuffer = Buffer.substr(LastPos);
2300  StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
2301 
2302  // If this check is a "CHECK-NEXT", verify that the previous match was on
2303  // the previous line (i.e. that there is one newline between them).
2304  if (CheckNext(SM, SkippedRegion)) {
2305  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2306  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2307  Diags, Req.Verbose);
2308  return StringRef::npos;
2309  }
2310 
2311  // If this check is a "CHECK-SAME", verify that the previous match was on
2312  // the same line (i.e. that there is no newline between them).
2313  if (CheckSame(SM, SkippedRegion)) {
2314  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2315  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2316  Diags, Req.Verbose);
2317  return StringRef::npos;
2318  }
2319 
2320  // If this match had "not strings", verify that they don't exist in the
2321  // skipped region.
2322  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2323  return StringRef::npos;
2324  }
2325 
2326  return FirstMatchPos;
2327 }
2328 
2329 bool FileCheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
2330  if (Pat.getCheckTy() != Check::CheckNext &&
2332  return false;
2333 
2334  Twine CheckName =
2335  Prefix +
2336  Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT");
2337 
2338  // Count the number of newlines between the previous match and this one.
2339  const char *FirstNewLine = nullptr;
2340  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2341 
2342  if (NumNewLines == 0) {
2344  CheckName + ": is on the same line as previous match");
2346  "'next' match was here");
2348  "previous match ended here");
2349  return true;
2350  }
2351 
2352  if (NumNewLines != 1) {
2354  CheckName +
2355  ": is not on the line after the previous match");
2357  "'next' match was here");
2359  "previous match ended here");
2361  "non-matching line after previous match is here");
2362  return true;
2363  }
2364 
2365  return false;
2366 }
2367 
2368 bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
2369  if (Pat.getCheckTy() != Check::CheckSame)
2370  return false;
2371 
2372  // Count the number of newlines between the previous match and this one.
2373  const char *FirstNewLine = nullptr;
2374  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2375 
2376  if (NumNewLines != 0) {
2378  Prefix +
2379  "-SAME: is not on the same line as the previous match");
2381  "'next' match was here");
2383  "previous match ended here");
2384  return true;
2385  }
2386 
2387  return false;
2388 }
2389 
2390 bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
2391  const std::vector<const Pattern *> &NotStrings,
2392  const FileCheckRequest &Req,
2393  std::vector<FileCheckDiag> *Diags) const {
2394  bool DirectiveFail = false;
2395  for (const Pattern *Pat : NotStrings) {
2396  assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
2397  Pattern::MatchResult MatchResult = Pat->match(Buffer, SM);
2398  if (Error Err = reportMatchResult(/*ExpectedMatch=*/false, SM, Prefix,
2399  Pat->getLoc(), *Pat, 1, Buffer,
2400  std::move(MatchResult), Req, Diags)) {
2401  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2402  DirectiveFail = true;
2403  continue;
2404  }
2405  }
2406  return DirectiveFail;
2407 }
2408 
2409 size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
2410  std::vector<const Pattern *> &NotStrings,
2411  const FileCheckRequest &Req,
2412  std::vector<FileCheckDiag> *Diags) const {
2413  if (DagNotStrings.empty())
2414  return 0;
2415 
2416  // The start of the search range.
2417  size_t StartPos = 0;
2418 
2419  struct MatchRange {
2420  size_t Pos;
2421  size_t End;
2422  };
2423  // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match
2424  // ranges are erased from this list once they are no longer in the search
2425  // range.
2426  std::list<MatchRange> MatchRanges;
2427 
2428  // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG
2429  // group, so we don't use a range-based for loop here.
2430  for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end();
2431  PatItr != PatEnd; ++PatItr) {
2432  const Pattern &Pat = *PatItr;
2434  Pat.getCheckTy() == Check::CheckNot) &&
2435  "Invalid CHECK-DAG or CHECK-NOT!");
2436 
2437  if (Pat.getCheckTy() == Check::CheckNot) {
2438  NotStrings.push_back(&Pat);
2439  continue;
2440  }
2441 
2442  assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
2443 
2444  // CHECK-DAG always matches from the start.
2445  size_t MatchLen = 0, MatchPos = StartPos;
2446 
2447  // Search for a match that doesn't overlap a previous match in this
2448  // CHECK-DAG group.
2449  for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) {
2450  StringRef MatchBuffer = Buffer.substr(MatchPos);
2451  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2452  // With a group of CHECK-DAGs, a single mismatching means the match on
2453  // that group of CHECK-DAGs fails immediately.
2454  if (MatchResult.TheError || Req.VerboseVerbose) {
2455  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix,
2456  Pat.getLoc(), Pat, 1, MatchBuffer,
2457  std::move(MatchResult), Req, Diags)) {
2458  cantFail(
2459  handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2460  return StringRef::npos;
2461  }
2462  }
2463  MatchLen = MatchResult.TheMatch->Len;
2464  // Re-calc it as the offset relative to the start of the original
2465  // string.
2466  MatchPos += MatchResult.TheMatch->Pos;
2467  MatchRange M{MatchPos, MatchPos + MatchLen};
2468  if (Req.AllowDeprecatedDagOverlap) {
2469  // We don't need to track all matches in this mode, so we just maintain
2470  // one match range that encompasses the current CHECK-DAG group's
2471  // matches.
2472  if (MatchRanges.empty())
2473  MatchRanges.insert(MatchRanges.end(), M);
2474  else {
2475  auto Block = MatchRanges.begin();
2476  Block->Pos = std::min(Block->Pos, M.Pos);
2477  Block->End = std::max(Block->End, M.End);
2478  }
2479  break;
2480  }
2481  // Iterate previous matches until overlapping match or insertion point.
2482  bool Overlap = false;
2483  for (; MI != ME; ++MI) {
2484  if (M.Pos < MI->End) {
2485  // !Overlap => New match has no overlap and is before this old match.
2486  // Overlap => New match overlaps this old match.
2487  Overlap = MI->Pos < M.End;
2488  break;
2489  }
2490  }
2491  if (!Overlap) {
2492  // Insert non-overlapping match into list.
2493  MatchRanges.insert(MI, M);
2494  break;
2495  }
2496  if (Req.VerboseVerbose) {
2497  // Due to their verbosity, we don't print verbose diagnostics here if
2498  // we're gathering them for a different rendering, but we always print
2499  // other diagnostics.
2500  if (!Diags) {
2501  SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos);
2502  SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End);
2503  SMRange OldRange(OldStart, OldEnd);
2504  SM.PrintMessage(OldStart, SourceMgr::DK_Note,
2505  "match discarded, overlaps earlier DAG match here",
2506  {OldRange});
2507  } else {
2508  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
2509  for (auto I = Diags->rbegin(), E = Diags->rend();
2510  I != E && I->CheckLoc == CheckLoc; ++I)
2512  }
2513  }
2514  MatchPos = MI->End;
2515  }
2516  if (!Req.VerboseVerbose)
2517  cantFail(printMatch(
2518  /*ExpectedMatch=*/true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer,
2519  Pattern::MatchResult(MatchPos, MatchLen, Error::success()), Req,
2520  Diags));
2521 
2522  // Handle the end of a CHECK-DAG group.
2523  if (std::next(PatItr) == PatEnd ||
2524  std::next(PatItr)->getCheckTy() == Check::CheckNot) {
2525  if (!NotStrings.empty()) {
2526  // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to
2527  // CHECK-DAG, verify that there are no 'not' strings occurred in that
2528  // region.
2529  StringRef SkippedRegion =
2530  Buffer.slice(StartPos, MatchRanges.begin()->Pos);
2531  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2532  return StringRef::npos;
2533  // Clear "not strings".
2534  NotStrings.clear();
2535  }
2536  // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the
2537  // end of this CHECK-DAG group's match range.
2538  StartPos = MatchRanges.rbegin()->End;
2539  // Don't waste time checking for (impossible) overlaps before that.
2540  MatchRanges.clear();
2541  }
2542  }
2543 
2544  return StartPos;
2545 }
2546 
2547 static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes,
2548  ArrayRef<StringRef> SuppliedPrefixes) {
2549  for (StringRef Prefix : SuppliedPrefixes) {
2550  if (Prefix.empty()) {
2551  errs() << "error: supplied " << Kind << " prefix must not be the empty "
2552  << "string\n";
2553  return false;
2554  }
2555  static const Regex Validator("^[a-zA-Z0-9_-]*$");
2556  if (!Validator.match(Prefix)) {
2557  errs() << "error: supplied " << Kind << " prefix must start with a "
2558  << "letter and contain only alphanumeric characters, hyphens, and "
2559  << "underscores: '" << Prefix << "'\n";
2560  return false;
2561  }
2562  if (!UniquePrefixes.insert(Prefix).second) {
2563  errs() << "error: supplied " << Kind << " prefix must be unique among "
2564  << "check and comment prefixes: '" << Prefix << "'\n";
2565  return false;
2566  }
2567  }
2568  return true;
2569 }
2570 
2571 static const char *DefaultCheckPrefixes[] = {"CHECK"};
2572 static const char *DefaultCommentPrefixes[] = {"COM", "RUN"};
2573 
2575  StringSet<> UniquePrefixes;
2576  // Add default prefixes to catch user-supplied duplicates of them below.
2577  if (Req.CheckPrefixes.empty()) {
2578  for (const char *Prefix : DefaultCheckPrefixes)
2579  UniquePrefixes.insert(Prefix);
2580  }
2581  if (Req.CommentPrefixes.empty()) {
2582  for (const char *Prefix : DefaultCommentPrefixes)
2583  UniquePrefixes.insert(Prefix);
2584  }
2585  // Do not validate the default prefixes, or diagnostics about duplicates might
2586  // incorrectly indicate that they were supplied by the user.
2587  if (!ValidatePrefixes("check", UniquePrefixes, Req.CheckPrefixes))
2588  return false;
2589  if (!ValidatePrefixes("comment", UniquePrefixes, Req.CommentPrefixes))
2590  return false;
2591  return true;
2592 }
2593 
2595  if (Req.CheckPrefixes.empty()) {
2596  for (const char *Prefix : DefaultCheckPrefixes)
2597  Req.CheckPrefixes.push_back(Prefix);
2598  Req.IsDefaultCheckPrefix = true;
2599  }
2600  if (Req.CommentPrefixes.empty()) {
2601  for (const char *Prefix : DefaultCommentPrefixes)
2602  Req.CommentPrefixes.push_back(Prefix);
2603  }
2604 
2605  // We already validated the contents of CheckPrefixes and CommentPrefixes so
2606  // just concatenate them as alternatives.
2607  SmallString<32> PrefixRegexStr;
2608  for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) {
2609  if (I != 0)
2610  PrefixRegexStr.push_back('|');
2611  PrefixRegexStr.append(Req.CheckPrefixes[I]);
2612  }
2613  for (StringRef Prefix : Req.CommentPrefixes) {
2614  PrefixRegexStr.push_back('|');
2615  PrefixRegexStr.append(Prefix);
2616  }
2617 
2618  return Regex(PrefixRegexStr);
2619 }
2620 
2622  ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM) {
2623  assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() &&
2624  "Overriding defined variable with command-line variable definitions");
2625 
2626  if (CmdlineDefines.empty())
2627  return Error::success();
2628 
2629  // Create a string representing the vector of command-line definitions. Each
2630  // definition is on its own line and prefixed with a definition number to
2631  // clarify which definition a given diagnostic corresponds to.
2632  unsigned I = 0;
2633  Error Errs = Error::success();
2634  std::string CmdlineDefsDiag;
2635  SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices;
2636  for (StringRef CmdlineDef : CmdlineDefines) {
2637  std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str();
2638  size_t EqIdx = CmdlineDef.find('=');
2639  if (EqIdx == StringRef::npos) {
2640  CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0));
2641  continue;
2642  }
2643  // Numeric variable definition.
2644  if (CmdlineDef[0] == '#') {
2645  // Append a copy of the command-line definition adapted to use the same
2646  // format as in the input file to be able to reuse
2647  // parseNumericSubstitutionBlock.
2648  CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str();
2649  std::string SubstitutionStr = std::string(CmdlineDef);
2650  SubstitutionStr[EqIdx] = ':';
2651  CmdlineDefsIndices.push_back(
2652  std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size()));
2653  CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str();
2654  } else {
2655  CmdlineDefsDiag += DefPrefix;
2656  CmdlineDefsIndices.push_back(
2657  std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size()));
2658  CmdlineDefsDiag += (CmdlineDef + "\n").str();
2659  }
2660  }
2661 
2662  // Create a buffer with fake command line content in order to display
2663  // parsing diagnostic with location information and point to the
2664  // global definition with invalid syntax.
2665  std::unique_ptr<MemoryBuffer> CmdLineDefsDiagBuffer =
2666  MemoryBuffer::getMemBufferCopy(CmdlineDefsDiag, "Global defines");
2667  StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer();
2668  SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc());
2669 
2670  for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) {
2671  StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first,
2672  CmdlineDefIndices.second);
2673  if (CmdlineDef.empty()) {
2674  Errs = joinErrors(
2675  std::move(Errs),
2676  ErrorDiagnostic::get(SM, CmdlineDef,
2677  "missing equal sign in global definition"));
2678  continue;
2679  }
2680 
2681  // Numeric variable definition.
2682  if (CmdlineDef[0] == '#') {
2683  // Now parse the definition both to check that the syntax is correct and
2684  // to create the necessary class instance.
2685  StringRef CmdlineDefExpr = CmdlineDef.substr(1);
2686  Optional<NumericVariable *> DefinedNumericVariable;
2687  Expected<std::unique_ptr<Expression>> ExpressionResult =
2689  CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM);
2690  if (!ExpressionResult) {
2691  Errs = joinErrors(std::move(Errs), ExpressionResult.takeError());
2692  continue;
2693  }
2694  std::unique_ptr<Expression> Expression = std::move(*ExpressionResult);
2695  // Now evaluate the expression whose value this variable should be set
2696  // to, since the expression of a command-line variable definition should
2697  // only use variables defined earlier on the command-line. If not, this
2698  // is an error and we report it.
2700  if (!Value) {
2701  Errs = joinErrors(std::move(Errs), Value.takeError());
2702  continue;
2703  }
2704 
2705  assert(DefinedNumericVariable && "No variable defined");
2706  (*DefinedNumericVariable)->setValue(*Value);
2707 
2708  // Record this variable definition.
2709  GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] =
2710  *DefinedNumericVariable;
2711  } else {
2712  // String variable definition.
2713  std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
2714  StringRef CmdlineName = CmdlineNameVal.first;
2715  StringRef OrigCmdlineName = CmdlineName;
2716  Expected<Pattern::VariableProperties> ParseVarResult =
2717  Pattern::parseVariable(CmdlineName, SM);
2718  if (!ParseVarResult) {
2719  Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
2720  continue;
2721  }
2722  // Check that CmdlineName does not denote a pseudo variable is only
2723  // composed of the parsed numeric variable. This catches cases like
2724  // "FOO+2" in a "FOO+2=10" definition.
2725  if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
2726  Errs = joinErrors(std::move(Errs),
2728  SM, OrigCmdlineName,
2729  "invalid name in string variable definition '" +
2730  OrigCmdlineName + "'"));
2731  continue;
2732  }
2733  StringRef Name = ParseVarResult->Name;
2734 
2735  // Detect collisions between string and numeric variables when the former
2736  // is created later than the latter.
2737  if (GlobalNumericVariableTable.find(Name) !=
2738  GlobalNumericVariableTable.end()) {
2739  Errs = joinErrors(std::move(Errs),
2741  "numeric variable with name '" +
2742  Name + "' already exists"));
2743  continue;
2744  }
2745  GlobalVariableTable.insert(CmdlineNameVal);
2746  // Mark the string variable as defined to detect collisions between
2747  // string and numeric variables in defineCmdlineVariables when the latter
2748  // is created later than the former. We cannot reuse GlobalVariableTable
2749  // for this by populating it with an empty string since we would then
2750  // lose the ability to detect the use of an undefined variable in
2751  // match().
2752  DefinedVariableTable[Name] = true;
2753  }
2754  }
2755 
2756  return Errs;
2757 }
2758 
2760  SmallVector<StringRef, 16> LocalPatternVars, LocalNumericVars;
2761  for (const StringMapEntry<StringRef> &Var : GlobalVariableTable)
2762  if (Var.first()[0] != '$')
2763  LocalPatternVars.push_back(Var.first());
2764 
2765  // Numeric substitution reads the value of a variable directly, not via
2766  // GlobalNumericVariableTable. Therefore, we clear local variables by
2767  // clearing their value which will lead to a numeric substitution failure. We
2768  // also mark the variable for removal from GlobalNumericVariableTable since
2769  // this is what defineCmdlineVariables checks to decide that no global
2770  // variable has been defined.
2771  for (const auto &Var : GlobalNumericVariableTable)
2772  if (Var.first()[0] != '$') {
2773  Var.getValue()->clearValue();
2774  LocalNumericVars.push_back(Var.first());
2775  }
2776 
2777  for (const auto &Var : LocalPatternVars)
2778  GlobalVariableTable.erase(Var);
2779  for (const auto &Var : LocalNumericVars)
2780  GlobalNumericVariableTable.erase(Var);
2781 }
2782 
2783 bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
2784  std::vector<FileCheckDiag> *Diags) {
2785  bool ChecksFailed = false;
2786 
2787  unsigned i = 0, j = 0, e = CheckStrings->size();
2788  while (true) {
2789  StringRef CheckRegion;
2790  if (j == e) {
2791  CheckRegion = Buffer;
2792  } else {
2793  const FileCheckString &CheckLabelStr = (*CheckStrings)[j];
2794  if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
2795  ++j;
2796  continue;
2797  }
2798 
2799  // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
2800  size_t MatchLabelLen = 0;
2801  size_t MatchLabelPos =
2802  CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, Req, Diags);
2803  if (MatchLabelPos == StringRef::npos)
2804  // Immediately bail if CHECK-LABEL fails, nothing else we can do.
2805  return false;
2806 
2807  CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
2808  Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
2809  ++j;
2810  }
2811 
2812  // Do not clear the first region as it's the one before the first
2813  // CHECK-LABEL and it would clear variables defined on the command-line
2814  // before they get used.
2815  if (i != 0 && Req.EnableVarScope)
2816  PatternContext->clearLocalVars();
2817 
2818  for (; i != j; ++i) {
2819  const FileCheckString &CheckStr = (*CheckStrings)[i];
2820 
2821  // Check each string within the scanned region, including a second check
2822  // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
2823  size_t MatchLen = 0;
2824  size_t MatchPos =
2825  CheckStr.Check(SM, CheckRegion, false, MatchLen, Req, Diags);
2826 
2827  if (MatchPos == StringRef::npos) {
2828  ChecksFailed = true;
2829  i = j;
2830  break;
2831  }
2832 
2833  CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
2834  }
2835 
2836  if (j == e)
2837  break;
2838  }
2839 
2840  // Success if no checks failed.
2841  return !ChecksFailed;
2842 }
FileCheck.h
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
llvm::FileCheckDiag::MatchNoneAndExcluded
@ MatchNoneAndExcluded
Indicates no match for an excluded pattern.
Definition: FileCheck.h:144
llvm::ExpressionValue::ExpressionValue
ExpressionValue(T Val)
Definition: FileCheckImpl.h:128
i
i
Definition: README.txt:29
llvm::EngineKind::Kind
Kind
Definition: ExecutionEngine.h:524
llvm::StringRef::back
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:171
llvm::ExpressionValue
Class representing a numeric value.
Definition: FileCheckImpl.h:121
llvm::SMRange::Start
SMLoc Start
Definition: SMLoc.h:50
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:289
llvm::ExpressionValue::isNegative
bool isNegative() const
Returns true if value is signed and negative, false otherwise.
Definition: FileCheckImpl.h:139
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm::ExpressionFormat::Kind::Unsigned
@ Unsigned
Value is an unsigned integer and should be printed as a decimal number.
llvm
Definition: AllocatorList.h:23
llvm::StringSubstitution::getResult
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:429
llvm::FileCheckRequest::AllowDeprecatedDagOverlap
bool AllowDeprecatedDagOverlap
Definition: FileCheck.h:39
llvm::FileCheckString::Pat
Pattern Pat
The pattern to match.
Definition: FileCheckImpl.h:869
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:906
llvm::Operator
This is a utility class that provides an abstraction for the common functionality between Instruction...
Definition: Operator.h:30
llvm::ExpressionFormat::Kind::Signed
@ Signed
Value is a signed integer and should be printed as a decimal number.
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
llvm::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMapEntry.h:98
llvm::StringRef::count
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:490
llvm::StringRef::rtrim
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:837
llvm::FileCheckRequest::GlobalDefines
std::vector< StringRef > GlobalDefines
Definition: FileCheck.h:32
llvm::OverflowError
Class to represent an overflow error that might result when manipulating a value.
Definition: FileCheckImpl.h:109
llvm::FileCheckRequest::NoCanonicalizeWhiteSpace
bool NoCanonicalizeWhiteSpace
Definition: FileCheck.h:30
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
llvm::FileCheckRequest::IsDefaultCheckPrefix
bool IsDefaultCheckPrefix
Definition: FileCheck.h:37
llvm::FileCheckString::CheckNext
bool CheckNext(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is a single line in the given Buffer.
Note
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles Note
Definition: README.txt:239
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
llvm::SMRange::End
SMLoc End
Definition: SMLoc.h:50
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:614
llvm::FileCheckRequest::Verbose
bool Verbose
Definition: FileCheck.h:40
llvm::Check::CheckSame
@ CheckSame
Definition: FileCheck.h:50
llvm::NumericVariable::setValue
void setValue(ExpressionValue NewValue, Optional< StringRef > NewStrValue=None)
Sets value of this numeric variable to NewValue, and sets the input buffer string from which it was p...
Definition: FileCheckImpl.h:309
llvm::Check::CheckLabel
@ CheckLabel
Definition: FileCheck.h:53
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:59
llvm::StringRef::find
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:318
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::FileCheck::~FileCheck
~FileCheck()
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:332
llvm::FileCheckString::Loc
SMLoc Loc
The location in the match file that the check string was specified.
Definition: FileCheckImpl.h:875
llvm::StringRef::ltrim
LLVM_NODISCARD StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:823
popFront
static char popFront(StringRef &S)
Definition: FileCheck.cpp:469
llvm::StringRef::consume_front
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:683
llvm::tgtok::VarName
@ VarName
Definition: TGLexer.h:71
getAsSigned
static int64_t getAsSigned(uint64_t UnsignedValue)
Definition: FileCheck.cpp:160
llvm::Check::FileCheckType::setCount
FileCheckType & setCount(int C)
llvm::StringRef::find_lower
LLVM_NODISCARD size_t find_lower(char C, size_t From=0) const
Search for the first character C in the string, ignoring case.
Definition: StringRef.cpp:58
llvm::UndefVarError::ID
static char ID
Definition: FileCheckImpl.h:220
llvm::Pattern::parsePattern
bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM, const FileCheckRequest &Req)
Parses the pattern in PatternStr and initializes this Pattern instance accordingly.
Definition: FileCheck.cpp:916
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
llvm::NumericVariableUse::eval
Expected< ExpressionValue > eval() const override
Definition: FileCheck.cpp:365
llvm::FileCheckDiag::FileCheckDiag
FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy, SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange, StringRef Note="")
llvm::Pattern::MatchResult
Definition: FileCheckImpl.h:739
llvm::Optional< int64_t >
llvm::FileCheck::checkInput
bool checkInput(SourceMgr &SM, StringRef Buffer, std::vector< FileCheckDiag > *Diags=nullptr)
Checks the input to FileCheck provided in the Buffer against the expected strings read from the check...
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::FileCheckPatternContext::clearLocalVars
void clearLocalVars()
Undefines local variables (variables whose name does not start with a '$' sign), i....
llvm::SourceMgr::DK_Note
@ DK_Note
Definition: SourceMgr.h:37
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:33
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
llvm::DiagnosticPredicateTy::Match
@ Match
llvm::StringRef::slice
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:713
llvm::FileCheckPatternContext::getPatternVarValue
Expected< StringRef > getPatternVarValue(StringRef VarName)
llvm::Pattern::match
MatchResult match(StringRef Buffer, const SourceMgr &SM) const
Matches the pattern string against the input buffer Buffer.
llvm::Regex::match
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Definition: Regex.cpp:86
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1006
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
llvm::operator/
Align operator/(Align Lhs, uint64_t Divisor)
Definition: Alignment.h:337
llvm::NumericVariable::getImplicitFormat
ExpressionFormat getImplicitFormat() const
Definition: FileCheckImpl.h:294
llvm::SourceMgr::DK_Remark
@ DK_Remark
Definition: SourceMgr.h:36
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::ExpressionValue::getAbsolute
ExpressionValue getAbsolute() const
Definition: FileCheck.cpp:188
llvm::StringRef::substr
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:612
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:205
llvm::Pattern::printSubstitutions
void printSubstitutions(const SourceMgr &SM, StringRef Buffer, SMRange MatchRange, FileCheckDiag::MatchType MatchTy, std::vector< FileCheckDiag > *Diags) const
Prints the value of successful substitutions or the name of the undefined string or numeric variables...
llvm::FileCheck::buildCheckPrefixRegex
Regex buildCheckPrefixRegex()
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:872
llvm::ErrorReported
An error that has already been reported.
Definition: FileCheckImpl.h:595
llvm::checkedSub
std::enable_if_t< std::is_signed< T >::value, llvm::Optional< T > > checkedSub(T LHS, T RHS)
Subtract two signed integers LHS and RHS.
Definition: CheckedArithmetic.h:57
llvm::AArch64CC::VC
@ VC
Definition: AArch64BaseInfo.h:243
llvm::BinaryOperation::eval
Expected< ExpressionValue > eval() const override
Evaluates the value of the binary operation represented by this AST, using EvalBinop on the result of...
Definition: FileCheck.cpp:373
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
llvm::ExpressionFormat
Type representing the format an expression value should be textualized into for matching.
Definition: FileCheckImpl.h:39
CheckedArithmetic.h
llvm::StringRef::take_front
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:621
llvm::MemoryBuffer::getBufferEnd
const char * getBufferEnd() const
Definition: MemoryBuffer.h:66
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::ErrorDiagnostic
Class to represent an error holding a diagnostic with location information used when printing it.
Definition: FileCheckImpl.h:537
llvm::StringRef::split
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:730
llvm::FileCheck::ValidateCheckPrefixes
bool ValidateCheckPrefixes()
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition: MemoryBuffer.h:67
SpaceChars
constexpr StringLiteral SpaceChars
Definition: FileCheck.cpp:466
llvm::FileCheckRequest::CheckPrefixes
std::vector< StringRef > CheckPrefixes
Definition: FileCheck.h:28
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::Expression::getAST
ExpressionAST * getAST() const
Definition: FileCheckImpl.h:254
llvm::NotFoundError
Definition: FileCheckImpl.h:571
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
Twine.h
llvm::NumericSubstitution::getResult
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:418
llvm::Substitution::FromStr
StringRef FromStr
The string that needs to be substituted for something else.
Definition: FileCheckImpl.h:401
llvm::FileCheckDiag::MatchFoundAndExpected
@ MatchFoundAndExpected
Indicates a good match for an expected pattern.
Definition: FileCheck.h:129
llvm::ExpressionFormat::getMatchingString
Expected< std::string > getMatchingString(ExpressionValue Value) const
Definition: FileCheck.cpp:80
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
llvm::Pattern::getCheckTy
Check::FileCheckType getCheckTy() const
Definition: FileCheckImpl.h:773
llvm::Check::CheckNot
@ CheckNot
Definition: FileCheck.h:51
llvm::UndefVarError
Class to represent an undefined variable error, which quotes that variable's name when printed.
Definition: FileCheckImpl.h:215
llvm::ExpressionValue::getSignedValue
Expected< int64_t > getSignedValue() const
Definition: FileCheck.cpp:170
llvm::operator-
APInt operator-(APInt)
Definition: APInt.h:2113
llvm::FileCheckPatternContext
Class holding the Pattern global state, shared by all patterns: tables holding values of variables an...
Definition: FileCheckImpl.h:460
llvm::OverflowError::ID
static char ID
Definition: FileCheckImpl.h:111
llvm::Pattern::parseVariable
static Expected< VariableProperties > parseVariable(StringRef &Str, const SourceMgr &SM)
Parses the string at the start of Str for a variable name.
Definition: FileCheck.cpp:440
llvm::FileCheckString::Check
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".
llvm::ErrorReported::reportedOrSuccess
static Error reportedOrSuccess(bool HasErrorReported)
Definition: FileCheckImpl.h:608
llvm::FileCheckDiag::MatchFoundButWrongLine
@ MatchFoundButWrongLine
Indicates a match for an expected pattern, but the match is on the wrong line.
Definition: FileCheck.h:134
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
FormatVariadic.h
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:248
llvm::None
const NoneType None
Definition: None.h:23
llvm::Check::FileCheckType::getDescription
std::string getDescription(StringRef Prefix) const
llvm::FileCheckString::CheckNot
bool CheckNot(const SourceMgr &SM, StringRef Buffer, const std::vector< const Pattern * > &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Verifies that none of the strings in NotStrings are found in the given Buffer.
llvm::SmallString< 256 >
FileCheckImpl.h
llvm::FileCheckString::Prefix
StringRef Prefix
Which prefix name this check matched.
Definition: FileCheckImpl.h:872
llvm::NumericVariable::getValue
Optional< ExpressionValue > getValue() const
Definition: FileCheckImpl.h:297
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:67
llvm::StringRef::trim
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:851
llvm::FileCheckDiag::MatchType
MatchType
What type of match result does this diagnostic describe?
Definition: FileCheck.h:127
llvm::ExpressionAST::eval
virtual Expected< ExpressionValue > eval() const =0
Evaluates and.
llvm::Check::FileCheckType
Definition: FileCheck.h:76
llvm::FileCheck::readCheckFile
bool readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, std::pair< unsigned, unsigned > *ImpPatBufferIDRange=nullptr)
Reads the check file from Buffer and records the expected strings it contains.
llvm::FileCheckString
A check that we found in the input file.
Definition: FileCheckImpl.h:867
llvm::Check::CheckNext
@ CheckNext
Definition: FileCheck.h:49
llvm::FileCheckDiag::MatchFoundButExcluded
@ MatchFoundButExcluded
Indicates a match for an excluded pattern.
Definition: FileCheck.h:131
llvm::Substitution
Class representing a substitution to perform in the RegExStr string.
Definition: FileCheckImpl.h:389
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:133
llvm::NotFoundError::ID
static char ID
Definition: FileCheckImpl.h:573
llvm::SourceMgr::PrintMessage
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:341
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::StringRef::front
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:164
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:429
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1570
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::ExpressionFormat::Kind::NoFormat
@ NoFormat
Denote absence of format.
llvm::StringRef::find_first_not_of
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:244
llvm::Check::CheckBadCount
@ CheckBadCount
Marks when parsing found a -COUNT directive with invalid count value.
Definition: FileCheck.h:65
llvm::operator+
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2118
llvm::Pattern::MatchResult::TheError
Error TheError
Definition: FileCheckImpl.h:741
llvm::StringRef::drop_back
LLVM_NODISCARD StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Definition: StringRef.h:662
llvm::FileCheck::FileCheck
FileCheck(FileCheckRequest Req)
llvm::Check::CheckBadNot
@ CheckBadNot
Marks when parsing found a -NOT check combined with another CHECK suffix.
Definition: FileCheck.h:62
llvm::FileCheckDiag::MatchNoneForInvalidPattern
@ MatchNoneForInvalidPattern
Indicates no match due to an expected or excluded pattern that has proven to be invalid at match time...
Definition: FileCheck.h:153
llvm::Expression
Class representing an expression and its matching format.
Definition: FileCheckImpl.h:238
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:22
llvm::FileCheckString::CheckSame
bool CheckSame(const SourceMgr &SM, StringRef Buffer) const
Verifies that there is no newline in the given Buffer.
llvm::operator*
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2160
llvm::FileCheckRequest::MatchFullLines
bool MatchFullLines
Definition: FileCheck.h:35
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:33
llvm::FileCheck::CanonicalizeFile
StringRef CanonicalizeFile(MemoryBuffer &MB, SmallVectorImpl< char > &OutputBuffer)
Canonicalizes whitespaces in the file.
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::Pattern::parseNumericSubstitutionBlock
static Expected< std::unique_ptr< Expression > > parseNumericSubstitutionBlock(StringRef Expr, Optional< NumericVariable * > &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:767
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:708
llvm::ErrorReported::ID
static char ID
Definition: FileCheckImpl.h:597
llvm::SourceMgr
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition: SourceMgr.h:31
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::FileCheckDiag::MatchFuzzy
@ MatchFuzzy
Indicates a fuzzy match that serves as a suggestion for the next intended match for an expected patte...
Definition: FileCheck.h:156
llvm::Regex::IgnoreCase
@ IgnoreCase
Compile for matching that ignores upper/lower case distinctions.
Definition: Regex.h:33
llvm::StringRef::consumeInteger
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:545
llvm::ExpressionValue::getUnsignedValue
Expected< uint64_t > getUnsignedValue() const
Definition: FileCheck.cpp:181
llvm::FileCheckDiag::MatchNoneButExpected
@ MatchNoneButExpected
Indicates no match for an expected pattern, but this might follow good matches when multiple matches ...
Definition: FileCheck.h:148
llvm::Regex::Newline
@ Newline
Compile for newline-sensitive matching.
Definition: Regex.h:39
llvm::logAllUnhandledErrors
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:61
llvm::tgtok::StrVal
@ StrVal
Definition: TGLexer.h:71
StringSet.h
j
return j(j<< 16)
llvm::Pattern::printFuzzyMatch
void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, std::vector< FileCheckDiag > *Diags) const
llvm::FileCheckRequest::EnableVarScope
bool EnableVarScope
Definition: FileCheck.h:38
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
llvm::Check::CheckDAG
@ CheckDAG
Definition: FileCheck.h:52
llvm::Pattern::getCount
int getCount() const
Definition: FileCheckImpl.h:775
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1202
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:65
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::StringRef::drop_front
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:654
llvm::Check::CheckEmpty
@ CheckEmpty
Definition: FileCheck.h:54
llvm::ExpressionFormat::getWildcardRegex
Expected< std::string > getWildcardRegex() const
Definition: FileCheck.cpp:47
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::ErrorDiagnostic::ID
static char ID
Definition: FileCheckImpl.h:543
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1446
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::Substitution::getResult
virtual Expected< std::string > getResult() const =0
llvm::ExpressionFormat::valueFromStringRepr
Expected< ExpressionValue > valueFromStringRepr(StringRef StrVal, const SourceMgr &SM) const
Definition: FileCheck.cpp:128
llvm::SourceMgr::DK_Error
@ DK_Error
Definition: SourceMgr.h:34
llvm::Check::FileCheckType::getModifiersDescription
std::string getModifiersDescription() const
llvm::SourceMgr::AddNewSourceBuffer
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition: SourceMgr.h:141
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::ErrorDiagnostic::get
static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg, SMRange Range=None)
Definition: FileCheckImpl.h:558
llvm::FileCheckDiag::MatchFoundButDiscarded
@ MatchFoundButDiscarded
Indicates a discarded match for an expected pattern.
Definition: FileCheck.h:136
llvm::FileCheckRequest::CommentPrefixes
std::vector< StringRef > CommentPrefixes
Definition: FileCheck.h:29
llvm::FileCheckRequest::IgnoreCase
bool IgnoreCase
Definition: FileCheck.h:36
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:557
llvm::Pattern
Definition: FileCheckImpl.h:615
llvm::Substitution::getIndex
size_t getIndex() const
Definition: FileCheckImpl.h:417
llvm::FileCheckRequest
Contains info about various FileCheck options.
Definition: FileCheck.h:27
llvm::FileCheckRequest::VerboseVerbose
bool VerboseVerbose
Definition: FileCheck.h:41
exit
declare void exit(i32) noreturn nounwind This compiles into
Definition: README.txt:1072
llvm::SMRange
Represents a range in source code.
Definition: SMLoc.h:48
llvm::Check::CheckPlain
@ CheckPlain
Definition: FileCheck.h:48
llvm::FileCheckPatternContext::defineCmdlineVariables
Error defineCmdlineVariables(ArrayRef< StringRef > CmdlineDefines, SourceMgr &SM)
Defines string and numeric variables from definitions given on the command line, passed as a vector o...
llvm::Pattern::isValidVarNameStart
static bool isValidVarNameStart(char C)
Definition: FileCheck.cpp:437
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
llvm::Pattern::printVariableDefs
void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy, std::vector< FileCheckDiag > *Diags) const
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:647
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:152
llvm::SmallVectorImpl< char >
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::BinaryOperation::getImplicitFormat
Expected< ExpressionFormat > getImplicitFormat(const SourceMgr &SM) const override
Definition: FileCheck.cpp:392
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
llvm::Pattern::getLoc
SMLoc getLoc() const
Definition: FileCheckImpl.h:690
llvm::NumericVariable::getDefLineNumber
Optional< size_t > getDefLineNumber() const
Definition: FileCheckImpl.h:324
llvm::NumericVariable
Class representing a numeric variable and its associated current value.
Definition: FileCheckImpl.h:260
llvm::Check::CheckNone
@ CheckNone
Definition: FileCheck.h:47
llvm::ExpressionAST::getExpressionStr
StringRef getExpressionStr() const
Definition: FileCheckImpl.h:182
llvm::Substitution::Context
FileCheckPatternContext * Context
Pointer to a class instance holding, among other things, the table with the values of live string var...
Definition: FileCheckImpl.h:397
llvm::StringRef::edit_distance
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:95
llvm::StringRef::find_first_of
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:413
llvm::SourceMgr::getLineAndColumn
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:180
llvm::ExpressionFormat::toString
StringRef toString() const
Definition: FileCheck.cpp:31
llvm::Check::FileCheckType::isLiteralMatch
bool isLiteralMatch() const
Definition: FileCheck.h:93
llvm::FileCheckString::CheckDag
size_t CheckDag(const SourceMgr &SM, StringRef Buffer, std::vector< const Pattern * > &NotStrings, const FileCheckRequest &Req, std::vector< FileCheckDiag > *Diags) const
Matches "dag strings" and their mixed "not strings".
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::Regex
Definition: Regex.h:28
llvm::FileCheckRequest::ImplicitCheckNot
std::vector< StringRef > ImplicitCheckNot
Definition: FileCheck.h:31
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
llvm::MemoryBuffer::getMemBufferCopy
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.
Definition: MemoryBuffer.cpp:135
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:624
llvm::Substitution::getFromString
StringRef getFromString() const
Definition: FileCheckImpl.h:414
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:131
llvm::pdb::PDB_SymType::Block
@ Block
llvm::FileCheckPatternContext::createLineVariable
void createLineVariable()
Create @LINE pseudo variable.
llvm::FileCheckRequest::AllowUnusedPrefixes
bool AllowUnusedPrefixes
Definition: FileCheck.h:34
llvm::ExpressionFormat::Kind::HexLower
@ HexLower
Value should be printed as a lowercase hex number.
llvm::handleAllErrors
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:929
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::Check::CheckEOF
@ CheckEOF
Indicates the pattern only matches the end of file.
Definition: FileCheck.h:59
llvm::Check::CheckComment
@ CheckComment
Definition: FileCheck.h:55
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:280
llvm::Pattern::MatchResult::TheMatch
Optional< Match > TheMatch
Definition: FileCheckImpl.h:740
llvm::Pattern::VariableProperties
Parsing information about a variable.
Definition: FileCheckImpl.h:700
llvm::ExpressionFormat::Kind::HexUpper
@ HexUpper
Value should be printed as an uppercase hex number.
llvm::AbsoluteDifference
std::enable_if_t< std::is_unsigned< T >::value, T > AbsoluteDifference(T X, T Y)
Subtract two unsigned integers, X and Y, of type T and return the absolute value of the result.
Definition: MathExtras.h:794
llvm::FileCheckString::DagNotStrings
std::vector< Pattern > DagNotStrings
All of the strings that are disallowed from occurring between this match string and the previous one ...
Definition: FileCheckImpl.h:879
llvm::remarks::Format
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25
llvm::Regex::escape
static std::string escape(StringRef String)
Turn String into a regex by escaping its special characters.
Definition: Regex.cpp:219