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