LLVM  16.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(":"))) {
1067  SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
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()) {
1090  SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
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)
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  if (&A == &B)
1428  return false;
1429  assert(A.Range.Start != B.Range.Start &&
1430  "unexpected overlapping variable captures");
1431  return A.Range.Start.getPointer() < B.Range.Start.getPointer();
1432  });
1433  // Create notes for the sorted captures.
1434  for (const VarCapture &VC : VarCaptures) {
1437  OS << "captured var \"" << VC.Name << "\"";
1438  if (Diags)
1439  Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, VC.Range, OS.str());
1440  else
1441  SM.PrintMessage(VC.Range.Start, SourceMgr::DK_Note, OS.str(), VC.Range);
1442  }
1443 }
1444 
1445 static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
1446  const SourceMgr &SM, SMLoc Loc,
1447  Check::FileCheckType CheckTy,
1448  StringRef Buffer, size_t Pos, size_t Len,
1449  std::vector<FileCheckDiag> *Diags,
1450  bool AdjustPrevDiags = false) {
1451  SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos);
1452  SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len);
1453  SMRange Range(Start, End);
1454  if (Diags) {
1455  if (AdjustPrevDiags) {
1456  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
1457  for (auto I = Diags->rbegin(), E = Diags->rend();
1458  I != E && I->CheckLoc == CheckLoc; ++I)
1459  I->MatchTy = MatchTy;
1460  } else
1461  Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range);
1462  }
1463  return Range;
1464 }
1465 
1466 void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
1467  std::vector<FileCheckDiag> *Diags) const {
1468  // Attempt to find the closest/best fuzzy match. Usually an error happens
1469  // because some string in the output didn't exactly match. In these cases, we
1470  // would like to show the user a best guess at what "should have" matched, to
1471  // save them having to actually check the input manually.
1472  size_t NumLinesForward = 0;
1473  size_t Best = StringRef::npos;
1474  double BestQuality = 0;
1475 
1476  // Use an arbitrary 4k limit on how far we will search.
1477  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
1478  if (Buffer[i] == '\n')
1479  ++NumLinesForward;
1480 
1481  // Patterns have leading whitespace stripped, so skip whitespace when
1482  // looking for something which looks like a pattern.
1483  if (Buffer[i] == ' ' || Buffer[i] == '\t')
1484  continue;
1485 
1486  // Compute the "quality" of this match as an arbitrary combination of the
1487  // match distance and the number of lines skipped to get to this match.
1488  unsigned Distance = computeMatchDistance(Buffer.substr(i));
1489  double Quality = Distance + (NumLinesForward / 100.);
1490 
1491  if (Quality < BestQuality || Best == StringRef::npos) {
1492  Best = i;
1493  BestQuality = Quality;
1494  }
1495  }
1496 
1497  // Print the "possible intended match here" line if we found something
1498  // reasonable and not equal to what we showed in the "scanning from here"
1499  // line.
1500  if (Best && Best != StringRef::npos && BestQuality < 50) {
1501  SMRange MatchRange =
1502  ProcessMatchResult(FileCheckDiag::MatchFuzzy, SM, getLoc(),
1503  getCheckTy(), Buffer, Best, 0, Diags);
1504  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note,
1505  "possible intended match here");
1506 
1507  // FIXME: If we wanted to be really friendly we would show why the match
1508  // failed, as it can be hard to spot simple one character differences.
1509  }
1510 }
1511 
1514  auto VarIter = GlobalVariableTable.find(VarName);
1515  if (VarIter == GlobalVariableTable.end())
1516  return make_error<UndefVarError>(VarName);
1517 
1518  return VarIter->second;
1519 }
1520 
1521 template <class... Types>
1522 NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) {
1523  NumericVariables.push_back(std::make_unique<NumericVariable>(args...));
1524  return NumericVariables.back().get();
1525 }
1526 
1527 Substitution *
1528 FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
1529  size_t InsertIdx) {
1530  Substitutions.push_back(
1531  std::make_unique<StringSubstitution>(this, VarName, InsertIdx));
1532  return Substitutions.back().get();
1533 }
1534 
1535 Substitution *FileCheckPatternContext::makeNumericSubstitution(
1536  StringRef ExpressionStr, std::unique_ptr<Expression> Expression,
1537  size_t InsertIdx) {
1538  Substitutions.push_back(std::make_unique<NumericSubstitution>(
1539  this, ExpressionStr, std::move(Expression), InsertIdx));
1540  return Substitutions.back().get();
1541 }
1542 
1543 size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
1544  // Offset keeps track of the current offset within the input Str
1545  size_t Offset = 0;
1546  // [...] Nesting depth
1547  size_t BracketDepth = 0;
1548 
1549  while (!Str.empty()) {
1550  if (Str.startswith("]]") && BracketDepth == 0)
1551  return Offset;
1552  if (Str[0] == '\\') {
1553  // Backslash escapes the next char within regexes, so skip them both.
1554  Str = Str.substr(2);
1555  Offset += 2;
1556  } else {
1557  switch (Str[0]) {
1558  default:
1559  break;
1560  case '[':
1561  BracketDepth++;
1562  break;
1563  case ']':
1564  if (BracketDepth == 0) {
1565  SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
1567  "missing closing \"]\" for regex variable");
1568  exit(1);
1569  }
1570  BracketDepth--;
1571  break;
1572  }
1573  Str = Str.substr(1);
1574  Offset++;
1575  }
1576  }
1577 
1578  return StringRef::npos;
1579 }
1580 
1582  SmallVectorImpl<char> &OutputBuffer) {
1583  OutputBuffer.reserve(MB.getBufferSize());
1584 
1585  for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
1586  Ptr != End; ++Ptr) {
1587  // Eliminate trailing dosish \r.
1588  if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
1589  continue;
1590  }
1591 
1592  // If current char is not a horizontal whitespace or if horizontal
1593  // whitespace canonicalization is disabled, dump it to output as is.
1594  if (Req.NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) {
1595  OutputBuffer.push_back(*Ptr);
1596  continue;
1597  }
1598 
1599  // Otherwise, add one space and advance over neighboring space.
1600  OutputBuffer.push_back(' ');
1601  while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
1602  ++Ptr;
1603  }
1604 
1605  // Add a null byte and then return all but that byte.
1606  OutputBuffer.push_back('\0');
1607  return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
1608 }
1609 
1611  const Check::FileCheckType &CheckTy,
1612  SMLoc CheckLoc, MatchType MatchTy,
1613  SMRange InputRange, StringRef Note)
1614  : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy), Note(Note) {
1615  auto Start = SM.getLineAndColumn(InputRange.Start);
1616  auto End = SM.getLineAndColumn(InputRange.End);
1617  InputStartLine = Start.first;
1618  InputStartCol = Start.second;
1619  InputEndLine = End.first;
1620  InputEndCol = End.second;
1621 }
1622 
1623 static bool IsPartOfWord(char c) {
1624  return (isAlnum(c) || c == '-' || c == '_');
1625 }
1626 
1628  assert(Count > 0 && "zero and negative counts are not supported");
1629  assert((C == 1 || Kind == CheckPlain) &&
1630  "count supported only for plain CHECK directives");
1631  Count = C;
1632  return *this;
1633 }
1634 
1636  if (Modifiers.none())
1637  return "";
1638  std::string Ret;
1639  raw_string_ostream OS(Ret);
1640  OS << '{';
1641  if (isLiteralMatch())
1642  OS << "LITERAL";
1643  OS << '}';
1644  return OS.str();
1645 }
1646 
1648  // Append directive modifiers.
1649  auto WithModifiers = [this, Prefix](StringRef Str) -> std::string {
1650  return (Prefix + Str + getModifiersDescription()).str();
1651  };
1652 
1653  switch (Kind) {
1654  case Check::CheckNone:
1655  return "invalid";
1657  return "misspelled";
1658  case Check::CheckPlain:
1659  if (Count > 1)
1660  return WithModifiers("-COUNT");
1661  return WithModifiers("");
1662  case Check::CheckNext:
1663  return WithModifiers("-NEXT");
1664  case Check::CheckSame:
1665  return WithModifiers("-SAME");
1666  case Check::CheckNot:
1667  return WithModifiers("-NOT");
1668  case Check::CheckDAG:
1669  return WithModifiers("-DAG");
1670  case Check::CheckLabel:
1671  return WithModifiers("-LABEL");
1672  case Check::CheckEmpty:
1673  return WithModifiers("-EMPTY");
1674  case Check::CheckComment:
1675  return std::string(Prefix);
1676  case Check::CheckEOF:
1677  return "implicit EOF";
1678  case Check::CheckBadNot:
1679  return "bad NOT";
1680  case Check::CheckBadCount:
1681  return "bad COUNT";
1682  }
1683  llvm_unreachable("unknown FileCheckType");
1684 }
1685 
1686 static std::pair<Check::FileCheckType, StringRef>
1687 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix,
1688  bool &Misspelled) {
1689  if (Buffer.size() <= Prefix.size())
1690  return {Check::CheckNone, StringRef()};
1691 
1692  StringRef Rest = Buffer.drop_front(Prefix.size());
1693  // Check for comment.
1695  if (Rest.consume_front(":"))
1696  return {Check::CheckComment, Rest};
1697  // Ignore a comment prefix if it has a suffix like "-NOT".
1698  return {Check::CheckNone, StringRef()};
1699  }
1700 
1701  auto ConsumeModifiers = [&](Check::FileCheckType Ret)
1702  -> std::pair<Check::FileCheckType, StringRef> {
1703  if (Rest.consume_front(":"))
1704  return {Ret, Rest};
1705  if (!Rest.consume_front("{"))
1706  return {Check::CheckNone, StringRef()};
1707 
1708  // Parse the modifiers, speparated by commas.
1709  do {
1710  // Allow whitespace in modifiers list.
1711  Rest = Rest.ltrim();
1712  if (Rest.consume_front("LITERAL"))
1713  Ret.setLiteralMatch();
1714  else
1715  return {Check::CheckNone, Rest};
1716  // Allow whitespace in modifiers list.
1717  Rest = Rest.ltrim();
1718  } while (Rest.consume_front(","));
1719  if (!Rest.consume_front("}:"))
1720  return {Check::CheckNone, Rest};
1721  return {Ret, Rest};
1722  };
1723 
1724  // Verify that the prefix is followed by directive modifiers or a colon.
1725  if (Rest.consume_front(":"))
1726  return {Check::CheckPlain, Rest};
1727  if (Rest.front() == '{')
1728  return ConsumeModifiers(Check::CheckPlain);
1729 
1730  if (Rest.consume_front("_"))
1731  Misspelled = true;
1732  else if (!Rest.consume_front("-"))
1733  return {Check::CheckNone, StringRef()};
1734 
1735  if (Rest.consume_front("COUNT-")) {
1736  int64_t Count;
1737  if (Rest.consumeInteger(10, Count))
1738  // Error happened in parsing integer.
1739  return {Check::CheckBadCount, Rest};
1740  if (Count <= 0 || Count > INT32_MAX)
1741  return {Check::CheckBadCount, Rest};
1742  if (Rest.front() != ':' && Rest.front() != '{')
1743  return {Check::CheckBadCount, Rest};
1744  return ConsumeModifiers(
1745  Check::FileCheckType(Check::CheckPlain).setCount(Count));
1746  }
1747 
1748  // You can't combine -NOT with another suffix.
1749  if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
1750  Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
1751  Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") ||
1752  Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:"))
1753  return {Check::CheckBadNot, Rest};
1754 
1755  if (Rest.consume_front("NEXT"))
1756  return ConsumeModifiers(Check::CheckNext);
1757 
1758  if (Rest.consume_front("SAME"))
1759  return ConsumeModifiers(Check::CheckSame);
1760 
1761  if (Rest.consume_front("NOT"))
1762  return ConsumeModifiers(Check::CheckNot);
1763 
1764  if (Rest.consume_front("DAG"))
1765  return ConsumeModifiers(Check::CheckDAG);
1766 
1767  if (Rest.consume_front("LABEL"))
1768  return ConsumeModifiers(Check::CheckLabel);
1769 
1770  if (Rest.consume_front("EMPTY"))
1771  return ConsumeModifiers(Check::CheckEmpty);
1772 
1773  return {Check::CheckNone, Rest};
1774 }
1775 
1776 static std::pair<Check::FileCheckType, StringRef>
1777 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix) {
1778  bool Misspelled = false;
1779  auto Res = FindCheckType(Req, Buffer, Prefix, Misspelled);
1780  if (Res.first != Check::CheckNone && Misspelled)
1781  return {Check::CheckMisspelled, Res.second};
1782  return Res;
1783 }
1784 
1785 // From the given position, find the next character after the word.
1786 static size_t SkipWord(StringRef Str, size_t Loc) {
1787  while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
1788  ++Loc;
1789  return Loc;
1790 }
1791 
1792 /// Searches the buffer for the first prefix in the prefix regular expression.
1793 ///
1794 /// This searches the buffer using the provided regular expression, however it
1795 /// enforces constraints beyond that:
1796 /// 1) The found prefix must not be a suffix of something that looks like
1797 /// a valid prefix.
1798 /// 2) The found prefix must be followed by a valid check type suffix using \c
1799 /// FindCheckType above.
1800 ///
1801 /// \returns a pair of StringRefs into the Buffer, which combines:
1802 /// - the first match of the regular expression to satisfy these two is
1803 /// returned,
1804 /// otherwise an empty StringRef is returned to indicate failure.
1805 /// - buffer rewound to the location right after parsed suffix, for parsing
1806 /// to continue from
1807 ///
1808 /// If this routine returns a valid prefix, it will also shrink \p Buffer to
1809 /// start at the beginning of the returned prefix, increment \p LineNumber for
1810 /// each new line consumed from \p Buffer, and set \p CheckTy to the type of
1811 /// check found by examining the suffix.
1812 ///
1813 /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
1814 /// is unspecified.
1815 static std::pair<StringRef, StringRef>
1816 FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE,
1817  StringRef &Buffer, unsigned &LineNumber,
1818  Check::FileCheckType &CheckTy) {
1819  SmallVector<StringRef, 2> Matches;
1820 
1821  while (!Buffer.empty()) {
1822  // Find the first (longest) match using the RE.
1823  if (!PrefixRE.match(Buffer, &Matches))
1824  // No match at all, bail.
1825  return {StringRef(), StringRef()};
1826 
1827  StringRef Prefix = Matches[0];
1828  Matches.clear();
1829 
1830  assert(Prefix.data() >= Buffer.data() &&
1831  Prefix.data() < Buffer.data() + Buffer.size() &&
1832  "Prefix doesn't start inside of buffer!");
1833  size_t Loc = Prefix.data() - Buffer.data();
1834  StringRef Skipped = Buffer.substr(0, Loc);
1835  Buffer = Buffer.drop_front(Loc);
1836  LineNumber += Skipped.count('\n');
1837 
1838  // Check that the matched prefix isn't a suffix of some other check-like
1839  // word.
1840  // FIXME: This is a very ad-hoc check. it would be better handled in some
1841  // other way. Among other things it seems hard to distinguish between
1842  // intentional and unintentional uses of this feature.
1843  if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
1844  // Now extract the type.
1845  StringRef AfterSuffix;
1846  std::tie(CheckTy, AfterSuffix) = FindCheckType(Req, Buffer, Prefix);
1847 
1848  // If we've found a valid check type for this prefix, we're done.
1849  if (CheckTy != Check::CheckNone)
1850  return {Prefix, AfterSuffix};
1851  }
1852 
1853  // If we didn't successfully find a prefix, we need to skip this invalid
1854  // prefix and continue scanning. We directly skip the prefix that was
1855  // matched and any additional parts of that check-like word.
1856  Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size()));
1857  }
1858 
1859  // We ran out of buffer while skipping partial matches so give up.
1860  return {StringRef(), StringRef()};
1861 }
1862 
1864  assert(!LineVariable && "@LINE pseudo numeric variable already created");
1865  StringRef LineName = "@LINE";
1866  LineVariable = makeNumericVariable(
1868  GlobalNumericVariableTable[LineName] = LineVariable;
1869 }
1870 
1872  : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()),
1873  CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {}
1874 
1875 FileCheck::~FileCheck() = default;
1876 
1878  SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
1879  std::pair<unsigned, unsigned> *ImpPatBufferIDRange) {
1880  if (ImpPatBufferIDRange)
1881  ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0;
1882 
1883  Error DefineError =
1884  PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM);
1885  if (DefineError) {
1886  logAllUnhandledErrors(std::move(DefineError), errs());
1887  return true;
1888  }
1889 
1890  PatternContext->createLineVariable();
1891 
1892  std::vector<Pattern> ImplicitNegativeChecks;
1893  for (StringRef PatternString : Req.ImplicitCheckNot) {
1894  // Create a buffer with fake command line content in order to display the
1895  // command line option responsible for the specific implicit CHECK-NOT.
1896  std::string Prefix = "-implicit-check-not='";
1897  std::string Suffix = "'";
1898  std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
1899  (Prefix + PatternString + Suffix).str(), "command line");
1900 
1901  StringRef PatternInBuffer =
1902  CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
1903  unsigned BufferID = SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
1904  if (ImpPatBufferIDRange) {
1905  if (ImpPatBufferIDRange->first == ImpPatBufferIDRange->second) {
1906  ImpPatBufferIDRange->first = BufferID;
1907  ImpPatBufferIDRange->second = BufferID + 1;
1908  } else {
1909  assert(BufferID == ImpPatBufferIDRange->second &&
1910  "expected consecutive source buffer IDs");
1911  ++ImpPatBufferIDRange->second;
1912  }
1913  }
1914 
1915  ImplicitNegativeChecks.push_back(
1916  Pattern(Check::CheckNot, PatternContext.get()));
1917  ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
1918  "IMPLICIT-CHECK", SM, Req);
1919  }
1920 
1921  std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
1922 
1923  // LineNumber keeps track of the line on which CheckPrefix instances are
1924  // found.
1925  unsigned LineNumber = 1;
1926 
1927  std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(),
1928  Req.CheckPrefixes.end());
1929  const size_t DistinctPrefixes = PrefixesNotFound.size();
1930  while (true) {
1931  Check::FileCheckType CheckTy;
1932 
1933  // See if a prefix occurs in the memory buffer.
1934  StringRef UsedPrefix;
1935  StringRef AfterSuffix;
1936  std::tie(UsedPrefix, AfterSuffix) =
1937  FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy);
1938  if (UsedPrefix.empty())
1939  break;
1940  if (CheckTy != Check::CheckComment)
1941  PrefixesNotFound.erase(UsedPrefix);
1942 
1943  assert(UsedPrefix.data() == Buffer.data() &&
1944  "Failed to move Buffer's start forward, or pointed prefix outside "
1945  "of the buffer!");
1946  assert(AfterSuffix.data() >= Buffer.data() &&
1947  AfterSuffix.data() < Buffer.data() + Buffer.size() &&
1948  "Parsing after suffix doesn't start inside of buffer!");
1949 
1950  // Location to use for error messages.
1951  const char *UsedPrefixStart = UsedPrefix.data();
1952 
1953  // Skip the buffer to the end of parsed suffix (or just prefix, if no good
1954  // suffix was processed).
1955  Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size())
1956  : AfterSuffix;
1957 
1958  // Complain about misspelled directives.
1959  if (CheckTy == Check::CheckMisspelled) {
1960  StringRef UsedDirective(UsedPrefix.data(),
1961  AfterSuffix.data() - UsedPrefix.data());
1962  SM.PrintMessage(SMLoc::getFromPointer(UsedDirective.data()),
1964  "misspelled directive '" + UsedDirective + "'");
1965  return true;
1966  }
1967 
1968  // Complain about useful-looking but unsupported suffixes.
1969  if (CheckTy == Check::CheckBadNot) {
1971  "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
1972  return true;
1973  }
1974 
1975  // Complain about invalid count specification.
1976  if (CheckTy == Check::CheckBadCount) {
1978  "invalid count in -COUNT specification on prefix '" +
1979  UsedPrefix + "'");
1980  return true;
1981  }
1982 
1983  // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
1984  // leading whitespace.
1985  if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
1986  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
1987 
1988  // Scan ahead to the end of line.
1989  size_t EOL = Buffer.find_first_of("\n\r");
1990 
1991  // Remember the location of the start of the pattern, for diagnostics.
1992  SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
1993 
1994  // Extract the pattern from the buffer.
1995  StringRef PatternBuffer = Buffer.substr(0, EOL);
1996  Buffer = Buffer.substr(EOL);
1997 
1998  // If this is a comment, we're done.
1999  if (CheckTy == Check::CheckComment)
2000  continue;
2001 
2002  // Parse the pattern.
2003  Pattern P(CheckTy, PatternContext.get(), LineNumber);
2004  if (P.parsePattern(PatternBuffer, UsedPrefix, SM, Req))
2005  return true;
2006 
2007  // Verify that CHECK-LABEL lines do not define or use variables
2008  if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
2009  SM.PrintMessage(
2010  SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
2011  "found '" + UsedPrefix + "-LABEL:'"
2012  " with variable definition or use");
2013  return true;
2014  }
2015 
2016  // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
2017  if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
2018  CheckTy == Check::CheckEmpty) &&
2019  CheckStrings->empty()) {
2020  StringRef Type = CheckTy == Check::CheckNext
2021  ? "NEXT"
2022  : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
2023  SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
2025  "found '" + UsedPrefix + "-" + Type +
2026  "' without previous '" + UsedPrefix + ": line");
2027  return true;
2028  }
2029 
2030  // Handle CHECK-DAG/-NOT.
2031  if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
2032  DagNotMatches.push_back(P);
2033  continue;
2034  }
2035 
2036  // Okay, add the string we captured to the output vector and move on.
2037  CheckStrings->emplace_back(P, UsedPrefix, PatternLoc);
2038  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2039  DagNotMatches = ImplicitNegativeChecks;
2040  }
2041 
2042  // When there are no used prefixes we report an error except in the case that
2043  // no prefix is specified explicitly but -implicit-check-not is specified.
2044  const bool NoPrefixesFound = PrefixesNotFound.size() == DistinctPrefixes;
2045  const bool SomePrefixesUnexpectedlyNotUsed =
2046  !Req.AllowUnusedPrefixes && !PrefixesNotFound.empty();
2047  if ((NoPrefixesFound || SomePrefixesUnexpectedlyNotUsed) &&
2048  (ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) {
2049  errs() << "error: no check strings found with prefix"
2050  << (PrefixesNotFound.size() > 1 ? "es " : " ");
2051  bool First = true;
2052  for (StringRef MissingPrefix : PrefixesNotFound) {
2053  if (!First)
2054  errs() << ", ";
2055  errs() << "\'" << MissingPrefix << ":'";
2056  First = false;
2057  }
2058  errs() << '\n';
2059  return true;
2060  }
2061 
2062  // Add an EOF pattern for any trailing --implicit-check-not/CHECK-DAG/-NOTs,
2063  // and use the first prefix as a filler for the error message.
2064  if (!DagNotMatches.empty()) {
2065  CheckStrings->emplace_back(
2066  Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
2067  *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
2068  std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
2069  }
2070 
2071  return false;
2072 }
2073 
2074 /// Returns either (1) \c ErrorSuccess if there was no error or (2)
2075 /// \c ErrorReported if an error was reported, such as an unexpected match.
2076 static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
2077  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2078  int MatchedCount, StringRef Buffer,
2079  Pattern::MatchResult MatchResult,
2080  const FileCheckRequest &Req,
2081  std::vector<FileCheckDiag> *Diags) {
2082  // Suppress some verbosity if there's no error.
2083  bool HasError = !ExpectedMatch || MatchResult.TheError;
2084  bool PrintDiag = true;
2085  if (!HasError) {
2086  if (!Req.Verbose)
2087  return ErrorReported::reportedOrSuccess(HasError);
2088  if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF)
2089  return ErrorReported::reportedOrSuccess(HasError);
2090  // Due to their verbosity, we don't print verbose diagnostics here if we're
2091  // gathering them for Diags to be rendered elsewhere, but we always print
2092  // other diagnostics.
2093  PrintDiag = !Diags;
2094  }
2095 
2096  // Add "found" diagnostic, substitutions, and variable definitions to Diags.
2097  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2100  SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2101  Buffer, MatchResult.TheMatch->Pos,
2102  MatchResult.TheMatch->Len, Diags);
2103  if (Diags) {
2104  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags);
2105  Pat.printVariableDefs(SM, MatchTy, Diags);
2106  }
2107  if (!PrintDiag) {
2108  assert(!HasError && "expected to report more diagnostics for error");
2109  return ErrorReported::reportedOrSuccess(HasError);
2110  }
2111 
2112  // Print the match.
2113  std::string Message = formatv("{0}: {1} string found in input",
2115  (ExpectedMatch ? "expected" : "excluded"))
2116  .str();
2117  if (Pat.getCount() > 1)
2118  Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2119  SM.PrintMessage(
2120  Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message);
2121  SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here",
2122  {MatchRange});
2123 
2124  // Print additional information, which can be useful even if there are errors.
2125  Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, nullptr);
2126  Pat.printVariableDefs(SM, MatchTy, nullptr);
2127 
2128  // Print errors and add them to Diags. We report these errors after the match
2129  // itself because we found them after the match. If we had found them before
2130  // the match, we'd be in printNoMatch.
2131  handleAllErrors(std::move(MatchResult.TheError),
2132  [&](const ErrorDiagnostic &E) {
2133  E.log(errs());
2134  if (Diags) {
2135  Diags->emplace_back(SM, Pat.getCheckTy(), Loc,
2136  FileCheckDiag::MatchFoundErrorNote,
2137  E.getRange(), E.getMessage().str());
2138  }
2139  });
2140  return ErrorReported::reportedOrSuccess(HasError);
2141 }
2142 
2143 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2144 /// \c ErrorReported if an error was reported, such as an expected match not
2145 /// found.
2146 static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM,
2147  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2148  int MatchedCount, StringRef Buffer, Error MatchError,
2149  bool VerboseVerbose,
2150  std::vector<FileCheckDiag> *Diags) {
2151  // Print any pattern errors, and record them to be added to Diags later.
2152  bool HasError = ExpectedMatch;
2153  bool HasPatternError = false;
2154  FileCheckDiag::MatchType MatchTy = ExpectedMatch
2155  ? FileCheckDiag::MatchNoneButExpected
2156  : FileCheckDiag::MatchNoneAndExcluded;
2157  SmallVector<std::string, 4> ErrorMsgs;
2159  std::move(MatchError),
2160  [&](const ErrorDiagnostic &E) {
2161  HasError = HasPatternError = true;
2162  MatchTy = FileCheckDiag::MatchNoneForInvalidPattern;
2163  E.log(errs());
2164  if (Diags)
2165  ErrorMsgs.push_back(E.getMessage().str());
2166  },
2167  // NotFoundError is why printNoMatch was invoked.
2168  [](const NotFoundError &E) {});
2169 
2170  // Suppress some verbosity if there's no error.
2171  bool PrintDiag = true;
2172  if (!HasError) {
2173  if (!VerboseVerbose)
2174  return ErrorReported::reportedOrSuccess(HasError);
2175  // Due to their verbosity, we don't print verbose diagnostics here if we're
2176  // gathering them for Diags to be rendered elsewhere, but we always print
2177  // other diagnostics.
2178  PrintDiag = !Diags;
2179  }
2180 
2181  // Add "not found" diagnostic, substitutions, and pattern errors to Diags.
2182  //
2183  // We handle Diags a little differently than the errors we print directly:
2184  // we add the "not found" diagnostic to Diags even if there are pattern
2185  // errors. The reason is that we need to attach pattern errors as notes
2186  // somewhere in the input, and the input search range from the "not found"
2187  // diagnostic is all we have to anchor them.
2188  SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
2189  Buffer, 0, Buffer.size(), Diags);
2190  if (Diags) {
2191  SMRange NoteRange = SMRange(SearchRange.Start, SearchRange.Start);
2192  for (StringRef ErrorMsg : ErrorMsgs)
2193  Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, NoteRange,
2194  ErrorMsg);
2195  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, Diags);
2196  }
2197  if (!PrintDiag) {
2198  assert(!HasError && "expected to report more diagnostics for error");
2199  return ErrorReported::reportedOrSuccess(HasError);
2200  }
2201 
2202  // Print "not found" diagnostic, except that's implied if we already printed a
2203  // pattern error.
2204  if (!HasPatternError) {
2205  std::string Message = formatv("{0}: {1} string not found in input",
2207  (ExpectedMatch ? "expected" : "excluded"))
2208  .str();
2209  if (Pat.getCount() > 1)
2210  Message +=
2211  formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str();
2212  SM.PrintMessage(Loc,
2213  ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark,
2214  Message);
2215  SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note,
2216  "scanning from here");
2217  }
2218 
2219  // Print additional information, which can be useful even after a pattern
2220  // error.
2221  Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, nullptr);
2222  if (ExpectedMatch)
2223  Pat.printFuzzyMatch(SM, Buffer, Diags);
2224  return ErrorReported::reportedOrSuccess(HasError);
2225 }
2226 
2227 /// Returns either (1) \c ErrorSuccess if there was no error, or (2)
2228 /// \c ErrorReported if an error was reported.
2229 static Error reportMatchResult(bool ExpectedMatch, const SourceMgr &SM,
2230  StringRef Prefix, SMLoc Loc, const Pattern &Pat,
2231  int MatchedCount, StringRef Buffer,
2232  Pattern::MatchResult MatchResult,
2233  const FileCheckRequest &Req,
2234  std::vector<FileCheckDiag> *Diags) {
2235  if (MatchResult.TheMatch)
2236  return printMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2237  std::move(MatchResult), Req, Diags);
2238  return printNoMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
2239  std::move(MatchResult.TheError), Req.VerboseVerbose,
2240  Diags);
2241 }
2242 
2243 /// Counts the number of newlines in the specified range.
2244 static unsigned CountNumNewlinesBetween(StringRef Range,
2245  const char *&FirstNewLine) {
2246  unsigned NumNewLines = 0;
2247  while (true) {
2248  // Scan for newline.
2249  Range = Range.substr(Range.find_first_of("\n\r"));
2250  if (Range.empty())
2251  return NumNewLines;
2252 
2253  ++NumNewLines;
2254 
2255  // Handle \n\r and \r\n as a single newline.
2256  if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
2257  (Range[0] != Range[1]))
2258  Range = Range.substr(1);
2259  Range = Range.substr(1);
2260 
2261  if (NumNewLines == 1)
2262  FirstNewLine = Range.begin();
2263  }
2264 }
2265 
2266 size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
2267  bool IsLabelScanMode, size_t &MatchLen,
2268  FileCheckRequest &Req,
2269  std::vector<FileCheckDiag> *Diags) const {
2270  size_t LastPos = 0;
2271  std::vector<const Pattern *> NotStrings;
2272 
2273  // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
2274  // bounds; we have not processed variable definitions within the bounded block
2275  // yet so cannot handle any final CHECK-DAG yet; this is handled when going
2276  // over the block again (including the last CHECK-LABEL) in normal mode.
2277  if (!IsLabelScanMode) {
2278  // Match "dag strings" (with mixed "not strings" if any).
2279  LastPos = CheckDag(SM, Buffer, NotStrings, Req, Diags);
2280  if (LastPos == StringRef::npos)
2281  return StringRef::npos;
2282  }
2283 
2284  // Match itself from the last position after matching CHECK-DAG.
2285  size_t LastMatchEnd = LastPos;
2286  size_t FirstMatchPos = 0;
2287  // Go match the pattern Count times. Majority of patterns only match with
2288  // count 1 though.
2289  assert(Pat.getCount() != 0 && "pattern count can not be zero");
2290  for (int i = 1; i <= Pat.getCount(); i++) {
2291  StringRef MatchBuffer = Buffer.substr(LastMatchEnd);
2292  // get a match at current start point
2293  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2294 
2295  // report
2296  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix, Loc,
2297  Pat, i, MatchBuffer,
2298  std::move(MatchResult), Req, Diags)) {
2299  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2300  return StringRef::npos;
2301  }
2302 
2303  size_t MatchPos = MatchResult.TheMatch->Pos;
2304  if (i == 1)
2305  FirstMatchPos = LastPos + MatchPos;
2306 
2307  // move start point after the match
2308  LastMatchEnd += MatchPos + MatchResult.TheMatch->Len;
2309  }
2310  // Full match len counts from first match pos.
2311  MatchLen = LastMatchEnd - FirstMatchPos;
2312 
2313  // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
2314  // or CHECK-NOT
2315  if (!IsLabelScanMode) {
2316  size_t MatchPos = FirstMatchPos - LastPos;
2317  StringRef MatchBuffer = Buffer.substr(LastPos);
2318  StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
2319 
2320  // If this check is a "CHECK-NEXT", verify that the previous match was on
2321  // the previous line (i.e. that there is one newline between them).
2322  if (CheckNext(SM, SkippedRegion)) {
2323  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2324  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2325  Diags, Req.Verbose);
2326  return StringRef::npos;
2327  }
2328 
2329  // If this check is a "CHECK-SAME", verify that the previous match was on
2330  // the same line (i.e. that there is no newline between them).
2331  if (CheckSame(SM, SkippedRegion)) {
2332  ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
2333  Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
2334  Diags, Req.Verbose);
2335  return StringRef::npos;
2336  }
2337 
2338  // If this match had "not strings", verify that they don't exist in the
2339  // skipped region.
2340  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2341  return StringRef::npos;
2342  }
2343 
2344  return FirstMatchPos;
2345 }
2346 
2347 bool FileCheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
2348  if (Pat.getCheckTy() != Check::CheckNext &&
2350  return false;
2351 
2352  Twine CheckName =
2353  Prefix +
2354  Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT");
2355 
2356  // Count the number of newlines between the previous match and this one.
2357  const char *FirstNewLine = nullptr;
2358  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2359 
2360  if (NumNewLines == 0) {
2362  CheckName + ": is on the same line as previous match");
2364  "'next' match was here");
2366  "previous match ended here");
2367  return true;
2368  }
2369 
2370  if (NumNewLines != 1) {
2372  CheckName +
2373  ": is not on the line after the previous match");
2375  "'next' match was here");
2377  "previous match ended here");
2379  "non-matching line after previous match is here");
2380  return true;
2381  }
2382 
2383  return false;
2384 }
2385 
2386 bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
2387  if (Pat.getCheckTy() != Check::CheckSame)
2388  return false;
2389 
2390  // Count the number of newlines between the previous match and this one.
2391  const char *FirstNewLine = nullptr;
2392  unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
2393 
2394  if (NumNewLines != 0) {
2396  Prefix +
2397  "-SAME: is not on the same line as the previous match");
2399  "'next' match was here");
2401  "previous match ended here");
2402  return true;
2403  }
2404 
2405  return false;
2406 }
2407 
2408 bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
2409  const std::vector<const Pattern *> &NotStrings,
2410  const FileCheckRequest &Req,
2411  std::vector<FileCheckDiag> *Diags) const {
2412  bool DirectiveFail = false;
2413  for (const Pattern *Pat : NotStrings) {
2414  assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
2415  Pattern::MatchResult MatchResult = Pat->match(Buffer, SM);
2416  if (Error Err = reportMatchResult(/*ExpectedMatch=*/false, SM, Prefix,
2417  Pat->getLoc(), *Pat, 1, Buffer,
2418  std::move(MatchResult), Req, Diags)) {
2419  cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2420  DirectiveFail = true;
2421  continue;
2422  }
2423  }
2424  return DirectiveFail;
2425 }
2426 
2427 size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
2428  std::vector<const Pattern *> &NotStrings,
2429  const FileCheckRequest &Req,
2430  std::vector<FileCheckDiag> *Diags) const {
2431  if (DagNotStrings.empty())
2432  return 0;
2433 
2434  // The start of the search range.
2435  size_t StartPos = 0;
2436 
2437  struct MatchRange {
2438  size_t Pos;
2439  size_t End;
2440  };
2441  // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match
2442  // ranges are erased from this list once they are no longer in the search
2443  // range.
2444  std::list<MatchRange> MatchRanges;
2445 
2446  // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG
2447  // group, so we don't use a range-based for loop here.
2448  for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end();
2449  PatItr != PatEnd; ++PatItr) {
2450  const Pattern &Pat = *PatItr;
2452  Pat.getCheckTy() == Check::CheckNot) &&
2453  "Invalid CHECK-DAG or CHECK-NOT!");
2454 
2455  if (Pat.getCheckTy() == Check::CheckNot) {
2456  NotStrings.push_back(&Pat);
2457  continue;
2458  }
2459 
2460  assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
2461 
2462  // CHECK-DAG always matches from the start.
2463  size_t MatchLen = 0, MatchPos = StartPos;
2464 
2465  // Search for a match that doesn't overlap a previous match in this
2466  // CHECK-DAG group.
2467  for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) {
2468  StringRef MatchBuffer = Buffer.substr(MatchPos);
2469  Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM);
2470  // With a group of CHECK-DAGs, a single mismatching means the match on
2471  // that group of CHECK-DAGs fails immediately.
2472  if (MatchResult.TheError || Req.VerboseVerbose) {
2473  if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix,
2474  Pat.getLoc(), Pat, 1, MatchBuffer,
2475  std::move(MatchResult), Req, Diags)) {
2476  cantFail(
2477  handleErrors(std::move(Err), [&](const ErrorReported &E) {}));
2478  return StringRef::npos;
2479  }
2480  }
2481  MatchLen = MatchResult.TheMatch->Len;
2482  // Re-calc it as the offset relative to the start of the original
2483  // string.
2484  MatchPos += MatchResult.TheMatch->Pos;
2485  MatchRange M{MatchPos, MatchPos + MatchLen};
2486  if (Req.AllowDeprecatedDagOverlap) {
2487  // We don't need to track all matches in this mode, so we just maintain
2488  // one match range that encompasses the current CHECK-DAG group's
2489  // matches.
2490  if (MatchRanges.empty())
2491  MatchRanges.insert(MatchRanges.end(), M);
2492  else {
2493  auto Block = MatchRanges.begin();
2494  Block->Pos = std::min(Block->Pos, M.Pos);
2495  Block->End = std::max(Block->End, M.End);
2496  }
2497  break;
2498  }
2499  // Iterate previous matches until overlapping match or insertion point.
2500  bool Overlap = false;
2501  for (; MI != ME; ++MI) {
2502  if (M.Pos < MI->End) {
2503  // !Overlap => New match has no overlap and is before this old match.
2504  // Overlap => New match overlaps this old match.
2505  Overlap = MI->Pos < M.End;
2506  break;
2507  }
2508  }
2509  if (!Overlap) {
2510  // Insert non-overlapping match into list.
2511  MatchRanges.insert(MI, M);
2512  break;
2513  }
2514  if (Req.VerboseVerbose) {
2515  // Due to their verbosity, we don't print verbose diagnostics here if
2516  // we're gathering them for a different rendering, but we always print
2517  // other diagnostics.
2518  if (!Diags) {
2519  SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos);
2520  SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End);
2521  SMRange OldRange(OldStart, OldEnd);
2522  SM.PrintMessage(OldStart, SourceMgr::DK_Note,
2523  "match discarded, overlaps earlier DAG match here",
2524  {OldRange});
2525  } else {
2526  SMLoc CheckLoc = Diags->rbegin()->CheckLoc;
2527  for (auto I = Diags->rbegin(), E = Diags->rend();
2528  I != E && I->CheckLoc == CheckLoc; ++I)
2530  }
2531  }
2532  MatchPos = MI->End;
2533  }
2534  if (!Req.VerboseVerbose)
2535  cantFail(printMatch(
2536  /*ExpectedMatch=*/true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer,
2537  Pattern::MatchResult(MatchPos, MatchLen, Error::success()), Req,
2538  Diags));
2539 
2540  // Handle the end of a CHECK-DAG group.
2541  if (std::next(PatItr) == PatEnd ||
2542  std::next(PatItr)->getCheckTy() == Check::CheckNot) {
2543  if (!NotStrings.empty()) {
2544  // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to
2545  // CHECK-DAG, verify that there are no 'not' strings occurred in that
2546  // region.
2547  StringRef SkippedRegion =
2548  Buffer.slice(StartPos, MatchRanges.begin()->Pos);
2549  if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags))
2550  return StringRef::npos;
2551  // Clear "not strings".
2552  NotStrings.clear();
2553  }
2554  // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the
2555  // end of this CHECK-DAG group's match range.
2556  StartPos = MatchRanges.rbegin()->End;
2557  // Don't waste time checking for (impossible) overlaps before that.
2558  MatchRanges.clear();
2559  }
2560  }
2561 
2562  return StartPos;
2563 }
2564 
2565 static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes,
2566  ArrayRef<StringRef> SuppliedPrefixes) {
2567  for (StringRef Prefix : SuppliedPrefixes) {
2568  if (Prefix.empty()) {
2569  errs() << "error: supplied " << Kind << " prefix must not be the empty "
2570  << "string\n";
2571  return false;
2572  }
2573  static const Regex Validator("^[a-zA-Z0-9_-]*$");
2574  if (!Validator.match(Prefix)) {
2575  errs() << "error: supplied " << Kind << " prefix must start with a "
2576  << "letter and contain only alphanumeric characters, hyphens, and "
2577  << "underscores: '" << Prefix << "'\n";
2578  return false;
2579  }
2580  if (!UniquePrefixes.insert(Prefix).second) {
2581  errs() << "error: supplied " << Kind << " prefix must be unique among "
2582  << "check and comment prefixes: '" << Prefix << "'\n";
2583  return false;
2584  }
2585  }
2586  return true;
2587 }
2588 
2589 static const char *DefaultCheckPrefixes[] = {"CHECK"};
2590 static const char *DefaultCommentPrefixes[] = {"COM", "RUN"};
2591 
2593  StringSet<> UniquePrefixes;
2594  // Add default prefixes to catch user-supplied duplicates of them below.
2595  if (Req.CheckPrefixes.empty()) {
2596  for (const char *Prefix : DefaultCheckPrefixes)
2597  UniquePrefixes.insert(Prefix);
2598  }
2599  if (Req.CommentPrefixes.empty()) {
2600  for (const char *Prefix : DefaultCommentPrefixes)
2601  UniquePrefixes.insert(Prefix);
2602  }
2603  // Do not validate the default prefixes, or diagnostics about duplicates might
2604  // incorrectly indicate that they were supplied by the user.
2605  if (!ValidatePrefixes("check", UniquePrefixes, Req.CheckPrefixes))
2606  return false;
2607  if (!ValidatePrefixes("comment", UniquePrefixes, Req.CommentPrefixes))
2608  return false;
2609  return true;
2610 }
2611 
2613  if (Req.CheckPrefixes.empty()) {
2614  for (const char *Prefix : DefaultCheckPrefixes)
2615  Req.CheckPrefixes.push_back(Prefix);
2616  Req.IsDefaultCheckPrefix = true;
2617  }
2618  if (Req.CommentPrefixes.empty()) {
2619  for (const char *Prefix : DefaultCommentPrefixes)
2620  Req.CommentPrefixes.push_back(Prefix);
2621  }
2622 
2623  // We already validated the contents of CheckPrefixes and CommentPrefixes so
2624  // just concatenate them as alternatives.
2625  SmallString<32> PrefixRegexStr;
2626  for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) {
2627  if (I != 0)
2628  PrefixRegexStr.push_back('|');
2629  PrefixRegexStr.append(Req.CheckPrefixes[I]);
2630  }
2631  for (StringRef Prefix : Req.CommentPrefixes) {
2632  PrefixRegexStr.push_back('|');
2633  PrefixRegexStr.append(Prefix);
2634  }
2635 
2636  return Regex(PrefixRegexStr);
2637 }
2638 
2640  ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM) {
2641  assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() &&
2642  "Overriding defined variable with command-line variable definitions");
2643 
2644  if (CmdlineDefines.empty())
2645  return Error::success();
2646 
2647  // Create a string representing the vector of command-line definitions. Each
2648  // definition is on its own line and prefixed with a definition number to
2649  // clarify which definition a given diagnostic corresponds to.
2650  unsigned I = 0;
2651  Error Errs = Error::success();
2652  std::string CmdlineDefsDiag;
2653  SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices;
2654  for (StringRef CmdlineDef : CmdlineDefines) {
2655  std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str();
2656  size_t EqIdx = CmdlineDef.find('=');
2657  if (EqIdx == StringRef::npos) {
2658  CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0));
2659  continue;
2660  }
2661  // Numeric variable definition.
2662  if (CmdlineDef[0] == '#') {
2663  // Append a copy of the command-line definition adapted to use the same
2664  // format as in the input file to be able to reuse
2665  // parseNumericSubstitutionBlock.
2666  CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str();
2667  std::string SubstitutionStr = std::string(CmdlineDef);
2668  SubstitutionStr[EqIdx] = ':';
2669  CmdlineDefsIndices.push_back(
2670  std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size()));
2671  CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str();
2672  } else {
2673  CmdlineDefsDiag += DefPrefix;
2674  CmdlineDefsIndices.push_back(
2675  std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size()));
2676  CmdlineDefsDiag += (CmdlineDef + "\n").str();
2677  }
2678  }
2679 
2680  // Create a buffer with fake command line content in order to display
2681  // parsing diagnostic with location information and point to the
2682  // global definition with invalid syntax.
2683  std::unique_ptr<MemoryBuffer> CmdLineDefsDiagBuffer =
2684  MemoryBuffer::getMemBufferCopy(CmdlineDefsDiag, "Global defines");
2685  StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer();
2686  SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc());
2687 
2688  for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) {
2689  StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first,
2690  CmdlineDefIndices.second);
2691  if (CmdlineDef.empty()) {
2692  Errs = joinErrors(
2693  std::move(Errs),
2694  ErrorDiagnostic::get(SM, CmdlineDef,
2695  "missing equal sign in global definition"));
2696  continue;
2697  }
2698 
2699  // Numeric variable definition.
2700  if (CmdlineDef[0] == '#') {
2701  // Now parse the definition both to check that the syntax is correct and
2702  // to create the necessary class instance.
2703  StringRef CmdlineDefExpr = CmdlineDef.substr(1);
2704  Optional<NumericVariable *> DefinedNumericVariable;
2705  Expected<std::unique_ptr<Expression>> ExpressionResult =
2707  CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM);
2708  if (!ExpressionResult) {
2709  Errs = joinErrors(std::move(Errs), ExpressionResult.takeError());
2710  continue;
2711  }
2712  std::unique_ptr<Expression> Expression = std::move(*ExpressionResult);
2713  // Now evaluate the expression whose value this variable should be set
2714  // to, since the expression of a command-line variable definition should
2715  // only use variables defined earlier on the command-line. If not, this
2716  // is an error and we report it.
2718  if (!Value) {
2719  Errs = joinErrors(std::move(Errs), Value.takeError());
2720  continue;
2721  }
2722 
2723  assert(DefinedNumericVariable && "No variable defined");
2724  (*DefinedNumericVariable)->setValue(*Value);
2725 
2726  // Record this variable definition.
2727  GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] =
2728  *DefinedNumericVariable;
2729  } else {
2730  // String variable definition.
2731  std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
2732  StringRef CmdlineName = CmdlineNameVal.first;
2733  StringRef OrigCmdlineName = CmdlineName;
2734  Expected<Pattern::VariableProperties> ParseVarResult =
2735  Pattern::parseVariable(CmdlineName, SM);
2736  if (!ParseVarResult) {
2737  Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
2738  continue;
2739  }
2740  // Check that CmdlineName does not denote a pseudo variable is only
2741  // composed of the parsed numeric variable. This catches cases like
2742  // "FOO+2" in a "FOO+2=10" definition.
2743  if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
2744  Errs = joinErrors(std::move(Errs),
2746  SM, OrigCmdlineName,
2747  "invalid name in string variable definition '" +
2748  OrigCmdlineName + "'"));
2749  continue;
2750  }
2751  StringRef Name = ParseVarResult->Name;
2752 
2753  // Detect collisions between string and numeric variables when the former
2754  // is created later than the latter.
2755  if (GlobalNumericVariableTable.find(Name) !=
2756  GlobalNumericVariableTable.end()) {
2757  Errs = joinErrors(std::move(Errs),
2758  ErrorDiagnostic::get(SM, Name,
2759  "numeric variable with name '" +
2760  Name + "' already exists"));
2761  continue;
2762  }
2763  GlobalVariableTable.insert(CmdlineNameVal);
2764  // Mark the string variable as defined to detect collisions between
2765  // string and numeric variables in defineCmdlineVariables when the latter
2766  // is created later than the former. We cannot reuse GlobalVariableTable
2767  // for this by populating it with an empty string since we would then
2768  // lose the ability to detect the use of an undefined variable in
2769  // match().
2770  DefinedVariableTable[Name] = true;
2771  }
2772  }
2773 
2774  return Errs;
2775 }
2776 
2778  SmallVector<StringRef, 16> LocalPatternVars, LocalNumericVars;
2779  for (const StringMapEntry<StringRef> &Var : GlobalVariableTable)
2780  if (Var.first()[0] != '$')
2781  LocalPatternVars.push_back(Var.first());
2782 
2783  // Numeric substitution reads the value of a variable directly, not via
2784  // GlobalNumericVariableTable. Therefore, we clear local variables by
2785  // clearing their value which will lead to a numeric substitution failure. We
2786  // also mark the variable for removal from GlobalNumericVariableTable since
2787  // this is what defineCmdlineVariables checks to decide that no global
2788  // variable has been defined.
2789  for (const auto &Var : GlobalNumericVariableTable)
2790  if (Var.first()[0] != '$') {
2791  Var.getValue()->clearValue();
2792  LocalNumericVars.push_back(Var.first());
2793  }
2794 
2795  for (const auto &Var : LocalPatternVars)
2796  GlobalVariableTable.erase(Var);
2797  for (const auto &Var : LocalNumericVars)
2798  GlobalNumericVariableTable.erase(Var);
2799 }
2800 
2801 bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
2802  std::vector<FileCheckDiag> *Diags) {
2803  bool ChecksFailed = false;
2804 
2805  unsigned i = 0, j = 0, e = CheckStrings->size();
2806  while (true) {
2807  StringRef CheckRegion;
2808  if (j == e) {
2809  CheckRegion = Buffer;
2810  } else {
2811  const FileCheckString &CheckLabelStr = (*CheckStrings)[j];
2812  if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
2813  ++j;
2814  continue;
2815  }
2816 
2817  // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
2818  size_t MatchLabelLen = 0;
2819  size_t MatchLabelPos =
2820  CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, Req, Diags);
2821  if (MatchLabelPos == StringRef::npos)
2822  // Immediately bail if CHECK-LABEL fails, nothing else we can do.
2823  return false;
2824 
2825  CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
2826  Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
2827  ++j;
2828  }
2829 
2830  // Do not clear the first region as it's the one before the first
2831  // CHECK-LABEL and it would clear variables defined on the command-line
2832  // before they get used.
2833  if (i != 0 && Req.EnableVarScope)
2834  PatternContext->clearLocalVars();
2835 
2836  for (; i != j; ++i) {
2837  const FileCheckString &CheckStr = (*CheckStrings)[i];
2838 
2839  // Check each string within the scanned region, including a second check
2840  // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
2841  size_t MatchLen = 0;
2842  size_t MatchPos =
2843  CheckStr.Check(SM, CheckRegion, false, MatchLen, Req, Diags);
2844 
2845  if (MatchPos == StringRef::npos) {
2846  ChecksFailed = true;
2847  i = j;
2848  break;
2849  }
2850 
2851  CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
2852  }
2853 
2854  if (j == e)
2855  break;
2856  }
2857 
2858  // Success if no checks failed.
2859  return !ChecksFailed;
2860 }
FileCheck.h
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
llvm::ExpressionValue::ExpressionValue
ExpressionValue(T Val)
Definition: FileCheckImpl.h:128
i
i
Definition: README.txt:29
llvm::ExpressionValue
Class representing a numeric value.
Definition: FileCheckImpl.h:121
llvm::SMRange::Start
SMLoc Start
Definition: SMLoc.h:50
llvm::StringRef::take_front
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:572
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:108
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:18
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:942
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:102
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:161
llvm::FileCheckRequest::IsDefaultCheckPrefix
bool IsDefaultCheckPrefix
Definition: FileCheck.h:40
llvm::StringRef::consumeInteger
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:503
llvm::StringRef::trim
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:807
llvm::StringRef::front
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
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::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:629
llvm::FileCheckRequest::Verbose
bool Verbose
Definition: FileCheck.h:43
llvm::Check::CheckSame
@ CheckSame
Definition: FileCheck.h:54
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:57
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:52
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
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
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:627
llvm::tgtok::VarName
@ VarName
Definition: TGLexer.h:72
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::StringRef::find_first_of
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:381
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::StringRef::substr
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:564
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::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
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::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:1042
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:159
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
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
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:845
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::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:260
llvm::ExpressionFormat
Type representing the format an expression value should be textualized into for matching.
Definition: FileCheckImpl.h:39
CheckedArithmetic.h
llvm::MemoryBuffer::getBufferEnd
const char * getBufferEnd() const
Definition: MemoryBuffer.h:67
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::FileCheck::ValidateCheckPrefixes
bool ValidateCheckPrefixes()
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition: MemoryBuffer.h:68
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
llvm::operator/
InstructionCost operator/(const InstructionCost &LHS, const InstructionCost &RHS)
Definition: InstructionCost.h:274
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:132
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:55
llvm::UndefVarError
Class to represent an undefined variable error, which quotes that variable's name when printed.
Definition: FileCheckImpl.h:215
llvm::ExpressionValue::getSignedValue
Expected< int64_t > getSignedValue() const
Definition: FileCheck.cpp:170
llvm::operator-
APInt operator-(APInt)
Definition: APInt.h:2087
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::StringRef::data
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
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:137
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::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 >
llvm::StringRef::slice
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:676
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::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1657
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
llvm::FileCheckDiag::MatchType
MatchType
What type of match result does this diagnostic describe?
Definition: FileCheck.h:130
llvm::ExpressionAST::eval
virtual Expected< ExpressionValue > eval() const =0
Evaluates and.
llvm::Check::FileCheckType
Definition: FileCheck.h:80
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:53
llvm::Check::CheckMisspelled
@ CheckMisspelled
Definition: FileCheck.h:51
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
uint64_t
llvm::FileCheckDiag::MatchFoundButExcluded
@ MatchFoundButExcluded
Indicates a match for an excluded pattern.
Definition: FileCheck.h:134
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:113
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:53
llvm::StringRef::rtrim
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:795
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::StringRef::ltrim
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:783
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:1843
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h: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.
Ptr
@ Ptr
Definition: TargetLibraryInfo.cpp:60
llvm::StringRef::find_first_not_of
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:260
llvm::Check::CheckBadCount
@ CheckBadCount
Marks when parsing found a -COUNT directive with invalid count value.
Definition: FileCheck.h:69
llvm::operator+
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2092
llvm::Pattern::MatchResult::TheError
Error TheError
Definition: FileCheckImpl.h:740
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:66
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:2134
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::logicalview::LVCompareKind::Types
@ Types
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::logicalview::LVAttributeKind::Range
@ Range
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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:744
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:159
llvm::Regex::IgnoreCase
@ IgnoreCase
Compile for matching that ignores upper/lower case distinctions.
Definition: Regex.h:33
llvm::ExpressionValue::getUnsignedValue
Expected< uint64_t > getUnsignedValue() const
Definition: FileCheck.cpp:181
llvm::StringRef::count
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:455
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:63
llvm::tgtok::StrVal
@ StrVal
Definition: TGLexer.h:72
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
StringSet.h
j
return j(j<< 16)
llvm::Pattern::printFuzzyMatch
void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, std::vector< FileCheckDiag > *Diags) const
llvm::FileCheckRequest::EnableVarScope
bool EnableVarScope
Definition: FileCheck.h:41
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::Check::CheckDAG
@ CheckDAG
Definition: FileCheck.h:56
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:1238
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:66
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
llvm::Check::CheckEmpty
@ CheckEmpty
Definition: FileCheck.h:58
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::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:614
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:139
llvm::StringRef::contains
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:428
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:596
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:52
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::Pattern::printVariableDefs
void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy, std::vector< FileCheckDiag > *Diags) const
llvm::StringRef::back
char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:659
llvm::SmallVectorImpl< char >
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:183
llvm::StringRef::find_insensitive
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:45
llvm::Pattern::getLoc
SMLoc getLoc() const
Definition: FileCheckImpl.h:689
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
llvm::StringRef::find
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:294
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::omp::RTLDependInfoFields::Flags
@ Flags
llvm::StringRef::edit_distance
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::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:96
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:140
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:667
llvm::Substitution::getFromString
StringRef getFromString() const
Definition: FileCheckImpl.h:413
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:965
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
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:63
llvm::Check::CheckComment
@ CheckComment
Definition: FileCheck.h:59
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:601
llvm::Pattern::MatchResult::TheMatch
Optional< Match > TheMatch
Definition: FileCheckImpl.h:739
llvm::StringRef::drop_back
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Definition: StringRef.h:608
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:735
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