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   SMRange Range;
541 
542 public:
543   static char ID;
544 
545   ErrorDiagnostic(SMDiagnostic &&Diag, SMRange Range)
546       : Diagnostic(Diag), Range(Range) {}
547 
548   std::error_code convertToErrorCode() const override {
549     return inconvertibleErrorCode();
550   }
551 
552   /// Print diagnostic associated with this error when printing the error.
553   void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); }
554 
555   StringRef getMessage() const { return Diagnostic.getMessage(); }
556   SMRange getRange() const { return Range; }
557 
558   static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg,
559                    SMRange Range = None) {
560     return make_error<ErrorDiagnostic>(
561         SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg), Range);
562   }
563 
564   static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg) {
565     SMLoc Start = SMLoc::getFromPointer(Buffer.data());
566     SMLoc End = SMLoc::getFromPointer(Buffer.data() + Buffer.size());
567     return get(SM, Start, ErrMsg, SMRange(Start, End));
568   }
569 };
570 
571 class NotFoundError : public ErrorInfo<NotFoundError> {
572 public:
573   static char ID;
574 
575   std::error_code convertToErrorCode() const override {
576     return inconvertibleErrorCode();
577   }
578 
579   /// Print diagnostic associated with this error when printing the error.
580   void log(raw_ostream &OS) const override {
581     OS << "String not found in input";
582   }
583 };
584 
585 /// An error that has already been reported.
586 ///
587 /// This class is designed to support a function whose callers may need to know
588 /// whether the function encountered and reported an error but never need to
589 /// know the nature of that error.  For example, the function has a return type
590 /// of \c Error and always returns either \c ErrorReported or \c ErrorSuccess.
591 /// That interface is similar to that of a function returning bool to indicate
592 /// an error except, in the former case, (1) there is no confusion over polarity
593 /// and (2) the caller must either check the result or explicitly ignore it with
594 /// a call like \c consumeError.
595 class ErrorReported final : public ErrorInfo<ErrorReported> {
596 public:
597   static char ID;
598 
599   std::error_code convertToErrorCode() const override {
600     return inconvertibleErrorCode();
601   }
602 
603   /// Print diagnostic associated with this error when printing the error.
604   void log(raw_ostream &OS) const override {
605     OS << "error previously reported";
606   }
607 
608   static inline Error reportedOrSuccess(bool HasErrorReported) {
609     if (HasErrorReported)
610       return make_error<ErrorReported>();
611     return Error::success();
612   }
613 };
614 
615 class Pattern {
616   SMLoc PatternLoc;
617 
618   /// A fixed string to match as the pattern or empty if this pattern requires
619   /// a regex match.
620   StringRef FixedStr;
621 
622   /// A regex string to match as the pattern or empty if this pattern requires
623   /// a fixed string to match.
624   std::string RegExStr;
625 
626   /// Entries in this vector represent a substitution of a string variable or
627   /// an expression in the RegExStr regex at match time. For example, in the
628   /// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
629   /// RegExStr will contain "foobaz" and we'll get two entries in this vector
630   /// that tells us to insert the value of string variable "bar" at offset 3
631   /// and the value of expression "N+1" at offset 6.
632   std::vector<Substitution *> Substitutions;
633 
634   /// Maps names of string variables defined in a pattern to the number of
635   /// their parenthesis group in RegExStr capturing their last definition.
636   ///
637   /// E.g. for the pattern "foo[[bar:.*]]baz([[bar]][[QUUX]][[bar:.*]])",
638   /// RegExStr will be "foo(.*)baz(\1<quux value>(.*))" where <quux value> is
639   /// the value captured for QUUX on the earlier line where it was defined, and
640   /// VariableDefs will map "bar" to the third parenthesis group which captures
641   /// the second definition of "bar".
642   ///
643   /// Note: uses std::map rather than StringMap to be able to get the key when
644   /// iterating over values.
645   std::map<StringRef, unsigned> VariableDefs;
646 
647   /// Structure representing the definition of a numeric variable in a pattern.
648   /// It holds the pointer to the class instance holding the value and matching
649   /// format of the numeric variable whose value is being defined and the
650   /// number of the parenthesis group in RegExStr to capture that value.
651   struct NumericVariableMatch {
652     /// Pointer to class instance holding the value and matching format of the
653     /// numeric variable being defined.
654     NumericVariable *DefinedNumericVariable;
655 
656     /// Number of the parenthesis group in RegExStr that captures the value of
657     /// this numeric variable definition.
658     unsigned CaptureParenGroup;
659   };
660 
661   /// Holds the number of the parenthesis group in RegExStr and pointer to the
662   /// corresponding NumericVariable class instance of all numeric variable
663   /// definitions. Used to set the matched value of all those variables.
664   StringMap<NumericVariableMatch> NumericVariableDefs;
665 
666   /// Pointer to a class instance holding the global state shared by all
667   /// patterns:
668   /// - separate tables with the values of live string and numeric variables
669   ///   respectively at the start of any given CHECK line;
670   /// - table holding whether a string variable has been defined at any given
671   ///   point during the parsing phase.
672   FileCheckPatternContext *Context;
673 
674   Check::FileCheckType CheckTy;
675 
676   /// Line number for this CHECK pattern or None if it is an implicit pattern.
677   /// Used to determine whether a variable definition is made on an earlier
678   /// line to the one with this CHECK.
679   Optional<size_t> LineNumber;
680 
681   /// Ignore case while matching if set to true.
682   bool IgnoreCase = false;
683 
684 public:
685   Pattern(Check::FileCheckType Ty, FileCheckPatternContext *Context,
686           Optional<size_t> Line = None)
687       : Context(Context), CheckTy(Ty), LineNumber(Line) {}
688 
689   /// \returns the location in source code.
690   SMLoc getLoc() const { return PatternLoc; }
691 
692   /// \returns the pointer to the global state for all patterns in this
693   /// FileCheck instance.
694   FileCheckPatternContext *getContext() const { return Context; }
695 
696   /// \returns whether \p C is a valid first character for a variable name.
697   static bool isValidVarNameStart(char C);
698 
699   /// Parsing information about a variable.
700   struct VariableProperties {
701     StringRef Name;
702     bool IsPseudo;
703   };
704 
705   /// Parses the string at the start of \p Str for a variable name. \returns
706   /// a VariableProperties structure holding the variable name and whether it
707   /// is the name of a pseudo variable, or an error holding a diagnostic
708   /// against \p SM if parsing fail. If parsing was successful, also strips
709   /// \p Str from the variable name.
710   static Expected<VariableProperties> parseVariable(StringRef &Str,
711                                                     const SourceMgr &SM);
712   /// Parses \p Expr for a numeric substitution block at line \p LineNumber,
713   /// or before input is parsed if \p LineNumber is None. Parameter
714   /// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
715   /// expression and \p Context points to the class instance holding the live
716   /// string and numeric variables. \returns a pointer to the class instance
717   /// representing the expression whose value must be substitued, or an error
718   /// holding a diagnostic against \p SM if parsing fails. If substitution was
719   /// successful, sets \p DefinedNumericVariable to point to the class
720   /// representing the numeric variable defined in this numeric substitution
721   /// block, or None if this block does not define any variable.
722   static Expected<std::unique_ptr<Expression>> parseNumericSubstitutionBlock(
723       StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable,
724       bool IsLegacyLineExpr, Optional<size_t> LineNumber,
725       FileCheckPatternContext *Context, const SourceMgr &SM);
726   /// Parses the pattern in \p PatternStr and initializes this Pattern instance
727   /// accordingly.
728   ///
729   /// \p Prefix provides which prefix is being matched, \p Req describes the
730   /// global options that influence the parsing such as whitespace
731   /// canonicalization, \p SM provides the SourceMgr used for error reports.
732   /// \returns true in case of an error, false otherwise.
733   bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
734                     const FileCheckRequest &Req);
735   struct Match {
736     size_t Pos;
737     size_t Len;
738   };
739   struct MatchResult {
740     Optional<Match> TheMatch;
741     Error TheError;
742     MatchResult(size_t MatchPos, size_t MatchLen, Error E)
743         : TheMatch(Match{MatchPos, MatchLen}), TheError(std::move(E)) {}
744     MatchResult(Match M, Error E) : TheMatch(M), TheError(std::move(E)) {}
745     MatchResult(Error E) : TheError(std::move(E)) {}
746   };
747   /// Matches the pattern string against the input buffer \p Buffer.
748   ///
749   /// \returns either (1) an error resulting in no match or (2) a match possibly
750   /// with an error encountered while processing the match.
751   ///
752   /// The GlobalVariableTable StringMap in the FileCheckPatternContext class
753   /// instance provides the current values of FileCheck string variables and is
754   /// updated if this match defines new values. Likewise, the
755   /// GlobalNumericVariableTable StringMap in the same class provides the
756   /// current values of FileCheck numeric variables and is updated if this
757   /// match defines new numeric values.
758   MatchResult match(StringRef Buffer, const SourceMgr &SM) const;
759   /// Prints the value of successful substitutions or the name of the undefined
760   /// string or numeric variables preventing a successful substitution.
761   void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
762                           SMRange MatchRange, FileCheckDiag::MatchType MatchTy,
763                           std::vector<FileCheckDiag> *Diags) const;
764   void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
765                        std::vector<FileCheckDiag> *Diags) const;
766 
767   bool hasVariable() const {
768     return !(Substitutions.empty() && VariableDefs.empty());
769   }
770   void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
771                          std::vector<FileCheckDiag> *Diags) const;
772 
773   Check::FileCheckType getCheckTy() const { return CheckTy; }
774 
775   int getCount() const { return CheckTy.getCount(); }
776 
777 private:
778   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
779   void AddBackrefToRegEx(unsigned BackrefNum);
780   /// Computes an arbitrary estimate for the quality of matching this pattern
781   /// at the start of \p Buffer; a distance of zero should correspond to a
782   /// perfect match.
783   unsigned computeMatchDistance(StringRef Buffer) const;
784   /// Finds the closing sequence of a regex variable usage or definition.
785   ///
786   /// \p Str has to point in the beginning of the definition (right after the
787   /// opening sequence). \p SM holds the SourceMgr used for error reporting.
788   ///  \returns the offset of the closing sequence within Str, or npos if it
789   /// was not found.
790   static size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
791 
792   /// Parses \p Expr for the name of a numeric variable to be defined at line
793   /// \p LineNumber, or before input is parsed if \p LineNumber is None.
794   /// \returns a pointer to the class instance representing that variable,
795   /// creating it if needed, or an error holding a diagnostic against \p SM
796   /// should defining such a variable be invalid.
797   static Expected<NumericVariable *> parseNumericVariableDefinition(
798       StringRef &Expr, FileCheckPatternContext *Context,
799       Optional<size_t> LineNumber, ExpressionFormat ImplicitFormat,
800       const SourceMgr &SM);
801   /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
802   /// at line \p LineNumber, or before input is parsed if \p LineNumber is
803   /// None. Parameter \p Context points to the class instance holding the live
804   /// string and numeric variables. \returns the pointer to the class instance
805   /// representing that variable if successful, or an error holding a
806   /// diagnostic against \p SM otherwise.
807   static Expected<std::unique_ptr<NumericVariableUse>> parseNumericVariableUse(
808       StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
809       FileCheckPatternContext *Context, const SourceMgr &SM);
810   enum class AllowedOperand { LineVar, LegacyLiteral, Any };
811   /// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
812   /// before input is parsed if \p LineNumber is None. Accepts literal values,
813   /// numeric variables and function calls, depending on the value of \p AO.
814   /// \p MaybeInvalidConstraint indicates whether the text being parsed could
815   /// be an invalid constraint. \p Context points to the class instance holding
816   /// the live string and numeric variables. \returns the class representing
817   /// that operand in the AST of the expression or an error holding a
818   /// diagnostic against \p SM otherwise. If \p Expr starts with a "(" this
819   /// function will attempt to parse a parenthesized expression.
820   static Expected<std::unique_ptr<ExpressionAST>>
821   parseNumericOperand(StringRef &Expr, AllowedOperand AO, bool ConstraintParsed,
822                       Optional<size_t> LineNumber,
823                       FileCheckPatternContext *Context, const SourceMgr &SM);
824   /// Parses and updates \p RemainingExpr for a binary operation at line
825   /// \p LineNumber, or before input is parsed if \p LineNumber is None. The
826   /// left operand of this binary operation is given in \p LeftOp and \p Expr
827   /// holds the string for the full expression, including the left operand.
828   /// Parameter \p IsLegacyLineExpr indicates whether we are parsing a legacy
829   /// @LINE expression. Parameter \p Context points to the class instance
830   /// holding the live string and numeric variables. \returns the class
831   /// representing the binary operation in the AST of the expression, or an
832   /// error holding a diagnostic against \p SM otherwise.
833   static Expected<std::unique_ptr<ExpressionAST>>
834   parseBinop(StringRef Expr, StringRef &RemainingExpr,
835              std::unique_ptr<ExpressionAST> LeftOp, bool IsLegacyLineExpr,
836              Optional<size_t> LineNumber, FileCheckPatternContext *Context,
837              const SourceMgr &SM);
838 
839   /// Parses a parenthesized expression inside \p Expr at line \p LineNumber, or
840   /// before input is parsed if \p LineNumber is None. \p Expr must start with
841   /// a '('. Accepts both literal values and numeric variables. Parameter \p
842   /// Context points to the class instance holding the live string and numeric
843   /// variables. \returns the class representing that operand in the AST of the
844   /// expression or an error holding a diagnostic against \p SM otherwise.
845   static Expected<std::unique_ptr<ExpressionAST>>
846   parseParenExpr(StringRef &Expr, Optional<size_t> LineNumber,
847                  FileCheckPatternContext *Context, const SourceMgr &SM);
848 
849   /// Parses \p Expr for an argument list belonging to a call to function \p
850   /// FuncName at line \p LineNumber, or before input is parsed if \p LineNumber
851   /// is None. Parameter \p FuncLoc is the source location used for diagnostics.
852   /// Parameter \p Context points to the class instance holding the live string
853   /// and numeric variables. \returns the class representing that call in the
854   /// AST of the expression or an error holding a diagnostic against \p SM
855   /// otherwise.
856   static Expected<std::unique_ptr<ExpressionAST>>
857   parseCallExpr(StringRef &Expr, StringRef FuncName,
858                 Optional<size_t> LineNumber, FileCheckPatternContext *Context,
859                 const SourceMgr &SM);
860 };
861 
862 //===----------------------------------------------------------------------===//
863 // Check Strings.
864 //===----------------------------------------------------------------------===//
865 
866 /// A check that we found in the input file.
867 struct FileCheckString {
868   /// The pattern to match.
869   Pattern Pat;
870 
871   /// Which prefix name this check matched.
872   StringRef Prefix;
873 
874   /// The location in the match file that the check string was specified.
875   SMLoc Loc;
876 
877   /// All of the strings that are disallowed from occurring between this match
878   /// string and the previous one (or start of file).
879   std::vector<Pattern> DagNotStrings;
880 
881   FileCheckString(const Pattern &P, StringRef S, SMLoc L)
882       : Pat(P), Prefix(S), Loc(L) {}
883 
884   /// Matches check string and its "not strings" and/or "dag strings".
885   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
886                size_t &MatchLen, FileCheckRequest &Req,
887                std::vector<FileCheckDiag> *Diags) const;
888 
889   /// Verifies that there is a single line in the given \p Buffer. Errors are
890   /// reported against \p SM.
891   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
892   /// Verifies that there is no newline in the given \p Buffer. Errors are
893   /// reported against \p SM.
894   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
895   /// Verifies that none of the strings in \p NotStrings are found in the given
896   /// \p Buffer. Errors are reported against \p SM and diagnostics recorded in
897   /// \p Diags according to the verbosity level set in \p Req.
898   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
899                 const std::vector<const Pattern *> &NotStrings,
900                 const FileCheckRequest &Req,
901                 std::vector<FileCheckDiag> *Diags) const;
902   /// Matches "dag strings" and their mixed "not strings".
903   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
904                   std::vector<const Pattern *> &NotStrings,
905                   const FileCheckRequest &Req,
906                   std::vector<FileCheckDiag> *Diags) const;
907 };
908 
909 } // namespace llvm
910 
911 #endif
912