LLVM  15.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 
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;
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 printNoMatch() 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 ||
958  (!PatternStr.contains("{{") && !PatternStr.contains("[[")))) {
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. If there are extra '['s
1011  // before the "[[", treat them literally.
1012  if (PatternStr.startswith("[[") && !PatternStr.startswith("[[[")) {
1013  StringRef UnparsedPatternStr = PatternStr.substr(2);
1014  // Find the closing bracket pair ending the match. End is going to be an
1015  // offset relative to the beginning of the match string.
1016  size_t End = FindRegexVarEnd(UnparsedPatternStr, SM);
1017  StringRef MatchStr = UnparsedPatternStr.substr(0, End);
1018  bool IsNumBlock = MatchStr.consume_front("#");
1019 
1020  if (End == StringRef::npos) {
1021  SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
1023  "Invalid substitution block, no ]] found");
1024  return true;
1025  }
1026  // Strip the substitution block we are parsing. End points to the start
1027  // of the "]]" closing the expression so account for it in computing the
1028  // index of the first unparsed character.
1029  PatternStr = UnparsedPatternStr.substr(End + 2);
1030 
1031  bool IsDefinition = false;
1032  bool SubstNeeded = false;
1033  // Whether the substitution block is a legacy use of @LINE with string
1034  // substitution block syntax.
1035  bool IsLegacyLineExpr = false;
1036  StringRef DefName;
1037  StringRef SubstStr;
1038  StringRef MatchRegexp;
1039  std::string WildcardRegexp;
1040  size_t SubstInsertIdx = RegExStr.size();
1041 
1042  // Parse string variable or legacy @LINE expression.
1043  if (!IsNumBlock) {
1044  size_t VarEndIdx = MatchStr.find(':');
1045  size_t SpacePos = MatchStr.substr(0, VarEndIdx).find_first_of(" \t");
1046  if (SpacePos != StringRef::npos) {
1047  SM.PrintMessage(SMLoc::getFromPointer(MatchStr.data() + SpacePos),
1048  SourceMgr::DK_Error, "unexpected whitespace");
1049  return true;
1050  }
1051 
1052  // Get the name (e.g. "foo") and verify it is well formed.
1053  StringRef OrigMatchStr = MatchStr;
1054  Expected<Pattern::VariableProperties> ParseVarResult =
1055  parseVariable(MatchStr, SM);
1056  if (!ParseVarResult) {
1057  logAllUnhandledErrors(ParseVarResult.takeError(), errs());
1058  return true;
1059  }
1060  StringRef Name = ParseVarResult->Name;
1061  bool IsPseudo = ParseVarResult->IsPseudo;
1062 
1063  IsDefinition = (VarEndIdx != StringRef::npos);
1064  SubstNeeded = !IsDefinition;
1065  if (IsDefinition) {
1066  if ((IsPseudo || !MatchStr.consume_front(":"))) {
1069  "invalid name in string variable definition");
1070  return true;
1071  }
1072 
1073  // Detect collisions between string and numeric variables when the
1074  // former is created later than the latter.
1075  if (Context->GlobalNumericVariableTable.find(Name) !=
1076  Context->GlobalNumericVariableTable.end()) {
1077  SM.PrintMessage(
1079  "numeric variable with name '" + Name + "' already exists");
1080  return true;
1081  }
1082  DefName = Name;
1083  MatchRegexp = MatchStr;
1084  } else {
1085  if (IsPseudo) {
1086  MatchStr = OrigMatchStr;
1087  IsLegacyLineExpr = IsNumBlock = true;
1088  } else {
1089  if (!MatchStr.empty()) {
1092  "invalid name in string variable use");
1093  return true;
1094  }
1095  SubstStr = Name;
1096  }
1097  }
1098  }
1099 
1100  // Parse numeric substitution block.
1101  std::unique_ptr<Expression> ExpressionPointer;
1102  Optional<NumericVariable *> DefinedNumericVariable;
1103  if (IsNumBlock) {
1105  parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
1106  IsLegacyLineExpr, LineNumber, Context,
1107  SM);
1108  if (!ParseResult) {
1109  logAllUnhandledErrors(ParseResult.takeError(), errs());
1110  return true;
1111  }
1112  ExpressionPointer = std::move(*ParseResult);
1113  SubstNeeded = ExpressionPointer->getAST() != nullptr;
1114  if (DefinedNumericVariable) {
1115  IsDefinition = true;
1116  DefName = (*DefinedNumericVariable)->getName();
1117  }
1118  if (SubstNeeded)
1119  SubstStr = MatchStr;
1120  else {
1121  ExpressionFormat Format = ExpressionPointer->getFormat();
1122  WildcardRegexp = cantFail(Format.getWildcardRegex());
1123  MatchRegexp = WildcardRegexp;
1124  }
1125  }
1126 
1127  // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]].
1128  if (IsDefinition) {
1129  RegExStr += '(';
1130  ++SubstInsertIdx;
1131 
1132  if (IsNumBlock) {
1133  NumericVariableMatch NumericVariableDefinition = {
1134  *DefinedNumericVariable, CurParen};
1135  NumericVariableDefs[DefName] = NumericVariableDefinition;
1136  // This store is done here rather than in match() to allow
1137  // parseNumericVariableUse() to get the pointer to the class instance
1138  // of the right variable definition corresponding to a given numeric
1139  // variable use.
1140  Context->GlobalNumericVariableTable[DefName] =
1141  *DefinedNumericVariable;
1142  } else {
1143  VariableDefs[DefName] = CurParen;
1144  // Mark string variable as defined to detect collisions between
1145  // string and numeric variables in parseNumericVariableUse() and
1146  // defineCmdlineVariables() when the latter is created later than the
1147  // former. We cannot reuse GlobalVariableTable for this by populating
1148  // it with an empty string since we would then lose the ability to
1149  // detect the use of an undefined variable in match().
1150  Context->DefinedVariableTable[DefName] = true;
1151  }
1152 
1153  ++CurParen;
1154  }
1155 
1156  if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM))
1157  return true;
1158 
1159  if (IsDefinition)
1160  RegExStr += ')';
1161 
1162  // Handle substitutions: [[foo]] and [[#<foo expr>]].
1163  if (SubstNeeded) {
1164  // Handle substitution of string variables that were defined earlier on
1165  // the same line by emitting a backreference. Expressions do not
1166  // support substituting a numeric variable defined on the same line.
1167  if (!IsNumBlock && VariableDefs.find(SubstStr) != VariableDefs.end()) {
1168  unsigned CaptureParenGroup = VariableDefs[SubstStr];
1169  if (CaptureParenGroup < 1 || CaptureParenGroup > 9) {
1170  SM.PrintMessage(SMLoc::getFromPointer(SubstStr.data()),
1172  "Can't back-reference more than 9 variables");
1173  return true;
1174  }
1175  AddBackrefToRegEx(CaptureParenGroup);
1176  } else {
1177  // Handle substitution of string variables ([[<var>]]) defined in
1178  // previous CHECK patterns, and substitution of expressions.
1180  IsNumBlock
1181  ? Context->makeNumericSubstitution(
1182  SubstStr, std::move(ExpressionPointer), SubstInsertIdx)
1183  : Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
1184  Substitutions.push_back(Substitution);
1185  }
1186  }
1187 
1188  continue;
1189  }
1190 
1191  // Handle fixed string matches.
1192  // Find the end, which is the start of the next regex.
1193  size_t FixedMatchEnd =
1194  std::min(PatternStr.find("{{", 1), PatternStr.find("[[", 1));
1195  RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
1196  PatternStr = PatternStr.substr(FixedMatchEnd);
1197  }
1198 
1199  if (MatchFullLinesHere) {
1200  if (!Req.NoCanonicalizeWhiteSpace)
1201  RegExStr += " *";
1202  RegExStr += '$';
1203  }
1204 
1205  return false;
1206 }
1207 
1208 bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
1209  Regex R(RS);
1210  std::string Error;
1211  if (!R.isValid(Error)) {
1213  "invalid regex: " + Error);
1214  return true;
1215  }
1216 
1217  RegExStr += RS.str();
1218  CurParen += R.getNumMatches();
1219  return false;
1220 }
1221 
1222 void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
1223  assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
1224  std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
1225  RegExStr += Backref;
1226 }
1227 
1229  const SourceMgr &SM) const {
1230  // If this is the EOF pattern, match it immediately.
1231  if (CheckTy == Check::CheckEOF)
1232  return MatchResult(Buffer.size(), 0, Error::success());
1233 
1234  // If this is a fixed string pattern, just match it now.
1235  if (!FixedStr.empty()) {
1236  size_t Pos =
1237  IgnoreCase ? Buffer.find_insensitive(FixedStr) : Buffer.find(FixedStr);
1238  if (Pos == StringRef::npos)
1239  return make_error<NotFoundError>();
1240  return MatchResult(Pos, /*MatchLen=*/FixedStr.size(), Error::success());
1241  }
1242 
1243  // Regex match.
1244 
1245  // If there are substitutions, we need to create a temporary string with the
1246  // actual value.
1247  StringRef RegExToMatch = RegExStr;
1248  std::string TmpStr;
1249  if (!Substitutions.empty()) {
1250  TmpStr = RegExStr;
1251  if (LineNumber)
1252  Context->LineVariable->setValue(ExpressionValue(*LineNumber));
1253 
1254  size_t InsertOffset = 0;
1255  // Substitute all string variables and expressions whose values are only
1256  // now known. Use of string variables defined on the same line are handled
1257  // by back-references.
1258  Error Errs = Error::success();
1259  for (const auto &Substitution : Substitutions) {
1260  // Substitute and check for failure (e.g. use of undefined variable).
1262  if (!Value) {
1263  // Convert to an ErrorDiagnostic to get location information. This is
1264  // done here rather than printMatch/printNoMatch since now we know which
1265  // substitution block caused the overflow.
1266  Errs = joinErrors(std::move(Errs),
1267  handleErrors(
1268  Value.takeError(),
1269  [&](const OverflowError &E) {
1270  return ErrorDiagnostic::get(
1271  SM, Substitution->getFromString(),
1272  "unable to substitute variable or "
1273  "numeric expression: overflow error");
1274  },
1275  [&SM](const UndefVarError &E) {
1276  return ErrorDiagnostic::get(SM, E.getVarName(),
1277  E.message());
1278  }));
1279  continue;
1280  }
1281 
1282  // Plop it into the regex at the adjusted offset.
1283  TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset,
1284  Value->begin(), Value->end());
1285  InsertOffset += Value->size();
1286  }
1287  if (Errs)
1288  return std::move(Errs);
1289 
1290  // Match the newly constructed regex.
1291  RegExToMatch = TmpStr;
1292  }
1293 
1294  SmallVector<StringRef, 4> MatchInfo;
1295  unsigned int Flags = Regex::Newline;
1296  if (IgnoreCase)
1297  Flags |= Regex::IgnoreCase;
1298  if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo))
1299  return make_error<NotFoundError>();
1300 
1301  // Successful regex match.
1302  assert(!MatchInfo.empty() && "Didn't get any match");
1303  StringRef FullMatch = MatchInfo[0];
1304 
1305  // If this defines any string variables, remember their values.
1306  for (const auto &VariableDef : VariableDefs) {
1307  assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
1308  Context->GlobalVariableTable[VariableDef.first] =
1309  MatchInfo[VariableDef.second];
1310  }
1311 
1312  // Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after
1313  // the required preceding newline, which is consumed by the pattern in the
1314  // case of CHECK-EMPTY but not CHECK-NEXT.
1315  size_t MatchStartSkip = CheckTy == Check::CheckEmpty;
1316  Match TheMatch;
1317  TheMatch.Pos = FullMatch.data() - Buffer.data() + MatchStartSkip;
1318  TheMatch.Len = FullMatch.size() - MatchStartSkip;
1319 
1320  // If this defines any numeric variables, remember their values.
1321  for (const auto &NumericVariableDef : NumericVariableDefs) {
1322  const NumericVariableMatch &NumericVariableMatch =
1323  NumericVariableDef.getValue();
1324  unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
1325  assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
1326  NumericVariable *DefinedNumericVariable =
1327  NumericVariableMatch.DefinedNumericVariable;
1328 
1329  StringRef MatchedValue = MatchInfo[CaptureParenGroup];
1330  ExpressionFormat Format = DefinedNumericVariable->getImplicitFormat();
1332  Format.valueFromStringRepr(MatchedValue, SM);
1333  if (!Value)
1334  return MatchResult(TheMatch, Value.takeError());
1335  DefinedNumericVariable->setValue(*Value, MatchedValue);
1336  }
1337 
1338  return MatchResult(TheMatch, Error::success());
1339 }
1340 
1341 unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
1342  // Just compute the number of matching characters. For regular expressions, we
1343  // just compare against the regex itself and hope for the best.
1344  //
1345  // FIXME: One easy improvement here is have the regex lib generate a single
1346  // example regular expression which matches, and use that as the example
1347  // string.
1348  StringRef ExampleString(FixedStr);
1349  if (ExampleString.empty())
1350  ExampleString = RegExStr;
1351 
1352  // Only compare up to the first line in the buffer, or the string size.
1353  StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
1354  BufferPrefix = BufferPrefix.split('\n').first;
1355  return BufferPrefix.edit_distance(ExampleString);
1356 }
1357 
1358 void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
1359  SMRange Range,
1360  FileCheckDiag::MatchType MatchTy,
1361  std::vector<FileCheckDiag> *Diags) const {
1362  // Print what we know about substitutions.
1363  if (!Substitutions.empty()) {
1364  for (const auto &Substitution : Substitutions) {
1367 
1368  Expected<std::string> MatchedValue = Substitution->getResult();
1369  // Substitution failures are handled in printNoMatch().
1370  if (!MatchedValue) {
1371  consumeError(MatchedValue.takeError());
1372  continue;
1373  }
1374 
1375  OS << "with \"";
1376  OS.write_escaped(Substitution->getFromString()) << "\" equal to \"";
1377  OS.write_escaped(*MatchedValue) << "\"";
1378 
1379  // We report only the start of the match/search range to suggest we are
1380  // reporting the substitutions as set at the start of the match/search.
1381  // Indicating a non-zero-length range might instead seem to imply that the
1382  // substitution matches or was captured from exactly that range.
1383  if (Diags)
1384  Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy,
1385  SMRange(Range.Start, Range.Start), OS.str());
1386  else
1387  SM.PrintMessage(Range.Start, SourceMgr::DK_Note, OS.str());
1388  }
1389  }
1390 }
1391 
1392 void Pattern::printVariableDefs(const SourceMgr &SM,
1393  FileCheckDiag::MatchType MatchTy,
1394  std::vector<FileCheckDiag> *Diags) const {
1395  if (VariableDefs.empty() && NumericVariableDefs.empty())
1396  return;
1397  // Build list of variable captures.
1398  struct VarCapture {
1399  StringRef Name;
1400  SMRange Range;
1401  };
1402  SmallVector<VarCapture, 2> VarCaptures;
1403  for (const auto &VariableDef : VariableDefs) {
1404  VarCapture VC;
1405  VC.Name = VariableDef.first;
1406  StringRef Value = Context->GlobalVariableTable[VC.Name];
1407  SMLoc Start = SMLoc::getFromPointer(Value.data());
1408  SMLoc End = SMLoc::getFromPointer(Value.data() + Value.size());
1409  VC.Range = SMRange(Start, End);
1410  VarCaptures.push_back(VC);
1411  }
1412  for (const auto &VariableDef : NumericVariableDefs) {
1413  VarCapture VC;
1414  VC.Name = VariableDef.getKey();
1415  Optional<StringRef> StrValue =
1416  VariableDef.getValue().DefinedNumericVariable->getStringValue();
1417  if (!StrValue)
1418  continue;
1419  SMLoc Start = SMLoc::getFromPointer(StrValue->data());
1420  SMLoc End = SMLoc::getFromPointer(StrValue->data() + StrValue->size());
1421  VC.Range = SMRange(Start, End);
1422  VarCaptures.push_back(VC);
1423  }
1424  // Sort variable captures by the order in which they matched the input.
1425  // Ranges shouldn't be overlapping, so we can just compare the start.
1426  llvm::sort(VarCaptures, [](const VarCapture &A, const VarCapture &B) {
1427  assert(A.Range.Start != B.Range.Start &&
1428  "unexpected overlapping variable captures");
1429  return A.Range.Start.getPointer() < B.Range.Start.getPointer();
1430  });
1431  // Create notes for the sorted captures.
1432  for (const VarCapture &VC : VarCaptures) {
1435  OS << "captured var \"" << VC.Name << "\"";
1436  if (Diags)
1437  Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, VC.Range, OS.str());
1438  else
1439  SM.PrintMessage(VC.Range.Start, SourceMgr::DK_Note, OS.str(), VC.Range);
1440  }
1441 }
1442 
1443 static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
1444  const SourceMgr &SM, SMLoc Loc,
1445  Check::FileCheckType CheckTy,
1446  StringRef Buffer, size_t Pos, size_t Len,
1447  std::vector<FileCheckDiag> *Diags,
1448  bool AdjustPrevDiags = false) {
1449  SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos);
1450  SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len);
1451  SMRange Range(Start, End);
1452  if (Diags) {
1453  if (AdjustPrevDiags) {
1454  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
1455  for (auto I = Diags->rbegin(), E = Diags->rend();
1456  I != E && I->CheckLoc == CheckLoc; ++I)
1457  I->MatchTy = MatchTy;
1458  } else
1459  Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range);
1460  }
1461  return Range;
1462 }
1463 
1464 void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
1465  std::vector<FileCheckDiag> *Diags) const {
1466  // Attempt to find the closest/best fuzzy match. Usually an error happens
1467  // because some string in the output didn't exactly match. In these cases, we
1468  // would like to show the user a best guess at what "should have" matched, to
1469  // save them having to actually check the input manually.
1470  size_t NumLinesForward = 0;
1471  size_t Best = StringRef::npos;
1472  double BestQuality = 0;
1473 
1474  // Use an arbitrary 4k limit on how far we will search.
1475  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
1476  if (Buffer[i] == '\n')
1477  ++NumLinesForward;
1478 
1479  // Patterns have leading whitespace stripped, so skip whitespace when
1480  // looking for something which looks like a pattern.
1481  if (Buffer[i] == ' ' || Buffer[i] == '\t')
1482  continue;
1483 
1484  // Compute the "quality" of this match as an arbitrary combination of the
1485  // match distance and the number of lines skipped to get to this match.
1486  unsigned Distance = computeMatchDistance(Buffer.substr(i));
1487  double Quality = Distance + (NumLinesForward / 100.);
1488 
1489  if (Quality < BestQuality || Best == StringRef::npos) {
1490  Best = i;
1491  BestQuality = Quality;
1492  }
1493  }
1494 
1495  // Print the "possible intended match here" line if we found something
1496  // reasonable and not equal to what we showed in the "scanning from here"
1497  // line.
1498  if (Best && Best != StringRef::npos && BestQuality < 50) {
1499  SMRange MatchRange =
1500  ProcessMatchResult(FileCheckDiag::MatchFuzzy, SM, getLoc(),
1501  getCheckTy(), Buffer, Best, 0, Diags);
1502  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note,
1503  "possible intended match here");
1504 
1505  // FIXME: If we wanted to be really friendly we would show why the match
1506  // failed, as it can be hard to spot simple one character differences.
1507  }
1508 }
1509 
1512  auto VarIter = GlobalVariableTable.find(VarName);
1513  if (VarIter == GlobalVariableTable.end())
1514  return make_error<UndefVarError>(VarName);
1515 
1516  return VarIter->second;
1517 }
1518 
1519 template <class... Types>
1520 NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) {
1521  NumericVariables.push_back(std::make_unique<NumericVariable>(args...));
1522  return NumericVariables.back().get();
1523 }
1524 
1525 Substitution *
1526 FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
1527  size_t InsertIdx) {
1528  Substitutions.push_back(
1529  std::make_unique<StringSubstitution>(this, VarName, InsertIdx));
1530  return Substitutions.back().get();
1531 }
1532 
1533 Substitution *FileCheckPatternContext::makeNumericSubstitution(
1534  StringRef ExpressionStr, std::unique_ptr<Expression> Expression,
1535  size_t InsertIdx) {
1536  Substitutions.push_back(std::make_unique<NumericSubstitution>(
1537  this, ExpressionStr, std::move(Expression), InsertIdx));
1538  return Substitutions.back().get();
1539 }
1540 
1541 size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
1542  // Offset keeps track of the current offset within the input Str
1543  size_t Offset = 0;
1544  // [...] Nesting depth
1545  size_t BracketDepth = 0;
1546 
1547  while (!Str.empty()) {
1548  if (Str.startswith("]]") && BracketDepth == 0)
1549  return Offset;
1550  if (Str[0] == '\\') {
1551  // Backslash escapes the next char within regexes, so skip them both.
1552  Str = Str.substr(2);
1553  Offset += 2;
1554  } else {
1555  switch (Str[0]) {
1556  default:
1557  break;
1558  case '[':
1559  BracketDepth++;
1560  break;
1561  case ']':
1562  if (BracketDepth == 0) {
1563  SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
1565  "missing closing \"]\" for regex variable");
1566  exit(1);
1567  }
1568  BracketDepth--;
1569  break;
1570  }
1571  Str = Str.substr(1);
1572  Offset++;
1573  }
1574  }
1575 
1576  return StringRef::npos;
1577 }
1578 
1580  SmallVectorImpl<char> &OutputBuffer) {
1581  OutputBuffer.reserve(MB.getBufferSize());
1582 
1583  for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
1584  Ptr != End; ++Ptr) {
1585  // Eliminate trailing dosish \r.
1586  if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
1587  continue;
1588  }
1589 
1590  // If current char is not a horizontal whitespace or if horizontal
1591  // whitespace canonicalization is disabled, dump it to output as is.
1592  if (Req.NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) {
1593  OutputBuffer.push_back(*Ptr);
1594  continue;
1595  }
1596 
1597  // Otherwise, add one space and advance over neighboring space.
1598  OutputBuffer.push_back(' ');
1599  while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
1600  ++Ptr;
1601  }
1602 
1603  // Add a null byte and then return all but that byte.
1604  OutputBuffer.push_back('\0');
1605  return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
1606 }
1607 
1609  const Check::FileCheckType &CheckTy,
1610  SMLoc CheckLoc, MatchType MatchTy,
1611  SMRange InputRange, StringRef Note)
1612  : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy), Note(Note) {
1613  auto Start = SM.getLineAndColumn(InputRange.Start);
1614  auto End = SM.getLineAndColumn(InputRange.End);
1615  InputStartLine = Start.first;
1616  InputStartCol = Start.second;
1617  InputEndLine = End.first;
1618  InputEndCol = End.second;
1619 }
1620 
1621 static bool IsPartOfWord(char c) {
1622  return (isAlnum(c) || c == '-' || c == '_');
1623 }
1624 
1626  assert(Count > 0 && "zero and negative counts are not supported");
1627  assert((C == 1 || Kind == CheckPlain) &&
1628  "count supported only for plain CHECK directives");
1629  Count = C;
1630  return *this;
1631 }
1632 
1634  if (Modifiers.none())
1635  return "";
1636  std::string Ret;
1637  raw_string_ostream OS(Ret);
1638  OS << '{';
1639  if (isLiteralMatch())
1640  OS << "LITERAL";
1641  OS << '}';
1642  return OS.str();
1643 }
1644 
1646  // Append directive modifiers.
1647  auto WithModifiers = [this, Prefix](StringRef Str) -> std::string {
1648  return (Prefix + Str + getModifiersDescription()).str();
1649  };
1650 
1651  switch (Kind) {
1652  case Check::CheckNone:
1653  return "invalid";
1654  case Check::CheckPlain:
1655  if (Count > 1)
1656  return WithModifiers("-COUNT");
1657  return WithModifiers("");
1658  case Check::CheckNext:
1659  return WithModifiers("-NEXT");
1660  case Check::CheckSame:
1661  return WithModifiers("-SAME");
1662  case Check::CheckNot:
1663  return WithModifiers("-NOT");
1664  case Check::CheckDAG:
1665  return WithModifiers("-DAG");
1666  case Check::CheckLabel:
1667  return WithModifiers("-LABEL");
1668  case Check::CheckEmpty:
1669  return WithModifiers("-EMPTY");
1670  case Check::CheckComment:
1671  return std::string(Prefix);
1672  case Check::CheckEOF:
1673  return "implicit EOF";
1674  case Check::CheckBadNot:
1675  return "bad NOT";
1676  case Check::CheckBadCount:
1677  return "bad COUNT";
1678  }
1679  llvm_unreachable("unknown FileCheckType");
1680 }
1681 
1682 static std::pair<Check::FileCheckType, StringRef>
1683 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix) {
1684  if (Buffer.size() <= Prefix.size())
1685  return {Check::CheckNone, StringRef()};
1686 
1687  StringRef Rest = Buffer.drop_front(Prefix.size());
1688  // Check for comment.
1690  if (Rest.consume_front(":"))
1691  return {Check::CheckComment, Rest};
1692  // Ignore a comment prefix if it has a suffix like "-NOT".
1693  return {Check::CheckNone, StringRef()};
1694  }
1695 
1696  auto ConsumeModifiers = [&](Check::FileCheckType Ret)
1697  -> std::pair<Check::FileCheckType, StringRef> {
1698  if (Rest.consume_front(":"))
1699  return {Ret, Rest};
1700  if (!Rest.consume_front("{"))
1701  return {Check::CheckNone, StringRef()};
1702 
1703  // Parse the modifiers, speparated by commas.
1704  do {
1705  // Allow whitespace in modifiers list.
1706  Rest = Rest.ltrim();
1707  if (Rest.consume_front("LITERAL"))
1708  Ret.setLiteralMatch();
1709  else
1710  return {Check::CheckNone, Rest};
1711  // Allow whitespace in modifiers list.
1712  Rest = Rest.ltrim();
1713  } while (Rest.consume_front(","));
1714  if (!Rest.consume_front("}:"))
1715  return {Check::CheckNone, Rest};
1716  return {Ret, Rest};
1717  };
1718 
1719  // Verify that the prefix is followed by directive modifiers or a colon.
1720  if (Rest.consume_front(":"))
1721  return {Check::CheckPlain, Rest};
1722  if (Rest.front() == '{')
1723  return ConsumeModifiers(Check::CheckPlain);
1724 
1725  if (!Rest.consume_front("-"))
1726  return {Check::CheckNone, StringRef()};
1727 
1728  if (Rest.consume_front("COUNT-")) {
1729  int64_t Count;
1730  if (Rest.consumeInteger(10, Count))
1731  // Error happened in parsing integer.
1732  return {Check::CheckBadCount, Rest};
1733  if (Count <= 0 || Count > INT32_MAX)
1734  return {Check::CheckBadCount, Rest};
1735  if (Rest.front() != ':' && Rest.front() != '{')
1736  return {Check::CheckBadCount, Rest};
1737  return ConsumeModifiers(
1738  Check::FileCheckType(Check::CheckPlain).setCount(Count));
1739  }
1740 
1741  // You can't combine -NOT with another suffix.
1742  if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
1743  Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
1744  Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") ||
1745  Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:"))
1746  return {Check::CheckBadNot, Rest};
1747 
1748  if (Rest.consume_front("NEXT"))
1749  return ConsumeModifiers(Check::CheckNext);
1750 
1751  if (Rest.consume_front("SAME"))
1752  return ConsumeModifiers(Check::CheckSame);
1753 
1754  if (Rest.consume_front("NOT"))
1755  return ConsumeModifiers(Check::CheckNot);
1756 
1757  if (Rest.consume_front("DAG"))
1758  return ConsumeModifiers(Check::CheckDAG);
1759 
1760  if (Rest.consume_front("LABEL"))
1761  return ConsumeModifiers(Check::CheckLabel);
1762 
1763  if (Rest.consume_front("EMPTY"))
1764  return ConsumeModifiers(Check::CheckEmpty);
1765 
1766  return {Check::CheckNone, Rest};
1767 }
1768 
1769 // From the given position, find the next character after the word.
1770 static size_t SkipWord(StringRef Str, size_t Loc) {
1771  while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
1772  ++Loc;
1773  return Loc;
1774 }
1775 
1776 /// Searches the buffer for the first prefix in the prefix regular expression.
1777 ///
1778 /// This searches the buffer using the provided regular expression, however it
1779 /// enforces constraints beyond that:
1780 /// 1) The found prefix must not be a suffix of something that looks like
1781 /// a valid prefix.
1782 /// 2) The found prefix must be followed by a valid check type suffix using \c
1783 /// FindCheckType above.
1784 ///
1785 /// \returns a pair of StringRefs into the Buffer, which combines:
1786 /// - the first match of the regular expression to satisfy these two is
1787 /// returned,
1788 /// otherwise an empty StringRef is returned to indicate failure.
1789 /// - buffer rewound to the location right after parsed suffix, for parsing
1790 /// to continue from
1791 ///
1792 /// If this routine returns a valid prefix, it will also shrink \p Buffer to
1793 /// start at the beginning of the returned prefix, increment \p LineNumber for
1794 /// each new line consumed from \p Buffer, and set \p CheckTy to the type of
1795 /// check found by examining the suffix.
1796 ///
1797 /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
1798 /// is unspecified.
1799 static std::pair<StringRef, StringRef>
1800 FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE,
1801  StringRef &Buffer, unsigned &LineNumber,
1802  Check::FileCheckType &CheckTy) {
1803  SmallVector<StringRef, 2> Matches;
1804 
1805  while (!Buffer.empty()) {
1806  // Find the first (longest) match using the RE.
1807  if (!PrefixRE.match(Buffer, &Matches))
1808  // No match at all, bail.
1809  return {StringRef(), StringRef()};
1810 
1811  StringRef Prefix = Matches[0];
1812  Matches.clear();
1813 
1814  assert(Prefix.data() >= Buffer.data() &&
1815  Prefix.data() < Buffer.data() + Buffer.size() &&
1816  "Prefix doesn't start inside of buffer!");
1817  size_t Loc = Prefix.data() - Buffer.data();
1818  StringRef Skipped = Buffer.substr(0, Loc);
1819  Buffer = Buffer.drop_front(Loc);
1820  LineNumber += Skipped.count('\n');
1821 
1822  // Check that the matched prefix isn't a suffix of some other check-like
1823  // word.
1824  // FIXME: This is a very ad-hoc check. it would be better handled in some
1825  // other way. Among other things it seems hard to distinguish between
1826  // intentional and unintentional uses of this feature.
1827  if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
1828  // Now extract the type.
1829  StringRef AfterSuffix;
1830  std::tie(CheckTy, AfterSuffix) = FindCheckType(Req, Buffer, Prefix);
1831 
1832  // If we've found a valid check type for this prefix, we're done.
1833  if (CheckTy != Check::CheckNone)
1834  return {Prefix, AfterSuffix};
1835  }
1836 
1837  // If we didn't successfully find a prefix, we need to skip this invalid
1838  // prefix and continue scanning. We directly skip the prefix that was
1839  // matched and any additional parts of that check-like word.
1840  Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size()));
1841  }
1842 
1843  // We ran out of buffer while skipping partial matches so give up.
1844  return {StringRef(), StringRef()};
1845 }
1846 
1848  assert(!LineVariable && "@LINE pseudo numeric variable already created");
1849  StringRef LineName = "@LINE";
1850  LineVariable = makeNumericVariable(
1852  GlobalNumericVariableTable[LineName] = LineVariable;
1853 }
1854 
1856  : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()),
1857  CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {}
1858 
1859 FileCheck::~FileCheck() = default;
1860 
1862  SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
1863  std::pair<unsigned, unsigned> *ImpPatBufferIDRange) {
1864  if (ImpPatBufferIDRange)
1865  ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0;
1866 
1867  Error DefineError =
1868  PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM);
1869  if (DefineError) {
1870  logAllUnhandledErrors(std::move(DefineError), errs());
1871  return true;
1872  }
1873 
1874  PatternContext->createLineVariable();
1875 
1876  std::vector<Pattern> ImplicitNegativeChecks;
1877  for (StringRef PatternString : Req.ImplicitCheckNot) {
1878  // Create a buffer with fake command line content in order to display the
1879  // command line option responsible for the specific implicit CHECK-NOT.
1880  std::string Prefix = "-implicit-check-not='";
1881  std::string Suffix = "'";
1882  std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
1883  (Prefix + PatternString + Suffix).str(), "command line");
1884 
1885  StringRef PatternInBuffer =
1886  CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
1887  unsigned BufferID = SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
1888  if (ImpPatBufferIDRange) {
1889  if (ImpPatBufferIDRange->first == ImpPatBufferIDRange->second) {
1890  ImpPatBufferIDRange->first = BufferID;
1891  ImpPatBufferIDRange->second = BufferID + 1;
1892  } else {
1893  assert(BufferID == ImpPatBufferIDRange->second &&
1894  "expected consecutive source buffer IDs");
1895  ++ImpPatBufferIDRange->second;
1896  }
1897  }
1898 
1899  ImplicitNegativeChecks.push_back(
1900  Pattern(Check::CheckNot, PatternContext.get()));
1901  ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
1902  "IMPLICIT-CHECK", SM, Req);
1903  }
1904 
1905  std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
1906 
1907  // LineNumber keeps track of the line on which CheckPrefix instances are
1908  // found.
1909  unsigned LineNumber = 1;
1910 
1911  std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(),
1912  Req.CheckPrefixes.end());
1913  const size_t DistinctPrefixes = PrefixesNotFound.size();
1914  while (true) {
1915  Check::FileCheckType CheckTy;
1916 
1917  // See if a prefix occurs in the memory buffer.
1918  StringRef UsedPrefix;
1919  StringRef AfterSuffix;
1920  std::tie(UsedPrefix, AfterSuffix) =
1921  FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy);
1922  if (UsedPrefix.empty())
1923  break;
1924  if (CheckTy != Check::CheckComment)
1925  PrefixesNotFound.erase(UsedPrefix);
1926 
1927  assert(UsedPrefix.data() == Buffer.data() &&
1928  "Failed to move Buffer's start forward, or pointed prefix outside "
1929  "of the buffer!");
1930  assert(AfterSuffix.data() >= Buffer.data() &&
1931  AfterSuffix.data() < Buffer.data() + Buffer.size() &&
1932  "Parsing after suffix doesn't start inside of buffer!");
1933 
1934  // Location to use for error messages.
1935  const char *UsedPrefixStart = UsedPrefix.data();
1936 
1937  // Skip the buffer to the end of parsed suffix (or just prefix, if no good
1938  // suffix was processed).
1939  Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size())
1940  : AfterSuffix;
1941 
1942  // Complain about useful-looking but unsupported suffixes.
1943  if (CheckTy == Check::CheckBadNot) {
1945  "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
1946  return true;
1947  }
1948 
1949  // Complain about invalid count specification.
1950  if (CheckTy == Check::CheckBadCount) {
1952  "invalid count in -COUNT specification on prefix '" +
1953  UsedPrefix + "'");
1954  return true;
1955  }
1956 
1957  // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
1958  // leading whitespace.
1959  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
1960  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
1961 
1962  // Scan ahead to the end of line.
1963  size_t EOL = Buffer.find_first_of("\n\r");
1964 
1965  // Remember the location of the start of the pattern, for diagnostics.
1966  SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
1967 
1968  // Extract the pattern from the buffer.
1969  StringRef PatternBuffer = Buffer.substr(0, EOL);
1970  Buffer = Buffer.substr(EOL);
1971 
1972  // If this is a comment, we're done.
1973  if (CheckTy == Check::CheckComment)
1974  continue;
1975 
1976  // Parse the pattern.
1977  Pattern P(CheckTy, PatternContext.get(), LineNumber);
1978  if (P.parsePattern(PatternBuffer, UsedPrefix, SM, Req))
1979  return true;
1980 
1981  // Verify that CHECK-LABEL lines do not define or use variables
1982  if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
1983  SM.PrintMessage(
1984  SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
1985  "found '" + UsedPrefix + "-LABEL:'"
1986  " with variable definition or use");
1987  return true;
1988  }
1989 
1990  // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
1991  if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
1992  CheckTy == Check::CheckEmpty) &&
1993  CheckStrings->empty()) {
1994  StringRef Type = CheckTy == Check::CheckNext
1995  ? "NEXT"
1996  : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
1997  SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
1999  "found '" + UsedPrefix + "-" + Type +
2000  "' without previous '" + UsedPrefix + ": line");
2001  return true;
2002  }
2003 
2004  // Handle CHECK-DAG/-NOT.
2005  if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
2006  DagNotMatches.push_back(P);
2007  continue;
2008  }
2009 
2010  // Okay, add the string we captured to the output vector and move on.
2011  CheckStrings->emplace_back(P, UsedPrefix, PatternLoc);
2012  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2013  DagNotMatches = ImplicitNegativeChecks;
2014  }
2015 
2016  // When there are no used prefixes we report an error except in the case that
2017  // no prefix is specified explicitly but -implicit-check-not is specified.
2018  const bool NoPrefixesFound = PrefixesNotFound.size() == DistinctPrefixes;
2019  const bool SomePrefixesUnexpectedlyNotUsed =
2020  !Req.AllowUnusedPrefixes && !PrefixesNotFound.empty();
2021  if ((NoPrefixesFound || SomePrefixesUnexpectedlyNotUsed) &&
2022  (ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) {
2023  errs() << "error: no check strings found with prefix"
2024  << (PrefixesNotFound.size() > 1 ? "es " : " ");
2025  bool First = true;
2026  for (StringRef MissingPrefix : PrefixesNotFound) {
2027  if (!First)
2028  errs() << ", ";
2029  errs() << "\'" << MissingPrefix << ":'";
2030  First = false;
2031  }
2032  errs() << '\n';
2033  return true;
2034  }
2035 
2036  // Add an EOF pattern for any trailing --implicit-check-not/CHECK-DAG/-NOTs,
2037  // and use the first prefix as a filler for the error message.
2038  if (!DagNotMatches.empty()) {
2039  CheckStrings->emplace_back(
2040  Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
2041  *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
2042  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2043  }
2044 
2045  return false;
2046 }
2047 
2048 /// Returns either (1) \c ErrorSuccess if there was no error or (2)
2049 /// \c ErrorReported if an error was reported, such as an unexpected match.
2050 static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
2051  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2052  int MatchedCount, StringRef Buffer,
2053  Pattern::MatchResult MatchResult,
2054  const FileCheckRequest &Req,
2055  std::vector<FileCheckDiag> *Diags) {
2056  // Suppress some verbosity if there's no error.
2057  bool HasError = !ExpectedMatch || MatchResult.TheError;
2058  bool PrintDiag = true;
2059  if (!HasError) {
2060  if (!Req.Verbose)
2061  return ErrorReported::reportedOrSuccess(HasError);
2062  if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF)
2063  return ErrorReported::reportedOrSuccess(HasError);
2064  // Due to their verbosity, we don't print verbose diagnostics here if we're
2065  // gathering them for Diags to be rendered elsewhere, but we always print
2066  // other diagnostics.
2067  PrintDiag = !Diags;
2068  }
2069 
2070  // Add "found" diagnostic, substitutions, and variable definitions to Diags.
2071  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2074  SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2075  Buffer, MatchResult.TheMatch->Pos,
2076  MatchResult.TheMatch->Len, Diags);
2077  if (Diags) {
2078  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags);
2079  Pat.printVariableDefs(SM, MatchTy, Diags);
2080  }
2081  if (!PrintDiag) {
2082  assert(!HasError && "expected to report more diagnostics for error");
2083  return ErrorReported::reportedOrSuccess(HasError);
2084  }
2085 
2086  // Print the match.
2087  std::string Message = formatv("{0}: {1} string found in input",
2089  (ExpectedMatch ? "expected" : "excluded"))
2090  .str();
2091  if (Pat.getCount() > 1)
2092  Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2093  SM.PrintMessage(
2094  Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message);
2095  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here",
2096  {MatchRange});
2097 
2098  // Print additional information, which can be useful even if there are errors.
2099  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, nullptr);
2100  Pat.printVariableDefs(SM, MatchTy, nullptr);
2101 
2102  // Print errors and add them to Diags. We report these errors after the match
2103  // itself because we found them after the match. If we had found them before
2104  // the match, we'd be in printNoMatch.
2105  handleAllErrors(std::move(MatchResult.TheError),
2106  [&](const ErrorDiagnostic &E) {
2107  E.log(errs());
2108  if (Diags) {
2109  Diags->emplace_back(SM, Pat.getCheckTy(), Loc,
2110  FileCheckDiag::MatchFoundErrorNote,
2111  E.getRange(), E.getMessage().str());
2112  }
2113  });
2114  return ErrorReported::reportedOrSuccess(HasError);
2115 }
2116 
2117 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2118 /// \c ErrorReported if an error was reported, such as an expected match not
2119 /// found.
2120 static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM,
2121  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2122  int MatchedCount, StringRef Buffer, Error MatchError,
2123  bool VerboseVerbose,
2124  std::vector<FileCheckDiag> *Diags) {
2125  // Print any pattern errors, and record them to be added to Diags later.
2126  bool HasError = ExpectedMatch;
2127  bool HasPatternError = false;
2128  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2129  ? FileCheckDiag::MatchNoneButExpected
2130  : FileCheckDiag::MatchNoneAndExcluded;
2131  SmallVector<std::string, 4> ErrorMsgs;
2133  std::move(MatchError),
2134  [&](const ErrorDiagnostic &E) {
2135  HasError = HasPatternError = true;
2136  MatchTy = FileCheckDiag::MatchNoneForInvalidPattern;
2137  E.log(errs());
2138  if (Diags)
2139  ErrorMsgs.push_back(E.getMessage().str());
2140  },
2141  // NotFoundError is why printNoMatch was invoked.
2142  [](const NotFoundError &E) {});
2143 
2144  // Suppress some verbosity if there's no error.
2145  bool PrintDiag = true;
2146  if (!HasError) {
2147  if (!VerboseVerbose)
2148  return ErrorReported::reportedOrSuccess(HasError);
2149  // Due to their verbosity, we don't print verbose diagnostics here if we're
2150  // gathering them for Diags to be rendered elsewhere, but we always print
2151  // other diagnostics.
2152  PrintDiag = !Diags;
2153  }
2154 
2155  // Add "not found" diagnostic, substitutions, and pattern errors to Diags.
2156  //
2157  // We handle Diags a little differently than the errors we print directly:
2158  // we add the "not found" diagnostic to Diags even if there are pattern
2159  // errors. The reason is that we need to attach pattern errors as notes
2160  // somewhere in the input, and the input search range from the "not found"
2161  // diagnostic is all we have to anchor them.
2162  SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2163  Buffer, 0, Buffer.size(), Diags);
2164  if (Diags) {
2165  SMRange NoteRange = SMRange(SearchRange.Start, SearchRange.Start);
2166  for (StringRef ErrorMsg : ErrorMsgs)
2167  Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, NoteRange,
2168  ErrorMsg);
2169  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, Diags);
2170  }
2171  if (!PrintDiag) {
2172  assert(!HasError && "expected to report more diagnostics for error");
2173  return ErrorReported::reportedOrSuccess(HasError);
2174  }
2175 
2176  // Print "not found" diagnostic, except that's implied if we already printed a
2177  // pattern error.
2178  if (!HasPatternError) {
2179  std::string Message = formatv("{0}: {1} string not found in input",
2181  (ExpectedMatch ? "expected" : "excluded"))
2182  .str();
2183  if (Pat.getCount() > 1)
2184  Message +=
2185  formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2186  SM.PrintMessage(Loc,
2187  ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark,
2188  Message);
2189  SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note,
2190  "scanning from here");
2191  }
2192 
2193  // Print additional information, which can be useful even after a pattern
2194  // error.
2195  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, nullptr);
2196  if (ExpectedMatch)
2197  Pat.printFuzzyMatch(SM, Buffer, Diags);
2198  return ErrorReported::reportedOrSuccess(HasError);
2199 }
2200 
2201 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2202 /// \c ErrorReported if an error was reported.
2203 static Error reportMatchResult(bool ExpectedMatch, const SourceMgr &SM,
2204  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2205  int MatchedCount, StringRef Buffer,
2206  Pattern::MatchResult MatchResult,
2207  const FileCheckRequest &Req,
2208  std::vector<FileCheckDiag> *Diags) {
2209  if (MatchResult.TheMatch)
2210  return printMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2211  std::move(MatchResult), Req, Diags);
2212  return printNoMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2213  std::move(MatchResult.TheError), Req.VerboseVerbose,
2214  Diags);
2215 }
2216 
2217 /// Counts the number of newlines in the specified range.
2218 static unsigned CountNumNewlinesBetween(StringRef Range,
2219  const char *&FirstNewLine) {
2220  unsigned NumNewLines = 0;
2221  while (true) {
2222  // Scan for newline.
2223  Range = Range.substr(Range.find_first_of("\n\r"));
2224  if (Range.empty())
2225  return NumNewLines;
2226 
2227  ++NumNewLines;
2228 
2229  // Handle \n\r and \r\n as a single newline.
2230  if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
2231  (Range[0] != Range[1]))
2232  Range = Range.substr(1);
2233  Range = Range.substr(1);
2234 
2235  if (NumNewLines == 1)
2236  FirstNewLine = Range.begin();
2237  }
2238 }
2239 
2240 size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
2241  bool IsLabelScanMode, size_t &MatchLen,
2242  FileCheckRequest &Req,
2243  std::vector<FileCheckDiag> *Diags) const {
2244  size_t LastPos = 0;
2245  std::vector<const Pattern *> NotStrings;
2246 
2247  // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
2248  // bounds; we have not processed variable definitions within the bounded block
2249  // yet so cannot handle any final CHECK-DAG yet; this is handled when going
2250  // over the block again (including the last CHECK-LABEL) in normal mode.
2251  if (!IsLabelScanMode) {
2252  // Match "dag strings" (with mixed "not strings" if any).
2253  LastPos = CheckDag(SM, Buffer, NotStrings, Req, Diags);
2254  if (LastPos == StringRef::npos)
2255  return StringRef::npos;
2256  }
2257 
2258  // Match itself from the last position after matching CHECK-DAG.
2259  size_t LastMatchEnd = LastPos;
2260  size_t FirstMatchPos = 0;
2261  // Go match the pattern Count times. Majority of patterns only match with
2262  // count 1 though.
2263  assert(Pat.getCount() != 0 && "pattern count can not be zero");
2264  for (int i = 1; i <= Pat.getCount(); i++) {
2265  StringRef MatchBuffer = Buffer.substr(LastMatchEnd);
2266  // get a match at current start point
2267  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2268 
2269  // report
2270  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix, Loc,
2271  Pat, i, MatchBuffer,
2272  std::move(MatchResult), Req, Diags)) {
2273  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2274  return StringRef::npos;
2275  }
2276 
2277  size_t MatchPos = MatchResult.TheMatch->Pos;
2278  if (i == 1)
2279  FirstMatchPos = LastPos + MatchPos;
2280 
2281  // move start point after the match
2282  LastMatchEnd += MatchPos + MatchResult.TheMatch->Len;
2283  }
2284  // Full match len counts from first match pos.
2285  MatchLen = LastMatchEnd - FirstMatchPos;
2286 
2287  // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
2288  // or CHECK-NOT
2289  if (!IsLabelScanMode) {
2290  size_t MatchPos = FirstMatchPos - LastPos;
2291  StringRef MatchBuffer = Buffer.substr(LastPos);
2292  StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
2293 
2294  // If this check is a "CHECK-NEXT", verify that the previous match was on
2295  // the previous line (i.e. that there is one newline between them).
2296  if (CheckNext(SM, SkippedRegion)) {
2297  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2298  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2299  Diags, Req.Verbose);
2300  return StringRef::npos;
2301  }
2302 
2303  // If this check is a "CHECK-SAME", verify that the previous match was on
2304  // the same line (i.e. that there is no newline between them).
2305  if (CheckSame(SM, SkippedRegion)) {
2306  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2307  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2308  Diags, Req.Verbose);
2309  return StringRef::npos;
2310  }
2311 
2312  // If this match had "not strings", verify that they don't exist in the
2313  // skipped region.
2314  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2315  return StringRef::npos;
2316  }
2317 
2318  return FirstMatchPos;
2319 }
2320 
2321 bool FileCheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
2322  if (Pat.getCheckTy() != Check::CheckNext &&
2324  return false;
2325 
2326  Twine CheckName =
2327  Prefix +
2328  Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT");
2329 
2330  // Count the number of newlines between the previous match and this one.
2331  const char *FirstNewLine = nullptr;
2332  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2333 
2334  if (NumNewLines == 0) {
2336  CheckName + ": is on the same line as previous match");
2338  "'next' match was here");
2340  "previous match ended here");
2341  return true;
2342  }
2343 
2344  if (NumNewLines != 1) {
2346  CheckName +
2347  ": is not on the line after the previous match");
2349  "'next' match was here");
2351  "previous match ended here");
2353  "non-matching line after previous match is here");
2354  return true;
2355  }
2356 
2357  return false;
2358 }
2359 
2360 bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
2361  if (Pat.getCheckTy() != Check::CheckSame)
2362  return false;
2363 
2364  // Count the number of newlines between the previous match and this one.
2365  const char *FirstNewLine = nullptr;
2366  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2367 
2368  if (NumNewLines != 0) {
2370  Prefix +
2371  "-SAME: is not on the same line as the previous match");
2373  "'next' match was here");
2375  "previous match ended here");
2376  return true;
2377  }
2378 
2379  return false;
2380 }
2381 
2382 bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
2383  const std::vector<const Pattern *> &NotStrings,
2384  const FileCheckRequest &Req,
2385  std::vector<FileCheckDiag> *Diags) const {
2386  bool DirectiveFail = false;
2387  for (const Pattern *Pat : NotStrings) {
2388  assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
2389  Pattern::MatchResult MatchResult = Pat->match(Buffer, SM);
2390  if (Error Err = reportMatchResult(/*ExpectedMatch=*/false, SM, Prefix,
2391  Pat->getLoc(), *Pat, 1, Buffer,
2392  std::move(MatchResult), Req, Diags)) {
2393  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2394  DirectiveFail = true;
2395  continue;
2396  }
2397  }
2398  return DirectiveFail;
2399 }
2400 
2401 size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
2402  std::vector<const Pattern *> &NotStrings,
2403  const FileCheckRequest &Req,
2404  std::vector<FileCheckDiag> *Diags) const {
2405  if (DagNotStrings.empty())
2406  return 0;
2407 
2408  // The start of the search range.
2409  size_t StartPos = 0;
2410 
2411  struct MatchRange {
2412  size_t Pos;
2413  size_t End;
2414  };
2415  // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match
2416  // ranges are erased from this list once they are no longer in the search
2417  // range.
2418  std::list<MatchRange> MatchRanges;
2419 
2420  // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG
2421  // group, so we don't use a range-based for loop here.
2422  for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end();
2423  PatItr != PatEnd; ++PatItr) {
2424  const Pattern &Pat = *PatItr;
2426  Pat.getCheckTy() == Check::CheckNot) &&
2427  "Invalid CHECK-DAG or CHECK-NOT!");
2428 
2429  if (Pat.getCheckTy() == Check::CheckNot) {
2430  NotStrings.push_back(&Pat);
2431  continue;
2432  }
2433 
2434  assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
2435 
2436  // CHECK-DAG always matches from the start.
2437  size_t MatchLen = 0, MatchPos = StartPos;
2438 
2439  // Search for a match that doesn't overlap a previous match in this
2440  // CHECK-DAG group.
2441  for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) {
2442  StringRef MatchBuffer = Buffer.substr(MatchPos);
2443  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2444  // With a group of CHECK-DAGs, a single mismatching means the match on
2445  // that group of CHECK-DAGs fails immediately.
2446  if (MatchResult.TheError || Req.VerboseVerbose) {
2447  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix,
2448  Pat.getLoc(), Pat, 1, MatchBuffer,
2449  std::move(MatchResult), Req, Diags)) {
2450  cantFail(
2451  handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2452  return StringRef::npos;
2453  }
2454  }
2455  MatchLen = MatchResult.TheMatch->Len;
2456  // Re-calc it as the offset relative to the start of the original
2457  // string.
2458  MatchPos += MatchResult.TheMatch->Pos;
2459  MatchRange M{MatchPos, MatchPos + MatchLen};
2460  if (Req.AllowDeprecatedDagOverlap) {
2461  // We don't need to track all matches in this mode, so we just maintain
2462  // one match range that encompasses the current CHECK-DAG group's
2463  // matches.
2464  if (MatchRanges.empty())
2465  MatchRanges.insert(MatchRanges.end(), M);
2466  else {
2467  auto Block = MatchRanges.begin();
2468  Block->Pos = std::min(Block->Pos, M.Pos);
2469  Block->End = std::max(Block->End, M.End);
2470  }
2471  break;
2472  }
2473  // Iterate previous matches until overlapping match or insertion point.
2474  bool Overlap = false;
2475  for (; MI != ME; ++MI) {
2476  if (M.Pos < MI->End) {
2477  // !Overlap => New match has no overlap and is before this old match.
2478  // Overlap => New match overlaps this old match.
2479  Overlap = MI->Pos < M.End;
2480  break;
2481  }
2482  }
2483  if (!Overlap) {
2484  // Insert non-overlapping match into list.
2485  MatchRanges.insert(MI, M);
2486  break;
2487  }
2488  if (Req.VerboseVerbose) {
2489  // Due to their verbosity, we don't print verbose diagnostics here if
2490  // we're gathering them for a different rendering, but we always print
2491  // other diagnostics.
2492  if (!Diags) {
2493  SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos);
2494  SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End);
2495  SMRange OldRange(OldStart, OldEnd);
2496  SM.PrintMessage(OldStart, SourceMgr::DK_Note,
2497  "match discarded, overlaps earlier DAG match here",
2498  {OldRange});
2499  } else {
2500  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
2501  for (auto I = Diags->rbegin(), E = Diags->rend();
2502  I != E && I->CheckLoc == CheckLoc; ++I)
2504  }
2505  }
2506  MatchPos = MI->End;
2507  }
2508  if (!Req.VerboseVerbose)
2509  cantFail(printMatch(
2510  /*ExpectedMatch=*/true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer,
2511  Pattern::MatchResult(MatchPos, MatchLen, Error::success()), Req,
2512  Diags));
2513 
2514  // Handle the end of a CHECK-DAG group.
2515  if (std::next(PatItr) == PatEnd ||
2516  std::next(PatItr)->getCheckTy() == Check::CheckNot) {
2517  if (!NotStrings.empty()) {
2518  // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to
2519  // CHECK-DAG, verify that there are no 'not' strings occurred in that
2520  // region.
2521  StringRef SkippedRegion =
2522  Buffer.slice(StartPos, MatchRanges.begin()->Pos);
2523  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2524  return StringRef::npos;
2525  // Clear "not strings".
2526  NotStrings.clear();
2527  }
2528  // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the
2529  // end of this CHECK-DAG group's match range.
2530  StartPos = MatchRanges.rbegin()->End;
2531  // Don't waste time checking for (impossible) overlaps before that.
2532  MatchRanges.clear();
2533  }
2534  }
2535 
2536  return StartPos;
2537 }
2538 
2539 static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes,
2540  ArrayRef<StringRef> SuppliedPrefixes) {
2541  for (StringRef Prefix : SuppliedPrefixes) {
2542  if (Prefix.empty()) {
2543  errs() << "error: supplied " << Kind << " prefix must not be the empty "
2544  << "string\n";
2545  return false;
2546  }
2547  static const Regex Validator("^[a-zA-Z0-9_-]*$");
2548  if (!Validator.match(Prefix)) {
2549  errs() << "error: supplied " << Kind << " prefix must start with a "
2550  << "letter and contain only alphanumeric characters, hyphens, and "
2551  << "underscores: '" << Prefix << "'\n";
2552  return false;
2553  }
2554  if (!UniquePrefixes.insert(Prefix).second) {
2555  errs() << "error: supplied " << Kind << " prefix must be unique among "
2556  << "check and comment prefixes: '" << Prefix << "'\n";
2557  return false;
2558  }
2559  }
2560  return true;
2561 }
2562 
2563 static const char *DefaultCheckPrefixes[] = {"CHECK"};
2564 static const char *DefaultCommentPrefixes[] = {"COM", "RUN"};
2565 
2567  StringSet<> UniquePrefixes;
2568  // Add default prefixes to catch user-supplied duplicates of them below.
2569  if (Req.CheckPrefixes.empty()) {
2570  for (const char *Prefix : DefaultCheckPrefixes)
2571  UniquePrefixes.insert(Prefix);
2572  }
2573  if (Req.CommentPrefixes.empty()) {
2574  for (const char *Prefix : DefaultCommentPrefixes)
2575  UniquePrefixes.insert(Prefix);
2576  }
2577  // Do not validate the default prefixes, or diagnostics about duplicates might
2578  // incorrectly indicate that they were supplied by the user.
2579  if (!ValidatePrefixes("check", UniquePrefixes, Req.CheckPrefixes))
2580  return false;
2581  if (!ValidatePrefixes("comment", UniquePrefixes, Req.CommentPrefixes))
2582  return false;
2583  return true;
2584 }
2585 
2587  if (Req.CheckPrefixes.empty()) {
2588  for (const char *Prefix : DefaultCheckPrefixes)
2589  Req.CheckPrefixes.push_back(Prefix);
2590  Req.IsDefaultCheckPrefix = true;
2591  }
2592  if (Req.CommentPrefixes.empty()) {
2593  for (const char *Prefix : DefaultCommentPrefixes)
2594  Req.CommentPrefixes.push_back(Prefix);
2595  }
2596 
2597  // We already validated the contents of CheckPrefixes and CommentPrefixes so
2598  // just concatenate them as alternatives.
2599  SmallString<32> PrefixRegexStr;
2600  for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) {
2601  if (I != 0)
2602  PrefixRegexStr.push_back('|');
2603  PrefixRegexStr.append(Req.CheckPrefixes[I]);
2604  }
2605  for (StringRef Prefix : Req.CommentPrefixes) {
2606  PrefixRegexStr.push_back('|');
2607  PrefixRegexStr.append(Prefix);
2608  }
2609 
2610  return Regex(PrefixRegexStr);
2611 }
2612 
2614  ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM) {
2615  assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() &&
2616  "Overriding defined variable with command-line variable definitions");
2617 
2618  if (CmdlineDefines.empty())
2619  return Error::success();
2620 
2621  // Create a string representing the vector of command-line definitions. Each
2622  // definition is on its own line and prefixed with a definition number to
2623  // clarify which definition a given diagnostic corresponds to.
2624  unsigned I = 0;
2625  Error Errs = Error::success();
2626  std::string CmdlineDefsDiag;
2627  SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices;
2628  for (StringRef CmdlineDef : CmdlineDefines) {
2629  std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str();
2630  size_t EqIdx = CmdlineDef.find('=');
2631  if (EqIdx == StringRef::npos) {
2632  CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0));
2633  continue;
2634  }
2635  // Numeric variable definition.
2636  if (CmdlineDef[0] == '#') {
2637  // Append a copy of the command-line definition adapted to use the same
2638  // format as in the input file to be able to reuse
2639  // parseNumericSubstitutionBlock.
2640  CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str();
2641  std::string SubstitutionStr = std::string(CmdlineDef);
2642  SubstitutionStr[EqIdx] = ':';
2643  CmdlineDefsIndices.push_back(
2644  std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size()));
2645  CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str();
2646  } else {
2647  CmdlineDefsDiag += DefPrefix;
2648  CmdlineDefsIndices.push_back(
2649  std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size()));
2650  CmdlineDefsDiag += (CmdlineDef + "\n").str();
2651  }
2652  }
2653 
2654  // Create a buffer with fake command line content in order to display
2655  // parsing diagnostic with location information and point to the
2656  // global definition with invalid syntax.
2657  std::unique_ptr<MemoryBuffer> CmdLineDefsDiagBuffer =
2658  MemoryBuffer::getMemBufferCopy(CmdlineDefsDiag, "Global defines");
2659  StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer();
2660  SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc());
2661 
2662  for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) {
2663  StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first,
2664  CmdlineDefIndices.second);
2665  if (CmdlineDef.empty()) {
2666  Errs = joinErrors(
2667  std::move(Errs),
2668  ErrorDiagnostic::get(SM, CmdlineDef,
2669  "missing equal sign in global definition"));
2670  continue;
2671  }
2672 
2673  // Numeric variable definition.
2674  if (CmdlineDef[0] == '#') {
2675  // Now parse the definition both to check that the syntax is correct and
2676  // to create the necessary class instance.
2677  StringRef CmdlineDefExpr = CmdlineDef.substr(1);
2678  Optional<NumericVariable *> DefinedNumericVariable;
2679  Expected<std::unique_ptr<Expression>> ExpressionResult =
2681  CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM);
2682  if (!ExpressionResult) {
2683  Errs = joinErrors(std::move(Errs), ExpressionResult.takeError());
2684  continue;
2685  }
2686  std::unique_ptr<Expression> Expression = std::move(*ExpressionResult);
2687  // Now evaluate the expression whose value this variable should be set
2688  // to, since the expression of a command-line variable definition should
2689  // only use variables defined earlier on the command-line. If not, this
2690  // is an error and we report it.
2692  if (!Value) {
2693  Errs = joinErrors(std::move(Errs), Value.takeError());
2694  continue;
2695  }
2696 
2697  assert(DefinedNumericVariable && "No variable defined");
2698  (*DefinedNumericVariable)->setValue(*Value);
2699 
2700  // Record this variable definition.
2701  GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] =
2702  *DefinedNumericVariable;
2703  } else {
2704  // String variable definition.
2705  std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
2706  StringRef CmdlineName = CmdlineNameVal.first;
2707  StringRef OrigCmdlineName = CmdlineName;
2708  Expected<Pattern::VariableProperties> ParseVarResult =
2709  Pattern::parseVariable(CmdlineName, SM);
2710  if (!ParseVarResult) {
2711  Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
2712  continue;
2713  }
2714  // Check that CmdlineName does not denote a pseudo variable is only
2715  // composed of the parsed numeric variable. This catches cases like
2716  // "FOO+2" in a "FOO+2=10" definition.
2717  if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
2718  Errs = joinErrors(std::move(Errs),
2720  SM, OrigCmdlineName,
2721  "invalid name in string variable definition '" +
2722  OrigCmdlineName + "'"));
2723  continue;
2724  }
2725  StringRef Name = ParseVarResult->Name;
2726 
2727  // Detect collisions between string and numeric variables when the former
2728  // is created later than the latter.
2729  if (GlobalNumericVariableTable.find(Name) !=
2730  GlobalNumericVariableTable.end()) {
2731  Errs = joinErrors(std::move(Errs),
2733  "numeric variable with name '" +
2734  Name + "' already exists"));
2735  continue;
2736  }
2737  GlobalVariableTable.insert(CmdlineNameVal);
2738  // Mark the string variable as defined to detect collisions between
2739  // string and numeric variables in defineCmdlineVariables when the latter
2740  // is created later than the former. We cannot reuse GlobalVariableTable
2741  // for this by populating it with an empty string since we would then
2742  // lose the ability to detect the use of an undefined variable in
2743  // match().
2744  DefinedVariableTable[Name] = true;
2745  }
2746  }
2747 
2748  return Errs;
2749 }
2750 
2752  SmallVector<StringRef, 16> LocalPatternVars, LocalNumericVars;
2753  for (const StringMapEntry<StringRef> &Var : GlobalVariableTable)
2754  if (Var.first()[0] != '$')
2755  LocalPatternVars.push_back(Var.first());
2756 
2757  // Numeric substitution reads the value of a variable directly, not via
2758  // GlobalNumericVariableTable. Therefore, we clear local variables by
2759  // clearing their value which will lead to a numeric substitution failure. We
2760  // also mark the variable for removal from GlobalNumericVariableTable since
2761  // this is what defineCmdlineVariables checks to decide that no global
2762  // variable has been defined.
2763  for (const auto &Var : GlobalNumericVariableTable)
2764  if (Var.first()[0] != '$') {
2765  Var.getValue()->clearValue();
2766  LocalNumericVars.push_back(Var.first());
2767  }
2768 
2769  for (const auto &Var : LocalPatternVars)
2770  GlobalVariableTable.erase(Var);
2771  for (const auto &Var : LocalNumericVars)
2772  GlobalNumericVariableTable.erase(Var);
2773 }
2774 
2775 bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
2776  std::vector<FileCheckDiag> *Diags) {
2777  bool ChecksFailed = false;
2778 
2779  unsigned i = 0, j = 0, e = CheckStrings->size();
2780  while (true) {
2781  StringRef CheckRegion;
2782  if (j == e) {
2783  CheckRegion = Buffer;
2784  } else {
2785  const FileCheckString &CheckLabelStr = (*CheckStrings)[j];
2786  if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
2787  ++j;
2788  continue;
2789  }
2790 
2791  // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
2792  size_t MatchLabelLen = 0;
2793  size_t MatchLabelPos =
2794  CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, Req, Diags);
2795  if (MatchLabelPos == StringRef::npos)
2796  // Immediately bail if CHECK-LABEL fails, nothing else we can do.
2797  return false;
2798 
2799  CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
2800  Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
2801  ++j;
2802  }
2803 
2804  // Do not clear the first region as it's the one before the first
2805  // CHECK-LABEL and it would clear variables defined on the command-line
2806  // before they get used.
2807  if (i != 0 && Req.EnableVarScope)
2808  PatternContext->clearLocalVars();
2809 
2810  for (; i != j; ++i) {
2811  const FileCheckString &CheckStr = (*CheckStrings)[i];
2812 
2813  // Check each string within the scanned region, including a second check
2814  // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
2815  size_t MatchLen = 0;
2816  size_t MatchPos =
2817  CheckStr.Check(SM, CheckRegion, false, MatchLen, Req, Diags);
2818 
2819  if (MatchPos == StringRef::npos) {
2820  ChecksFailed = true;
2821  i = j;
2822  break;
2823  }
2824 
2825  CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
2826  }
2827 
2828  if (j == e)
2829  break;
2830  }
2831 
2832  // Success if no checks failed.
2833  return !ChecksFailed;
2834 }
FileCheck.h
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm::ExpressionValue::ExpressionValue
ExpressionValue(T Val)
Definition: FileCheckImpl.h:128
i
i
Definition: README.txt:29
llvm::StringRef::back
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:168
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:286
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:104
llvm::ExpressionFormat::Kind::Unsigned
@ Unsigned
Value is an unsigned integer and should be printed as a decimal number.
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::StringSubstitution::getResult
Expected< std::string > getResult() const override
Definition: FileCheck.cpp:429
llvm::FileCheckRequest::AllowDeprecatedDagOverlap
bool AllowDeprecatedDagOverlap
Definition: FileCheck.h:42
llvm::FileCheckString::Pat
Pattern Pat
The pattern to match.
Definition: FileCheckImpl.h:867
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:943
llvm::Operator
This is a utility class that provides an abstraction for the common functionality between Instruction...
Definition: Operator.h:32
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::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMapEntry.h:101
llvm::StringRef::count
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:489
llvm::StringRef::rtrim
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:856
llvm::FileCheckRequest::GlobalDefines
std::vector< StringRef > GlobalDefines
Definition: FileCheck.h:35
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:33
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:160
llvm::FileCheckRequest::IsDefaultCheckPrefix
bool IsDefaultCheckPrefix
Definition: FileCheck.h:40
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:183
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:632
llvm::FileCheckRequest::Verbose
bool Verbose
Definition: FileCheck.h:43
llvm::Check::CheckSame
@ CheckSame
Definition: FileCheck.h:53
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:308
llvm::Check::CheckLabel
@ CheckLabel
Definition: FileCheck.h:56
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
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:315
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::FileCheck::~FileCheck
~FileCheck()
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::FileCheckString::Loc
SMLoc Loc
The location in the match file that the check string was specified.
Definition: FileCheckImpl.h:873
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:842
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:682
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::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:45
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:738
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...
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:893
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
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:732
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:1043
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:159
llvm::operator/
Align operator/(Align Lhs, uint64_t Divisor)
Definition: Alignment.h:327
llvm::NumericVariable::getImplicitFormat
ExpressionFormat getImplicitFormat() const
Definition: FileCheckImpl.h:293
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:611
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:186
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.
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:251
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:910
llvm::ErrorReported
An error that has already been reported.
Definition: FileCheckImpl.h:594
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:262
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:620
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:536
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:749
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:31
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::Expression::getAST
ExpressionAST * getAST() const
Definition: FileCheckImpl.h:253
llvm::NotFoundError
Definition: FileCheckImpl.h:570
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:400
Check
#define Check(C,...)
Definition: Lint.cpp:170
llvm::FileCheckDiag::MatchFoundAndExpected
@ MatchFoundAndExpected
Indicates a good match for an expected pattern.
Definition: FileCheck.h:131
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:771
llvm::Check::CheckNot
@ CheckNot
Definition: FileCheck.h:54
llvm::UndefVarError
Class to represent an undefined variable error, which quotes that variable's name when printed.
Definition: FileCheckImpl.h:215
llvm::StringRef::contains
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:462
llvm::ExpressionValue::getSignedValue
Expected< int64_t > getSignedValue() const
Definition: FileCheck.cpp:170
llvm::operator-
APInt operator-(APInt)
Definition: APInt.h:2079
llvm::FileCheckPatternContext
Class holding the Pattern global state, shared by all patterns: tables holding values of variables an...
Definition: FileCheckImpl.h:459
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:607
llvm::FileCheckDiag::MatchFoundButWrongLine
@ MatchFoundButWrongLine
Indicates a match for an expected pattern, but the match is on the wrong line.
Definition: FileCheck.h:136
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:245
llvm::None
const NoneType None
Definition: None.h:24
llvm::Check::FileCheckType::getDescription
std::string getDescription(StringRef Prefix) const
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
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:870
llvm::NumericVariable::getValue
Optional< ExpressionValue > getValue() const
Definition: FileCheckImpl.h:296
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
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:870
llvm::FileCheckDiag::MatchType
MatchType
What type of match result does this diagnostic describe?
Definition: FileCheck.h:129
llvm::ExpressionAST::eval
virtual Expected< ExpressionValue > eval() const =0
Evaluates and.
llvm::Check::FileCheckType
Definition: FileCheck.h:79
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:865
llvm::Check::CheckNext
@ CheckNext
Definition: FileCheck.h:52
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:405
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
uint64_t
llvm::FileCheckDiag::MatchFoundButExcluded
@ MatchFoundButExcluded
Indicates a match for an excluded pattern.
Definition: FileCheck.h:133
llvm::Substitution
Class representing a substitution to perform in the RegExStr string.
Definition: FileCheckImpl.h:388
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
llvm::NotFoundError::ID
static char ID
Definition: FileCheckImpl.h:572
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:348
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:161
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:426
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:1670
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Optional::getValue
constexpr const T & getValue() const &
Definition: Optional.h:279
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
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:241
llvm::Check::CheckBadCount
@ CheckBadCount
Marks when parsing found a -COUNT directive with invalid count value.
Definition: FileCheck.h:68
llvm::operator+
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2084
llvm::Pattern::MatchResult::TheError
Error TheError
Definition: FileCheckImpl.h:740
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:661
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:65
llvm::Expression
Class representing an expression and its matching format.
Definition: FileCheckImpl.h:237
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
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:2126
llvm::FileCheckRequest::MatchFullLines
bool MatchFullLines
Definition: FileCheck.h:38
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
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:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
llvm::ErrorReported::ID
static char ID
Definition: FileCheckImpl.h:596
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:158
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:544
llvm::ExpressionValue::getUnsignedValue
Expected< uint64_t > getUnsignedValue() const
Definition: FileCheck.cpp:181
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
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
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
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:41
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::Check::CheckDAG
@ CheckDAG
Definition: FileCheck.h:55
llvm::Pattern::getCount
int getCount() const
Definition: FileCheckImpl.h:773
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:65
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
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:653
llvm::Check::CheckEmpty
@ CheckEmpty
Definition: FileCheck.h:57
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:155
llvm::ErrorDiagnostic::ID
static char ID
Definition: FileCheckImpl.h:542
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1550
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:144
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:591
llvm::ErrorDiagnostic::get
static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg, SMRange Range=None)
Definition: FileCheckImpl.h:557
llvm::FileCheckDiag::MatchFoundButDiscarded
@ MatchFoundButDiscarded
Indicates a discarded match for an expected pattern.
Definition: FileCheck.h:138
llvm::FileCheckRequest::CommentPrefixes
std::vector< StringRef > CommentPrefixes
Definition: FileCheck.h:32
llvm::FileCheckRequest::IgnoreCase
bool IgnoreCase
Definition: FileCheck.h:39
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::Pattern
Definition: FileCheckImpl.h:614
llvm::Substitution::getIndex
size_t getIndex() const
Definition: FileCheckImpl.h:416
llvm::FileCheckRequest
Contains info about various FileCheck options.
Definition: FileCheck.h:30
llvm::FileCheckRequest::VerboseVerbose
bool VerboseVerbose
Definition: FileCheck.h:44
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:51
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:340
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:662
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:149
llvm::SmallVectorImpl< char >
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::StringRef::find_insensitive
LLVM_NODISCARD size_t find_insensitive(char C, size_t From=0) const
Search for the first character C in the string, ignoring case.
Definition: StringRef.cpp:55
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:44
llvm::Pattern::getLoc
SMLoc getLoc() const
Definition: FileCheckImpl.h:689
llvm::NumericVariable::getDefLineNumber
Optional< size_t > getDefLineNumber() const
Definition: FileCheckImpl.h:323
llvm::NumericVariable
Class representing a numeric variable and its associated current value.
Definition: FileCheckImpl.h:259
llvm::Check::CheckNone
@ CheckNone
Definition: FileCheck.h:50
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:396
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:92
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:410
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:188
llvm::ExpressionFormat::toString
StringRef toString() const
Definition: FileCheck.cpp:31
llvm::Check::FileCheckType::isLiteralMatch
bool isLiteralMatch() const
Definition: FileCheck.h:95
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:394
llvm::Regex
Definition: Regex.h:28
llvm::FileCheckRequest::ImplicitCheckNot
std::vector< StringRef > ImplicitCheckNot
Definition: FileCheck.h:34
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:138
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:644
llvm::Substitution::getFromString
StringRef getFromString() const
Definition: FileCheckImpl.h:413
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::pdb::PDB_SymType::Block
@ Block
llvm::FileCheckPatternContext::createLineVariable
void createLineVariable()
Create @LINE pseudo variable.
llvm::FileCheckRequest::AllowUnusedPrefixes
bool AllowUnusedPrefixes
Definition: FileCheck.h:37
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:966
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::Check::CheckEOF
@ CheckEOF
Indicates the pattern only matches the end of file.
Definition: FileCheck.h:62
llvm::Check::CheckComment
@ CheckComment
Definition: FileCheck.h:58
llvm::Pattern::MatchResult::TheMatch
Optional< Match > TheMatch
Definition: FileCheckImpl.h:739
llvm::Pattern::VariableProperties
Parsing information about a variable.
Definition: FileCheckImpl.h:699
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:821
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:877
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