//==-- llvm/Support/FileCheck.h ---------------------------*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file This file has some utilities to use FileCheck as an API
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_FILECHECK_H
#define LLVM_SUPPORT_FILECHECK_H

#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SourceMgr.h"
#include <vector>
#include <map>

namespace llvm {

/// Contains info about various FileCheck options.
struct FileCheckRequest {
  std::vector<std::string> CheckPrefixes;
  bool NoCanonicalizeWhiteSpace = false;
  std::vector<std::string> ImplicitCheckNot;
  std::vector<std::string> GlobalDefines;
  bool AllowEmptyInput = false;
  bool MatchFullLines = false;
  bool EnableVarScope = false;
  bool AllowDeprecatedDagOverlap = false;
  bool Verbose = false;
  bool VerboseVerbose = false;
};

//===----------------------------------------------------------------------===//
// Numeric substitution handling code.
//===----------------------------------------------------------------------===//

/// Class representing a numeric variable and its associated current value.
class FileCheckNumericVariable {
private:
  /// Name of the numeric variable.
  StringRef Name;

  /// Value of numeric variable, if defined, or None otherwise.
  Optional<uint64_t> Value;

  /// Line number where this variable is defined. Used to determine whether a
  /// variable is defined on the same line as a given use.
  size_t DefLineNumber;

public:
  /// Constructor for a variable \p Name defined at line \p DefLineNumber.
  FileCheckNumericVariable(size_t DefLineNumber, StringRef Name)
      : Name(Name), DefLineNumber(DefLineNumber) {}

  /// Constructor for numeric variable \p Name with a known \p Value at parse
  /// time (e.g. the @LINE numeric variable).
  FileCheckNumericVariable(StringRef Name, uint64_t Value)
      : Name(Name), Value(Value), DefLineNumber(0) {}

  /// \returns name of this numeric variable.
  StringRef getName() const { return Name; }

  /// \returns this variable's value.
  Optional<uint64_t> getValue() const { return Value; }

  /// Sets value of this numeric variable, if undefined. Triggers an assertion
  /// failure if the variable is actually defined.
  void setValue(uint64_t Value);

  /// Clears value of this numeric variable, regardless of whether it is
  /// currently defined or not.
  void clearValue();

  /// \returns the line number where this variable is defined.
  size_t getDefLineNumber() { return DefLineNumber; }
};

/// Type of functions evaluating a given binary operation.
using binop_eval_t = uint64_t (*)(uint64_t, uint64_t);

/// Class to represent an undefined variable error which prints that variable's
/// name between quotes when printed.
class FileCheckUndefVarError : public ErrorInfo<FileCheckUndefVarError> {
private:
  StringRef VarName;

public:
  static char ID;

  FileCheckUndefVarError(StringRef VarName) : VarName(VarName) {}

  StringRef getVarName() const { return VarName; }

  std::error_code convertToErrorCode() const override {
    return inconvertibleErrorCode();
  }

  /// Print name of variable associated with this error.
  void log(raw_ostream &OS) const override {
    OS << "\"";
    OS.write_escaped(VarName) << "\"";
  }
};

/// Class representing an expression consisting of either a single numeric
/// variable or a binary operation between a numeric variable and an
/// immediate.
class FileCheckExpression {
private:
  /// Left operand.
  FileCheckNumericVariable *LeftOp;

  /// Right operand.
  uint64_t RightOp;

  /// Pointer to function that can evaluate this binary operation.
  binop_eval_t EvalBinop;

public:
  FileCheckExpression(binop_eval_t EvalBinop,
                      FileCheckNumericVariable *OperandLeft,
                      uint64_t OperandRight)
      : LeftOp(OperandLeft), RightOp(OperandRight), EvalBinop(EvalBinop) {}

  /// Evaluates the value of this expression, using EvalBinop to perform the
  /// binary operation it consists of. \returns an error if the numeric
  /// variable used is undefined, or the expression value otherwise.
  Expected<uint64_t> eval() const;
};

class FileCheckPatternContext;

/// Class representing a substitution to perform in the RegExStr string.
class FileCheckSubstitution {
protected:
  /// Pointer to a class instance holding, among other things, the table with
  /// the values of live string variables at the start of any given CHECK line.
  /// Used for substituting string variables with the text they were defined
  /// as. Expressions are linked to the numeric variables they use at
  /// parse time and directly access the value of the numeric variable to
  /// evaluate their value.
  FileCheckPatternContext *Context;

  /// The string that needs to be substituted for something else. For a
  /// string variable this is its name, otherwise this is the whole expression.
  StringRef FromStr;

  // Index in RegExStr of where to do the substitution.
  size_t InsertIdx;

public:
  FileCheckSubstitution(FileCheckPatternContext *Context, StringRef VarName,
                        size_t InsertIdx)
      : Context(Context), FromStr(VarName), InsertIdx(InsertIdx) {}

  virtual ~FileCheckSubstitution() = default;

  /// \returns the string to be substituted for something else.
  StringRef getFromString() const { return FromStr; }

  /// \returns the index where the substitution is to be performed in RegExStr.
  size_t getIndex() const { return InsertIdx; }

  /// \returns a string containing the result of the substitution represented
  /// by this class instance or an error if substitution failed.
  virtual Expected<std::string> getResult() const = 0;
};

class FileCheckStringSubstitution : public FileCheckSubstitution {
public:
  FileCheckStringSubstitution(FileCheckPatternContext *Context,
                              StringRef VarName, size_t InsertIdx)
      : FileCheckSubstitution(Context, VarName, InsertIdx) {}

  /// \returns the text that the string variable in this substitution matched
  /// when defined, or an error if the variable is undefined.
  Expected<std::string> getResult() const override;
};

class FileCheckNumericSubstitution : public FileCheckSubstitution {
private:
  /// Pointer to the class representing the expression whose value is to be
  /// substituted.
  FileCheckExpression *Expression;

public:
  FileCheckNumericSubstitution(FileCheckPatternContext *Context,
                               StringRef ExpressionStr,
                               FileCheckExpression *Expression,
                               size_t InsertIdx)
      : FileCheckSubstitution(Context, ExpressionStr, InsertIdx),
        Expression(Expression) {}

  /// \returns a string containing the result of evaluating the expression in
  /// this substitution, or an error if evaluation failed.
  Expected<std::string> getResult() const override;
};

//===----------------------------------------------------------------------===//
// Pattern handling code.
//===----------------------------------------------------------------------===//

namespace Check {

enum FileCheckKind {
  CheckNone = 0,
  CheckPlain,
  CheckNext,
  CheckSame,
  CheckNot,
  CheckDAG,
  CheckLabel,
  CheckEmpty,

  /// Indicates the pattern only matches the end of file. This is used for
  /// trailing CHECK-NOTs.
  CheckEOF,

  /// Marks when parsing found a -NOT check combined with another CHECK suffix.
  CheckBadNot,

  /// Marks when parsing found a -COUNT directive with invalid count value.
  CheckBadCount
};

class FileCheckType {
  FileCheckKind Kind;
  int Count; ///< optional Count for some checks

public:
  FileCheckType(FileCheckKind Kind = CheckNone) : Kind(Kind), Count(1) {}
  FileCheckType(const FileCheckType &) = default;

  operator FileCheckKind() const { return Kind; }

  int getCount() const { return Count; }
  FileCheckType &setCount(int C);

  // \returns a description of \p Prefix.
  std::string getDescription(StringRef Prefix) const;
};
} // namespace Check

struct FileCheckDiag;

/// Class holding the FileCheckPattern global state, shared by all patterns:
/// tables holding values of variables and whether they are defined or not at
/// any given time in the matching process.
class FileCheckPatternContext {
  friend class FileCheckPattern;

private:
  /// When matching a given pattern, this holds the value of all the string
  /// variables defined in previous patterns. In a pattern, only the last
  /// definition for a given variable is recorded in this table.
  /// Back-references are used for uses after any the other definition.
  StringMap<StringRef> GlobalVariableTable;

  /// Map of all string variables defined so far. Used at parse time to detect
  /// a name conflict between a numeric variable and a string variable when
  /// the former is defined on a later line than the latter.
  StringMap<bool> DefinedVariableTable;

  /// When matching a given pattern, this holds the pointers to the classes
  /// representing the numeric variables defined in previous patterns. When
  /// matching a pattern all definitions for that pattern are recorded in the
  /// NumericVariableDefs table in the FileCheckPattern instance of that
  /// pattern.
  StringMap<FileCheckNumericVariable *> GlobalNumericVariableTable;

  /// Pointer to the class instance representing the @LINE pseudo variable for
  /// easily updating its value.
  FileCheckNumericVariable *LineVariable = nullptr;

  /// Vector holding pointers to all parsed expressions. Used to automatically
  /// free the expressions once they are guaranteed to no longer be used.
  std::vector<std::unique_ptr<FileCheckExpression>> Expressions;

  /// Vector holding pointers to all parsed numeric variables. Used to
  /// automatically free them once they are guaranteed to no longer be used.
  std::vector<std::unique_ptr<FileCheckNumericVariable>> NumericVariables;

  /// Vector holding pointers to all substitutions. Used to automatically free
  /// them once they are guaranteed to no longer be used.
  std::vector<std::unique_ptr<FileCheckSubstitution>> Substitutions;

public:
  /// \returns the value of string variable \p VarName or an error if no such
  /// variable has been defined.
  Expected<StringRef> getPatternVarValue(StringRef VarName);

  /// Defines string and numeric variables from definitions given on the
  /// command line, passed as a vector of [#]VAR=VAL strings in
  /// \p CmdlineDefines. \returns an error list containing diagnostics against
  /// \p SM for all definition parsing failures, if any, or Success otherwise.
  Error defineCmdlineVariables(std::vector<std::string> &CmdlineDefines,
                               SourceMgr &SM);

  /// Create @LINE pseudo variable. Value is set when pattern are being
  /// matched.
  void createLineVariable();

  /// Undefines local variables (variables whose name does not start with a '$'
  /// sign), i.e. removes them from GlobalVariableTable and from
  /// GlobalNumericVariableTable and also clears the value of numeric
  /// variables.
  void clearLocalVars();

private:
  /// Makes a new expression instance and registers it for destruction when
  /// the context is destroyed.
  FileCheckExpression *makeExpression(binop_eval_t EvalBinop,
                                      FileCheckNumericVariable *OperandLeft,
                                      uint64_t OperandRight);

  /// Makes a new numeric variable and registers it for destruction when the
  /// context is destroyed.
  template <class... Types>
  FileCheckNumericVariable *makeNumericVariable(Types... args);

  /// Makes a new string substitution and registers it for destruction when the
  /// context is destroyed.
  FileCheckSubstitution *makeStringSubstitution(StringRef VarName,
                                                size_t InsertIdx);

  /// Makes a new numeric substitution and registers it for destruction when
  /// the context is destroyed.
  FileCheckSubstitution *
  makeNumericSubstitution(StringRef ExpressionStr,
                          FileCheckExpression *Expression, size_t InsertIdx);
};

/// Class to represent an error holding a diagnostic with location information
/// used when printing it.
class FileCheckErrorDiagnostic : public ErrorInfo<FileCheckErrorDiagnostic> {
private:
  SMDiagnostic Diagnostic;

public:
  static char ID;

  FileCheckErrorDiagnostic(SMDiagnostic &&Diag) : Diagnostic(Diag) {}

  std::error_code convertToErrorCode() const override {
    return inconvertibleErrorCode();
  }

  /// Print diagnostic associated with this error when printing the error.
  void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); }

  static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg) {
    return make_error<FileCheckErrorDiagnostic>(
        SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg));
  }

  static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg) {
    return get(SM, SMLoc::getFromPointer(Buffer.data()), ErrMsg);
  }
};

class FileCheckNotFoundError : public ErrorInfo<FileCheckNotFoundError> {
public:
  static char ID;

  std::error_code convertToErrorCode() const override {
    return inconvertibleErrorCode();
  }

  /// Print diagnostic associated with this error when printing the error.
  void log(raw_ostream &OS) const override {
    OS << "String not found in input";
  }
};

class FileCheckPattern {
  SMLoc PatternLoc;

  /// A fixed string to match as the pattern or empty if this pattern requires
  /// a regex match.
  StringRef FixedStr;

  /// A regex string to match as the pattern or empty if this pattern requires
  /// a fixed string to match.
  std::string RegExStr;

  /// Entries in this vector represent a substitution of a string variable or
  /// an expression in the RegExStr regex at match time. For example, in the
  /// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
  /// RegExStr will contain "foobaz" and we'll get two entries in this vector
  /// that tells us to insert the value of string variable "bar" at offset 3
  /// and the value of expression "N+1" at offset 6.
  std::vector<FileCheckSubstitution *> Substitutions;

  /// Maps names of string variables defined in a pattern to the number of
  /// their parenthesis group in RegExStr capturing their last definition.
  ///
  /// E.g. for the pattern "foo[[bar:.*]]baz([[bar]][[QUUX]][[bar:.*]])",
  /// RegExStr will be "foo(.*)baz(\1<quux value>(.*))" where <quux value> is
  /// the value captured for QUUX on the earlier line where it was defined, and
  /// VariableDefs will map "bar" to the third parenthesis group which captures
  /// the second definition of "bar".
  ///
  /// Note: uses std::map rather than StringMap to be able to get the key when
  /// iterating over values.
  std::map<StringRef, unsigned> VariableDefs;

  /// Structure representing the definition of a numeric variable in a pattern.
  /// It holds the pointer to the class representing the numeric variable whose
  /// value is being defined and the number of the parenthesis group in
  /// RegExStr to capture that value.
  struct FileCheckNumericVariableMatch {
    /// Pointer to class representing the numeric variable whose value is being
    /// defined.
    FileCheckNumericVariable *DefinedNumericVariable;

    /// Number of the parenthesis group in RegExStr that captures the value of
    /// this numeric variable definition.
    unsigned CaptureParenGroup;
  };

  /// Holds the number of the parenthesis group in RegExStr and pointer to the
  /// corresponding FileCheckNumericVariable class instance of all numeric
  /// variable definitions. Used to set the matched value of all those
  /// variables.
  StringMap<FileCheckNumericVariableMatch> NumericVariableDefs;

  /// Pointer to a class instance holding the global state shared by all
  /// patterns:
  /// - separate tables with the values of live string and numeric variables
  ///   respectively at the start of any given CHECK line;
  /// - table holding whether a string variable has been defined at any given
  ///   point during the parsing phase.
  FileCheckPatternContext *Context;

  Check::FileCheckType CheckTy;

  /// Line number for this CHECK pattern. Used to determine whether a variable
  /// definition is made on an earlier line to the one with this CHECK.
  size_t LineNumber;

public:
  FileCheckPattern(Check::FileCheckType Ty, FileCheckPatternContext *Context,
                   size_t Line)
      : Context(Context), CheckTy(Ty), LineNumber(Line) {}

  /// \returns the location in source code.
  SMLoc getLoc() const { return PatternLoc; }

  /// \returns the pointer to the global state for all patterns in this
  /// FileCheck instance.
  FileCheckPatternContext *getContext() const { return Context; }

  /// \returns whether \p C is a valid first character for a variable name.
  static bool isValidVarNameStart(char C);
  /// Parses the string at the start of \p Str for a variable name. \returns
  /// an error holding a diagnostic against \p SM if parsing fail, or the
  /// name of the variable otherwise. In the latter case, sets \p IsPseudo to
  /// indicate if it is a pseudo variable and strips \p Str from the variable
  /// name.
  static Expected<StringRef> parseVariable(StringRef &Str, bool &IsPseudo,
                                           const SourceMgr &SM);
  /// Parses \p Expr for the name of a numeric variable to be defined at line
  /// \p LineNumber. \returns a pointer to the class instance representing that
  /// variable, creating it if needed, or an error holding a diagnostic against
  /// \p SM should defining such a variable be invalid.
  static Expected<FileCheckNumericVariable *>
  parseNumericVariableDefinition(StringRef &Expr,
                                 FileCheckPatternContext *Context,
                                 size_t LineNumber, const SourceMgr &SM);
  /// Parses \p Expr for a numeric substitution block. \returns the class
  /// representing the AST of the expression whose value must be substituted,
  /// or an error holding a diagnostic against \p SM if parsing fails. If
  /// substitution was successful, sets \p DefinedNumericVariable to point to
  /// the class representing the numeric variable defined in this numeric
  /// substitution block, or None if this block does not define any variable.
  Expected<FileCheckExpression *> parseNumericSubstitutionBlock(
      StringRef Expr,
      Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
      const SourceMgr &SM) const;
  /// Parses the pattern in \p PatternStr and initializes this FileCheckPattern
  /// instance accordingly.
  ///
  /// \p Prefix provides which prefix is being matched, \p Req describes the
  /// global options that influence the parsing such as whitespace
  /// canonicalization, \p SM provides the SourceMgr used for error reports.
  /// \returns true in case of an error, false otherwise.
  bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
                    const FileCheckRequest &Req);
  /// Matches the pattern string against the input buffer \p Buffer
  ///
  /// \returns the position that is matched or an error indicating why matching
  /// failed. If there is a match, updates \p MatchLen with the size of the
  /// matched string.
  ///
  /// The GlobalVariableTable StringMap in the FileCheckPatternContext class
  /// instance provides the current values of FileCheck string variables and
  /// is updated if this match defines new values. Likewise, the
  /// GlobalNumericVariableTable StringMap in the same class provides the
  /// current values of FileCheck numeric variables and is updated if this
  /// match defines new numeric values.
  Expected<size_t> match(StringRef Buffer, size_t &MatchLen,
                         const SourceMgr &SM) const;
  /// Prints the value of successful substitutions or the name of the undefined
  /// string or numeric variable preventing a successful substitution.
  void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
                          SMRange MatchRange = None) const;
  void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
                       std::vector<FileCheckDiag> *Diags) const;

  bool hasVariable() const {
    return !(Substitutions.empty() && VariableDefs.empty());
  }

  Check::FileCheckType getCheckTy() const { return CheckTy; }

  int getCount() const { return CheckTy.getCount(); }

private:
  bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
  void AddBackrefToRegEx(unsigned BackrefNum);
  /// Computes an arbitrary estimate for the quality of matching this pattern
  /// at the start of \p Buffer; a distance of zero should correspond to a
  /// perfect match.
  unsigned computeMatchDistance(StringRef Buffer) const;
  /// Finds the closing sequence of a regex variable usage or definition.
  ///
  /// \p Str has to point in the beginning of the definition (right after the
  /// opening sequence). \p SM holds the SourceMgr used for error repporting.
  ///  \returns the offset of the closing sequence within Str, or npos if it
  /// was not found.
  size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);

  /// Parses \p Expr for the use of a numeric variable. \returns the pointer to
  /// the class instance representing that variable if successful, or an error
  /// holding a diagnostic against \p SM otherwise.
  Expected<FileCheckNumericVariable *>
  parseNumericVariableUse(StringRef &Expr, const SourceMgr &SM) const;
  /// Parses \p Expr for a binary operation.
  /// \returns the class representing the binary operation of the expression,
  /// or an error holding a diagnostic against \p SM otherwise.
  Expected<FileCheckExpression *> parseBinop(StringRef &Expr,
                                             const SourceMgr &SM) const;
};

//===----------------------------------------------------------------------===//
/// Summary of a FileCheck diagnostic.
//===----------------------------------------------------------------------===//

struct FileCheckDiag {
  /// What is the FileCheck directive for this diagnostic?
  Check::FileCheckType CheckTy;
  /// Where is the FileCheck directive for this diagnostic?
  unsigned CheckLine, CheckCol;
  /// What type of match result does this diagnostic describe?
  ///
  /// A directive's supplied pattern is said to be either expected or excluded
  /// depending on whether the pattern must have or must not have a match in
  /// order for the directive to succeed.  For example, a CHECK directive's
  /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
  /// All match result types whose names end with "Excluded" are for excluded
  /// patterns, and all others are for expected patterns.
  ///
  /// There might be more than one match result for a single pattern.  For
  /// example, there might be several discarded matches
  /// (MatchFoundButDiscarded) before either a good match
  /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
  /// and there might be a fuzzy match (MatchFuzzy) after the latter.
  enum MatchType {
    /// Indicates a good match for an expected pattern.
    MatchFoundAndExpected,
    /// Indicates a match for an excluded pattern.
    MatchFoundButExcluded,
    /// Indicates a match for an expected pattern, but the match is on the
    /// wrong line.
    MatchFoundButWrongLine,
    /// Indicates a discarded match for an expected pattern.
    MatchFoundButDiscarded,
    /// Indicates no match for an excluded pattern.
    MatchNoneAndExcluded,
    /// Indicates no match for an expected pattern, but this might follow good
    /// matches when multiple matches are expected for the pattern, or it might
    /// follow discarded matches for the pattern.
    MatchNoneButExpected,
    /// Indicates a fuzzy match that serves as a suggestion for the next
    /// intended match for an expected pattern with too few or no good matches.
    MatchFuzzy,
  } MatchTy;
  /// The search range if MatchTy is MatchNoneAndExcluded or
  /// MatchNoneButExpected, or the match range otherwise.
  unsigned InputStartLine;
  unsigned InputStartCol;
  unsigned InputEndLine;
  unsigned InputEndCol;
  FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy,
                SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange);
};

//===----------------------------------------------------------------------===//
// Check Strings.
//===----------------------------------------------------------------------===//

/// A check that we found in the input file.
struct FileCheckString {
  /// The pattern to match.
  FileCheckPattern Pat;

  /// Which prefix name this check matched.
  StringRef Prefix;

  /// The location in the match file that the check string was specified.
  SMLoc Loc;

  /// All of the strings that are disallowed from occurring between this match
  /// string and the previous one (or start of file).
  std::vector<FileCheckPattern> DagNotStrings;

  FileCheckString(const FileCheckPattern &P, StringRef S, SMLoc L)
      : Pat(P), Prefix(S), Loc(L) {}

  /// Matches check string and its "not strings" and/or "dag strings".
  size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
               size_t &MatchLen, FileCheckRequest &Req,
               std::vector<FileCheckDiag> *Diags) const;

  /// Verifies that there is a single line in the given \p Buffer. Errors are
  /// reported against \p SM.
  bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
  /// Verifies that there is no newline in the given \p Buffer. Errors are
  /// reported against \p SM.
  bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
  /// Verifies that none of the strings in \p NotStrings are found in the given
  /// \p Buffer. Errors are reported against \p SM and diagnostics recorded in
  /// \p Diags according to the verbosity level set in \p Req.
  bool CheckNot(const SourceMgr &SM, StringRef Buffer,
                const std::vector<const FileCheckPattern *> &NotStrings,
                const FileCheckRequest &Req,
                std::vector<FileCheckDiag> *Diags) const;
  /// Matches "dag strings" and their mixed "not strings".
  size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
                  std::vector<const FileCheckPattern *> &NotStrings,
                  const FileCheckRequest &Req,
                  std::vector<FileCheckDiag> *Diags) const;
};

/// FileCheck class takes the request and exposes various methods that
/// use information from the request.
class FileCheck {
  FileCheckRequest Req;
  FileCheckPatternContext PatternContext;

public:
  FileCheck(FileCheckRequest Req) : Req(Req) {}

  // Combines the check prefixes into a single regex so that we can efficiently
  // scan for any of the set.
  //
  // The semantics are that the longest-match wins which matches our regex
  // library.
  Regex buildCheckPrefixRegex();

  /// Reads the check file from \p Buffer and records the expected strings it
  /// contains in the \p CheckStrings vector. Errors are reported against
  /// \p SM.
  ///
  /// Only expected strings whose prefix is one of those listed in \p PrefixRE
  /// are recorded. \returns true in case of an error, false otherwise.
  bool ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
                     std::vector<FileCheckString> &CheckStrings);

  bool ValidateCheckPrefixes();

  /// Canonicalizes whitespaces in the file. Line endings are replaced with
  /// UNIX-style '\n'.
  StringRef CanonicalizeFile(MemoryBuffer &MB,
                             SmallVectorImpl<char> &OutputBuffer);

  /// Checks the input to FileCheck provided in the \p Buffer against the
  /// \p CheckStrings read from the check file and record diagnostics emitted
  /// in \p Diags. Errors are recorded against \p SM.
  ///
  /// \returns false if the input fails to satisfy the checks.
  bool CheckInput(SourceMgr &SM, StringRef Buffer,
                  ArrayRef<FileCheckString> CheckStrings,
                  std::vector<FileCheckDiag> *Diags = nullptr);
};
} // namespace llvm
#endif
