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