1 //===-- FileCheckImpl.h - Private FileCheck Interface ------------*- C++ -*-==//
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 // This file defines the private interfaces of FileCheck. Its purpose is to
10 // allow unit testing of FileCheck and to separate the interface from the
11 // implementation. It is only meant to be used by FileCheck.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_FILECHECK_FILECHECKIMPL_H
16 #define LLVM_LIB_FILECHECK_FILECHECKIMPL_H
17 
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/FileCheck/FileCheck.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/SourceMgr.h"
24 #include <map>
25 #include <string>
26 #include <vector>
27 
28 namespace llvm {
29 
30 //===----------------------------------------------------------------------===//
31 // Numeric substitution handling code.
32 //===----------------------------------------------------------------------===//
33 
34 class ExpressionValue;
35 
36 /// Type representing the format an expression value should be textualized into
37 /// for matching. Used to represent both explicit format specifiers as well as
38 /// implicit format from using numeric variables.
39 struct ExpressionFormat {
40   enum class Kind {
41     /// Denote absence of format. Used for implicit format of literals and
42     /// empty expressions.
43     NoFormat,
44     /// Value is an unsigned integer and should be printed as a decimal number.
45     Unsigned,
46     /// Value is a signed integer and should be printed as a decimal number.
47     Signed,
48     /// Value should be printed as an uppercase hex number.
49     HexUpper,
50     /// Value should be printed as a lowercase hex number.
51     HexLower
52   };
53 
54 private:
55   Kind Value;
56   unsigned Precision = 0;
57 
58 public:
59   /// Evaluates a format to true if it can be used in a match.
60   explicit operator bool() const { return Value != Kind::NoFormat; }
61 
62   /// Define format equality: formats are equal if neither is NoFormat and
63   /// their kinds and precision are the same.
64   bool operator==(const ExpressionFormat &Other) const {
65     return Value != Kind::NoFormat && Value == Other.Value &&
66            Precision == Other.Precision;
67   }
68 
69   bool operator!=(const ExpressionFormat &Other) const {
70     return !(*this == Other);
71   }
72 
73   bool operator==(Kind OtherValue) const { return Value == OtherValue; }
74 
75   bool operator!=(Kind OtherValue) const { return !(*this == OtherValue); }
76 
77   /// \returns the format specifier corresponding to this format as a string.
78   StringRef toString() const;
79 
80   ExpressionFormat() : Value(Kind::NoFormat){};
81   explicit ExpressionFormat(Kind Value) : Value(Value), Precision(0){};
82   explicit ExpressionFormat(Kind Value, unsigned Precision)
83       : Value(Value), Precision(Precision){};
84 
85   /// \returns a wildcard regular expression string that matches any value in
86   /// the format represented by this instance and no other value, or an error
87   /// if the format is NoFormat.
88   Expected<std::string> getWildcardRegex() const;
89 
90   /// \returns the string representation of \p Value in the format represented
91   /// by this instance, or an error if conversion to this format failed or the
92   /// format is NoFormat.
93   Expected<std::string> getMatchingString(ExpressionValue Value) const;
94 
95   /// \returns the value corresponding to string representation \p StrVal
96   /// according to the matching format represented by this instance or an error
97   /// with diagnostic against \p SM if \p StrVal does not correspond to a valid
98   /// and representable value.
99   Expected<ExpressionValue> valueFromStringRepr(StringRef StrVal,
100                                                 const SourceMgr &SM) const;
101 };
102 
103 /// Class to represent an overflow error that might result when manipulating a
104 /// value.
105 class OverflowError : public ErrorInfo<OverflowError> {
106 public:
107   static char ID;
108 
109   std::error_code convertToErrorCode() const override {
110     return std::make_error_code(std::errc::value_too_large);
111   }
112 
113   void log(raw_ostream &OS) const override { OS << "overflow error"; }
114 };
115 
116 /// Class representing a numeric value.
117 class ExpressionValue {
118 private:
119   uint64_t Value;
120   bool Negative;
121 
122 public:
123   template <class T>
124   explicit ExpressionValue(T Val) : Value(Val), Negative(Val < 0) {}
125 
126   bool operator==(const ExpressionValue &Other) const {
127     return Value == Other.Value && isNegative() == Other.isNegative();
128   }
129 
130   bool operator!=(const ExpressionValue &Other) const {
131     return !(*this == Other);
132   }
133 
134   /// Returns true if value is signed and negative, false otherwise.
135   bool isNegative() const {
136     assert((Value != 0 || !Negative) && "Unexpected negative zero!");
137     return Negative;
138   }
139 
140   /// \returns the value as a signed integer or an error if the value is out of
141   /// range.
142   Expected<int64_t> getSignedValue() const;
143 
144   /// \returns the value as an unsigned integer or an error if the value is out
145   /// of range.
146   Expected<uint64_t> getUnsignedValue() const;
147 
148   /// \returns an unsigned ExpressionValue instance whose value is the absolute
149   /// value to this object's value.
150   ExpressionValue getAbsolute() const;
151 };
152 
153 /// Performs operation and \returns its result or an error in case of failure,
154 /// such as if an overflow occurs.
155 Expected<ExpressionValue> operator+(const ExpressionValue &Lhs,
156                                     const ExpressionValue &Rhs);
157 Expected<ExpressionValue> operator-(const ExpressionValue &Lhs,
158                                     const ExpressionValue &Rhs);
159 Expected<ExpressionValue> operator*(const ExpressionValue &Lhs,
160                                     const ExpressionValue &Rhs);
161 Expected<ExpressionValue> operator/(const ExpressionValue &Lhs,
162                                     const ExpressionValue &Rhs);
163 Expected<ExpressionValue> max(const ExpressionValue &Lhs,
164                               const ExpressionValue &Rhs);
165 Expected<ExpressionValue> min(const ExpressionValue &Lhs,
166                               const ExpressionValue &Rhs);
167 
168 /// Base class representing the AST of a given expression.
169 class ExpressionAST {
170 private:
171   StringRef ExpressionStr;
172 
173 public:
174   ExpressionAST(StringRef ExpressionStr) : ExpressionStr(ExpressionStr) {}
175 
176   virtual ~ExpressionAST() = default;
177 
178   StringRef getExpressionStr() const { return ExpressionStr; }
179 
180   /// Evaluates and \returns the value of the expression represented by this
181   /// AST or an error if evaluation fails.
182   virtual Expected<ExpressionValue> eval() const = 0;
183 
184   /// \returns either the implicit format of this AST, a diagnostic against
185   /// \p SM if implicit formats of the AST's components conflict, or NoFormat
186   /// if the AST has no implicit format (e.g. AST is made up of a single
187   /// literal).
188   virtual Expected<ExpressionFormat>
189   getImplicitFormat(const SourceMgr &SM) const {
190     return ExpressionFormat();
191   }
192 };
193 
194 /// Class representing an unsigned literal in the AST of an expression.
195 class ExpressionLiteral : public ExpressionAST {
196 private:
197   /// Actual value of the literal.
198   ExpressionValue Value;
199 
200 public:
201   template <class T>
202   explicit ExpressionLiteral(StringRef ExpressionStr, T Val)
203       : ExpressionAST(ExpressionStr), Value(Val) {}
204 
205   /// \returns the literal's value.
206   Expected<ExpressionValue> eval() const override { return Value; }
207 };
208 
209 /// Class to represent an undefined variable error, which quotes that
210 /// variable's name when printed.
211 class UndefVarError : public ErrorInfo<UndefVarError> {
212 private:
213   StringRef VarName;
214 
215 public:
216   static char ID;
217 
218   UndefVarError(StringRef VarName) : VarName(VarName) {}
219 
220   StringRef getVarName() const { return VarName; }
221 
222   std::error_code convertToErrorCode() const override {
223     return inconvertibleErrorCode();
224   }
225 
226   /// Print name of variable associated with this error.
227   void log(raw_ostream &OS) const override {
228     OS << "\"";
229     OS.write_escaped(VarName) << "\"";
230   }
231 };
232 
233 /// Class representing an expression and its matching format.
234 class Expression {
235 private:
236   /// Pointer to AST of the expression.
237   std::unique_ptr<ExpressionAST> AST;
238 
239   /// Format to use (e.g. hex upper case letters) when matching the value.
240   ExpressionFormat Format;
241 
242 public:
243   /// Generic constructor for an expression represented by the given \p AST and
244   /// whose matching format is \p Format.
245   Expression(std::unique_ptr<ExpressionAST> AST, ExpressionFormat Format)
246       : AST(std::move(AST)), Format(Format) {}
247 
248   /// \returns pointer to AST of the expression. Pointer is guaranteed to be
249   /// valid as long as this object is.
250   ExpressionAST *getAST() const { return AST.get(); }
251 
252   ExpressionFormat getFormat() const { return Format; }
253 };
254 
255 /// Class representing a numeric variable and its associated current value.
256 class NumericVariable {
257 private:
258   /// Name of the numeric variable.
259   StringRef Name;
260 
261   /// Format to use for expressions using this variable without an explicit
262   /// format.
263   ExpressionFormat ImplicitFormat;
264 
265   /// Value of numeric variable, if defined, or None otherwise.
266   Optional<ExpressionValue> Value;
267 
268   /// The input buffer's string from which Value was parsed, or None.  See
269   /// comments on getStringValue for a discussion of the None case.
270   Optional<StringRef> StrValue;
271 
272   /// Line number where this variable is defined, or None if defined before
273   /// input is parsed. Used to determine whether a variable is defined on the
274   /// same line as a given use.
275   Optional<size_t> DefLineNumber;
276 
277 public:
278   /// Constructor for a variable \p Name with implicit format \p ImplicitFormat
279   /// defined at line \p DefLineNumber or defined before input is parsed if
280   /// \p DefLineNumber is None.
281   explicit NumericVariable(StringRef Name, ExpressionFormat ImplicitFormat,
282                            Optional<size_t> DefLineNumber = None)
283       : Name(Name), ImplicitFormat(ImplicitFormat),
284         DefLineNumber(DefLineNumber) {}
285 
286   /// \returns name of this numeric variable.
287   StringRef getName() const { return Name; }
288 
289   /// \returns implicit format of this numeric variable.
290   ExpressionFormat getImplicitFormat() const { return ImplicitFormat; }
291 
292   /// \returns this variable's value.
293   Optional<ExpressionValue> getValue() const { return Value; }
294 
295   /// \returns the input buffer's string from which this variable's value was
296   /// parsed, or None if the value is not yet defined or was not parsed from the
297   /// input buffer.  For example, the value of @LINE is not parsed from the
298   /// input buffer, and some numeric variables are parsed from the command
299   /// line instead.
300   Optional<StringRef> getStringValue() const { return StrValue; }
301 
302   /// Sets value of this numeric variable to \p NewValue, and sets the input
303   /// buffer string from which it was parsed to \p NewStrValue.  See comments on
304   /// getStringValue for a discussion of when the latter can be None.
305   void setValue(ExpressionValue NewValue,
306                 Optional<StringRef> NewStrValue = None) {
307     Value = NewValue;
308     StrValue = NewStrValue;
309   }
310 
311   /// Clears value of this numeric variable, regardless of whether it is
312   /// currently defined or not.
313   void clearValue() {
314     Value = None;
315     StrValue = None;
316   }
317 
318   /// \returns the line number where this variable is defined, if any, or None
319   /// if defined before input is parsed.
320   Optional<size_t> getDefLineNumber() const { return DefLineNumber; }
321 };
322 
323 /// Class representing the use of a numeric variable in the AST of an
324 /// expression.
325 class NumericVariableUse : public ExpressionAST {
326 private:
327   /// Pointer to the class instance for the variable this use is about.
328   NumericVariable *Variable;
329 
330 public:
331   NumericVariableUse(StringRef Name, NumericVariable *Variable)
332       : ExpressionAST(Name), Variable(Variable) {}
333   /// \returns the value of the variable referenced by this instance.
334   Expected<ExpressionValue> eval() const override;
335 
336   /// \returns implicit format of this numeric variable.
337   Expected<ExpressionFormat>
338   getImplicitFormat(const SourceMgr &SM) const override {
339     return Variable->getImplicitFormat();
340   }
341 };
342 
343 /// Type of functions evaluating a given binary operation.
344 using binop_eval_t = Expected<ExpressionValue> (*)(const ExpressionValue &,
345                                                    const ExpressionValue &);
346 
347 /// Class representing a single binary operation in the AST of an expression.
348 class BinaryOperation : public ExpressionAST {
349 private:
350   /// Left operand.
351   std::unique_ptr<ExpressionAST> LeftOperand;
352 
353   /// Right operand.
354   std::unique_ptr<ExpressionAST> RightOperand;
355 
356   /// Pointer to function that can evaluate this binary operation.
357   binop_eval_t EvalBinop;
358 
359 public:
360   BinaryOperation(StringRef ExpressionStr, binop_eval_t EvalBinop,
361                   std::unique_ptr<ExpressionAST> LeftOp,
362                   std::unique_ptr<ExpressionAST> RightOp)
363       : ExpressionAST(ExpressionStr), EvalBinop(EvalBinop) {
364     LeftOperand = std::move(LeftOp);
365     RightOperand = std::move(RightOp);
366   }
367 
368   /// Evaluates the value of the binary operation represented by this AST,
369   /// using EvalBinop on the result of recursively evaluating the operands.
370   /// \returns the expression value or an error if an undefined numeric
371   /// variable is used in one of the operands.
372   Expected<ExpressionValue> eval() const override;
373 
374   /// \returns the implicit format of this AST, if any, a diagnostic against
375   /// \p SM if the implicit formats of the AST's components conflict, or no
376   /// format if the AST has no implicit format (e.g. AST is made of a single
377   /// literal).
378   Expected<ExpressionFormat>
379   getImplicitFormat(const SourceMgr &SM) const override;
380 };
381 
382 class FileCheckPatternContext;
383 
384 /// Class representing a substitution to perform in the RegExStr string.
385 class Substitution {
386 protected:
387   /// Pointer to a class instance holding, among other things, the table with
388   /// the values of live string variables at the start of any given CHECK line.
389   /// Used for substituting string variables with the text they were defined
390   /// as. Expressions are linked to the numeric variables they use at
391   /// parse time and directly access the value of the numeric variable to
392   /// evaluate their value.
393   FileCheckPatternContext *Context;
394 
395   /// The string that needs to be substituted for something else. For a
396   /// string variable this is its name, otherwise this is the whole expression.
397   StringRef FromStr;
398 
399   // Index in RegExStr of where to do the substitution.
400   size_t InsertIdx;
401 
402 public:
403   Substitution(FileCheckPatternContext *Context, StringRef VarName,
404                size_t InsertIdx)
405       : Context(Context), FromStr(VarName), InsertIdx(InsertIdx) {}
406 
407   virtual ~Substitution() = default;
408 
409   /// \returns the string to be substituted for something else.
410   StringRef getFromString() const { return FromStr; }
411 
412   /// \returns the index where the substitution is to be performed in RegExStr.
413   size_t getIndex() const { return InsertIdx; }
414 
415   /// \returns a string containing the result of the substitution represented
416   /// by this class instance or an error if substitution failed.
417   virtual Expected<std::string> getResult() const = 0;
418 };
419 
420 class StringSubstitution : public Substitution {
421 public:
422   StringSubstitution(FileCheckPatternContext *Context, StringRef VarName,
423                      size_t InsertIdx)
424       : Substitution(Context, VarName, InsertIdx) {}
425 
426   /// \returns the text that the string variable in this substitution matched
427   /// when defined, or an error if the variable is undefined.
428   Expected<std::string> getResult() const override;
429 };
430 
431 class NumericSubstitution : public Substitution {
432 private:
433   /// Pointer to the class representing the expression whose value is to be
434   /// substituted.
435   std::unique_ptr<Expression> ExpressionPointer;
436 
437 public:
438   NumericSubstitution(FileCheckPatternContext *Context, StringRef ExpressionStr,
439                       std::unique_ptr<Expression> ExpressionPointer,
440                       size_t InsertIdx)
441       : Substitution(Context, ExpressionStr, InsertIdx),
442         ExpressionPointer(std::move(ExpressionPointer)) {}
443 
444   /// \returns a string containing the result of evaluating the expression in
445   /// this substitution, or an error if evaluation failed.
446   Expected<std::string> getResult() const override;
447 };
448 
449 //===----------------------------------------------------------------------===//
450 // Pattern handling code.
451 //===----------------------------------------------------------------------===//
452 
453 /// Class holding the Pattern global state, shared by all patterns: tables
454 /// holding values of variables and whether they are defined or not at any
455 /// given time in the matching process.
456 class FileCheckPatternContext {
457   friend class Pattern;
458 
459 private:
460   /// When matching a given pattern, this holds the value of all the string
461   /// variables defined in previous patterns. In a pattern, only the last
462   /// definition for a given variable is recorded in this table.
463   /// Back-references are used for uses after any the other definition.
464   StringMap<StringRef> GlobalVariableTable;
465 
466   /// Map of all string variables defined so far. Used at parse time to detect
467   /// a name conflict between a numeric variable and a string variable when
468   /// the former is defined on a later line than the latter.
469   StringMap<bool> DefinedVariableTable;
470 
471   /// When matching a given pattern, this holds the pointers to the classes
472   /// representing the numeric variables defined in previous patterns. When
473   /// matching a pattern all definitions for that pattern are recorded in the
474   /// NumericVariableDefs table in the Pattern instance of that pattern.
475   StringMap<NumericVariable *> GlobalNumericVariableTable;
476 
477   /// Pointer to the class instance representing the @LINE pseudo variable for
478   /// easily updating its value.
479   NumericVariable *LineVariable = nullptr;
480 
481   /// Vector holding pointers to all parsed numeric variables. Used to
482   /// automatically free them once they are guaranteed to no longer be used.
483   std::vector<std::unique_ptr<NumericVariable>> NumericVariables;
484 
485   /// Vector holding pointers to all parsed expressions. Used to automatically
486   /// free the expressions once they are guaranteed to no longer be used.
487   std::vector<std::unique_ptr<Expression>> Expressions;
488 
489   /// Vector holding pointers to all substitutions. Used to automatically free
490   /// them once they are guaranteed to no longer be used.
491   std::vector<std::unique_ptr<Substitution>> Substitutions;
492 
493 public:
494   /// \returns the value of string variable \p VarName or an error if no such
495   /// variable has been defined.
496   Expected<StringRef> getPatternVarValue(StringRef VarName);
497 
498   /// Defines string and numeric variables from definitions given on the
499   /// command line, passed as a vector of [#]VAR=VAL strings in
500   /// \p CmdlineDefines. \returns an error list containing diagnostics against
501   /// \p SM for all definition parsing failures, if any, or Success otherwise.
502   Error defineCmdlineVariables(ArrayRef<StringRef> CmdlineDefines,
503                                SourceMgr &SM);
504 
505   /// Create @LINE pseudo variable. Value is set when pattern are being
506   /// matched.
507   void createLineVariable();
508 
509   /// Undefines local variables (variables whose name does not start with a '$'
510   /// sign), i.e. removes them from GlobalVariableTable and from
511   /// GlobalNumericVariableTable and also clears the value of numeric
512   /// variables.
513   void clearLocalVars();
514 
515 private:
516   /// Makes a new numeric variable and registers it for destruction when the
517   /// context is destroyed.
518   template <class... Types> NumericVariable *makeNumericVariable(Types... args);
519 
520   /// Makes a new string substitution and registers it for destruction when the
521   /// context is destroyed.
522   Substitution *makeStringSubstitution(StringRef VarName, size_t InsertIdx);
523 
524   /// Makes a new numeric substitution and registers it for destruction when
525   /// the context is destroyed.
526   Substitution *makeNumericSubstitution(StringRef ExpressionStr,
527                                         std::unique_ptr<Expression> Expression,
528                                         size_t InsertIdx);
529 };
530 
531 /// Class to represent an error holding a diagnostic with location information
532 /// used when printing it.
533 class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> {
534 private:
535   SMDiagnostic Diagnostic;
536 
537 public:
538   static char ID;
539 
540   ErrorDiagnostic(SMDiagnostic &&Diag) : Diagnostic(Diag) {}
541 
542   std::error_code convertToErrorCode() const override {
543     return inconvertibleErrorCode();
544   }
545 
546   /// Print diagnostic associated with this error when printing the error.
547   void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); }
548 
549   static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg) {
550     return make_error<ErrorDiagnostic>(
551         SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg));
552   }
553 
554   static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg) {
555     return get(SM, SMLoc::getFromPointer(Buffer.data()), ErrMsg);
556   }
557 };
558 
559 class NotFoundError : public ErrorInfo<NotFoundError> {
560 public:
561   static char ID;
562 
563   std::error_code convertToErrorCode() const override {
564     return inconvertibleErrorCode();
565   }
566 
567   /// Print diagnostic associated with this error when printing the error.
568   void log(raw_ostream &OS) const override {
569     OS << "String not found in input";
570   }
571 };
572 
573 class Pattern {
574   SMLoc PatternLoc;
575 
576   /// A fixed string to match as the pattern or empty if this pattern requires
577   /// a regex match.
578   StringRef FixedStr;
579 
580   /// A regex string to match as the pattern or empty if this pattern requires
581   /// a fixed string to match.
582   std::string RegExStr;
583 
584   /// Entries in this vector represent a substitution of a string variable or
585   /// an expression in the RegExStr regex at match time. For example, in the
586   /// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
587   /// RegExStr will contain "foobaz" and we'll get two entries in this vector
588   /// that tells us to insert the value of string variable "bar" at offset 3
589   /// and the value of expression "N+1" at offset 6.
590   std::vector<Substitution *> Substitutions;
591 
592   /// Maps names of string variables defined in a pattern to the number of
593   /// their parenthesis group in RegExStr capturing their last definition.
594   ///
595   /// E.g. for the pattern "foo[[bar:.*]]baz([[bar]][[QUUX]][[bar:.*]])",
596   /// RegExStr will be "foo(.*)baz(\1<quux value>(.*))" where <quux value> is
597   /// the value captured for QUUX on the earlier line where it was defined, and
598   /// VariableDefs will map "bar" to the third parenthesis group which captures
599   /// the second definition of "bar".
600   ///
601   /// Note: uses std::map rather than StringMap to be able to get the key when
602   /// iterating over values.
603   std::map<StringRef, unsigned> VariableDefs;
604 
605   /// Structure representing the definition of a numeric variable in a pattern.
606   /// It holds the pointer to the class instance holding the value and matching
607   /// format of the numeric variable whose value is being defined and the
608   /// number of the parenthesis group in RegExStr to capture that value.
609   struct NumericVariableMatch {
610     /// Pointer to class instance holding the value and matching format of the
611     /// numeric variable being defined.
612     NumericVariable *DefinedNumericVariable;
613 
614     /// Number of the parenthesis group in RegExStr that captures the value of
615     /// this numeric variable definition.
616     unsigned CaptureParenGroup;
617   };
618 
619   /// Holds the number of the parenthesis group in RegExStr and pointer to the
620   /// corresponding NumericVariable class instance of all numeric variable
621   /// definitions. Used to set the matched value of all those variables.
622   StringMap<NumericVariableMatch> NumericVariableDefs;
623 
624   /// Pointer to a class instance holding the global state shared by all
625   /// patterns:
626   /// - separate tables with the values of live string and numeric variables
627   ///   respectively at the start of any given CHECK line;
628   /// - table holding whether a string variable has been defined at any given
629   ///   point during the parsing phase.
630   FileCheckPatternContext *Context;
631 
632   Check::FileCheckType CheckTy;
633 
634   /// Line number for this CHECK pattern or None if it is an implicit pattern.
635   /// Used to determine whether a variable definition is made on an earlier
636   /// line to the one with this CHECK.
637   Optional<size_t> LineNumber;
638 
639   /// Ignore case while matching if set to true.
640   bool IgnoreCase = false;
641 
642 public:
643   Pattern(Check::FileCheckType Ty, FileCheckPatternContext *Context,
644           Optional<size_t> Line = None)
645       : Context(Context), CheckTy(Ty), LineNumber(Line) {}
646 
647   /// \returns the location in source code.
648   SMLoc getLoc() const { return PatternLoc; }
649 
650   /// \returns the pointer to the global state for all patterns in this
651   /// FileCheck instance.
652   FileCheckPatternContext *getContext() const { return Context; }
653 
654   /// \returns whether \p C is a valid first character for a variable name.
655   static bool isValidVarNameStart(char C);
656 
657   /// Parsing information about a variable.
658   struct VariableProperties {
659     StringRef Name;
660     bool IsPseudo;
661   };
662 
663   /// Parses the string at the start of \p Str for a variable name. \returns
664   /// a VariableProperties structure holding the variable name and whether it
665   /// is the name of a pseudo variable, or an error holding a diagnostic
666   /// against \p SM if parsing fail. If parsing was successful, also strips
667   /// \p Str from the variable name.
668   static Expected<VariableProperties> parseVariable(StringRef &Str,
669                                                     const SourceMgr &SM);
670   /// Parses \p Expr for a numeric substitution block at line \p LineNumber,
671   /// or before input is parsed if \p LineNumber is None. Parameter
672   /// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
673   /// expression and \p Context points to the class instance holding the live
674   /// string and numeric variables. \returns a pointer to the class instance
675   /// representing the expression whose value must be substitued, or an error
676   /// holding a diagnostic against \p SM if parsing fails. If substitution was
677   /// successful, sets \p DefinedNumericVariable to point to the class
678   /// representing the numeric variable defined in this numeric substitution
679   /// block, or None if this block does not define any variable.
680   static Expected<std::unique_ptr<Expression>> parseNumericSubstitutionBlock(
681       StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable,
682       bool IsLegacyLineExpr, Optional<size_t> LineNumber,
683       FileCheckPatternContext *Context, const SourceMgr &SM);
684   /// Parses the pattern in \p PatternStr and initializes this Pattern instance
685   /// accordingly.
686   ///
687   /// \p Prefix provides which prefix is being matched, \p Req describes the
688   /// global options that influence the parsing such as whitespace
689   /// canonicalization, \p SM provides the SourceMgr used for error reports.
690   /// \returns true in case of an error, false otherwise.
691   bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
692                     const FileCheckRequest &Req);
693   /// Matches the pattern string against the input buffer \p Buffer
694   ///
695   /// \returns the position that is matched or an error indicating why matching
696   /// failed. If there is a match, updates \p MatchLen with the size of the
697   /// matched string.
698   ///
699   /// The GlobalVariableTable StringMap in the FileCheckPatternContext class
700   /// instance provides the current values of FileCheck string variables and is
701   /// updated if this match defines new values. Likewise, the
702   /// GlobalNumericVariableTable StringMap in the same class provides the
703   /// current values of FileCheck numeric variables and is updated if this
704   /// match defines new numeric values.
705   Expected<size_t> match(StringRef Buffer, size_t &MatchLen,
706                          const SourceMgr &SM) const;
707   /// Prints the value of successful substitutions or the name of the undefined
708   /// string or numeric variables preventing a successful substitution.
709   void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
710                           SMRange MatchRange, FileCheckDiag::MatchType MatchTy,
711                           std::vector<FileCheckDiag> *Diags) const;
712   void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
713                        std::vector<FileCheckDiag> *Diags) const;
714 
715   bool hasVariable() const {
716     return !(Substitutions.empty() && VariableDefs.empty());
717   }
718   void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
719                          std::vector<FileCheckDiag> *Diags) const;
720 
721   Check::FileCheckType getCheckTy() const { return CheckTy; }
722 
723   int getCount() const { return CheckTy.getCount(); }
724 
725 private:
726   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
727   void AddBackrefToRegEx(unsigned BackrefNum);
728   /// Computes an arbitrary estimate for the quality of matching this pattern
729   /// at the start of \p Buffer; a distance of zero should correspond to a
730   /// perfect match.
731   unsigned computeMatchDistance(StringRef Buffer) const;
732   /// Finds the closing sequence of a regex variable usage or definition.
733   ///
734   /// \p Str has to point in the beginning of the definition (right after the
735   /// opening sequence). \p SM holds the SourceMgr used for error reporting.
736   ///  \returns the offset of the closing sequence within Str, or npos if it
737   /// was not found.
738   static size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
739 
740   /// Parses \p Expr for the name of a numeric variable to be defined at line
741   /// \p LineNumber, or before input is parsed if \p LineNumber is None.
742   /// \returns a pointer to the class instance representing that variable,
743   /// creating it if needed, or an error holding a diagnostic against \p SM
744   /// should defining such a variable be invalid.
745   static Expected<NumericVariable *> parseNumericVariableDefinition(
746       StringRef &Expr, FileCheckPatternContext *Context,
747       Optional<size_t> LineNumber, ExpressionFormat ImplicitFormat,
748       const SourceMgr &SM);
749   /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
750   /// at line \p LineNumber, or before input is parsed if \p LineNumber is
751   /// None. Parameter \p Context points to the class instance holding the live
752   /// string and numeric variables. \returns the pointer to the class instance
753   /// representing that variable if successful, or an error holding a
754   /// diagnostic against \p SM otherwise.
755   static Expected<std::unique_ptr<NumericVariableUse>> parseNumericVariableUse(
756       StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
757       FileCheckPatternContext *Context, const SourceMgr &SM);
758   enum class AllowedOperand { LineVar, LegacyLiteral, Any };
759   /// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
760   /// before input is parsed if \p LineNumber is None. Accepts literal values,
761   /// numeric variables and function calls, depending on the value of \p AO.
762   /// \p MaybeInvalidConstraint indicates whether the text being parsed could
763   /// be an invalid constraint. \p Context points to the class instance holding
764   /// the live string and numeric variables. \returns the class representing
765   /// that operand in the AST of the expression or an error holding a
766   /// diagnostic against \p SM otherwise. If \p Expr starts with a "(" this
767   /// function will attempt to parse a parenthesized expression.
768   static Expected<std::unique_ptr<ExpressionAST>>
769   parseNumericOperand(StringRef &Expr, AllowedOperand AO, bool ConstraintParsed,
770                       Optional<size_t> LineNumber,
771                       FileCheckPatternContext *Context, const SourceMgr &SM);
772   /// Parses and updates \p RemainingExpr for a binary operation at line
773   /// \p LineNumber, or before input is parsed if \p LineNumber is None. The
774   /// left operand of this binary operation is given in \p LeftOp and \p Expr
775   /// holds the string for the full expression, including the left operand.
776   /// Parameter \p IsLegacyLineExpr indicates whether we are parsing a legacy
777   /// @LINE expression. Parameter \p Context points to the class instance
778   /// holding the live string and numeric variables. \returns the class
779   /// representing the binary operation in the AST of the expression, or an
780   /// error holding a diagnostic against \p SM otherwise.
781   static Expected<std::unique_ptr<ExpressionAST>>
782   parseBinop(StringRef Expr, StringRef &RemainingExpr,
783              std::unique_ptr<ExpressionAST> LeftOp, bool IsLegacyLineExpr,
784              Optional<size_t> LineNumber, FileCheckPatternContext *Context,
785              const SourceMgr &SM);
786 
787   /// Parses a parenthesized expression inside \p Expr at line \p LineNumber, or
788   /// before input is parsed if \p LineNumber is None. \p Expr must start with
789   /// a '('. Accepts both literal values and numeric variables. Parameter \p
790   /// Context points to the class instance holding the live string and numeric
791   /// variables. \returns the class representing that operand in the AST of the
792   /// expression or an error holding a diagnostic against \p SM otherwise.
793   static Expected<std::unique_ptr<ExpressionAST>>
794   parseParenExpr(StringRef &Expr, Optional<size_t> LineNumber,
795                  FileCheckPatternContext *Context, const SourceMgr &SM);
796 
797   /// Parses \p Expr for an argument list belonging to a call to function \p
798   /// FuncName at line \p LineNumber, or before input is parsed if \p LineNumber
799   /// is None. Parameter \p FuncLoc is the source location used for diagnostics.
800   /// Parameter \p Context points to the class instance holding the live string
801   /// and numeric variables. \returns the class representing that call in the
802   /// AST of the expression or an error holding a diagnostic against \p SM
803   /// otherwise.
804   static Expected<std::unique_ptr<ExpressionAST>>
805   parseCallExpr(StringRef &Expr, StringRef FuncName,
806                 Optional<size_t> LineNumber, FileCheckPatternContext *Context,
807                 const SourceMgr &SM);
808 };
809 
810 //===----------------------------------------------------------------------===//
811 // Check Strings.
812 //===----------------------------------------------------------------------===//
813 
814 /// A check that we found in the input file.
815 struct FileCheckString {
816   /// The pattern to match.
817   Pattern Pat;
818 
819   /// Which prefix name this check matched.
820   StringRef Prefix;
821 
822   /// The location in the match file that the check string was specified.
823   SMLoc Loc;
824 
825   /// All of the strings that are disallowed from occurring between this match
826   /// string and the previous one (or start of file).
827   std::vector<Pattern> DagNotStrings;
828 
829   FileCheckString(const Pattern &P, StringRef S, SMLoc L)
830       : Pat(P), Prefix(S), Loc(L) {}
831 
832   /// Matches check string and its "not strings" and/or "dag strings".
833   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
834                size_t &MatchLen, FileCheckRequest &Req,
835                std::vector<FileCheckDiag> *Diags) const;
836 
837   /// Verifies that there is a single line in the given \p Buffer. Errors are
838   /// reported against \p SM.
839   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
840   /// Verifies that there is no newline in the given \p Buffer. Errors are
841   /// reported against \p SM.
842   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
843   /// Verifies that none of the strings in \p NotStrings are found in the given
844   /// \p Buffer. Errors are reported against \p SM and diagnostics recorded in
845   /// \p Diags according to the verbosity level set in \p Req.
846   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
847                 const std::vector<const Pattern *> &NotStrings,
848                 const FileCheckRequest &Req,
849                 std::vector<FileCheckDiag> *Diags) const;
850   /// Matches "dag strings" and their mixed "not strings".
851   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
852                   std::vector<const Pattern *> &NotStrings,
853                   const FileCheckRequest &Req,
854                   std::vector<FileCheckDiag> *Diags) const;
855 };
856 
857 } // namespace llvm
858 
859 #endif
860