1//==-- llvm/Support/FileCheck.h ---------------------------*- 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/// \file This file has some utilities to use FileCheck as an API
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_SUPPORT_FILECHECK_H
14#define LLVM_SUPPORT_FILECHECK_H
15
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/MemoryBuffer.h"
18#include "llvm/Support/Regex.h"
19#include "llvm/Support/SourceMgr.h"
20#include <string>
21#include <vector>
22
23namespace llvm {
24
25/// Contains info about various FileCheck options.
26struct FileCheckRequest {
27  std::vector<std::string> CheckPrefixes;
28  bool NoCanonicalizeWhiteSpace = false;
29  std::vector<std::string> ImplicitCheckNot;
30  std::vector<std::string> GlobalDefines;
31  bool AllowEmptyInput = false;
32  bool MatchFullLines = false;
33  bool IgnoreCase = false;
34  bool EnableVarScope = false;
35  bool AllowDeprecatedDagOverlap = false;
36  bool Verbose = false;
37  bool VerboseVerbose = false;
38};
39
40//===----------------------------------------------------------------------===//
41// Summary of a FileCheck diagnostic.
42//===----------------------------------------------------------------------===//
43
44namespace Check {
45
46enum FileCheckKind {
47  CheckNone = 0,
48  CheckPlain,
49  CheckNext,
50  CheckSame,
51  CheckNot,
52  CheckDAG,
53  CheckLabel,
54  CheckEmpty,
55
56  /// Indicates the pattern only matches the end of file. This is used for
57  /// trailing CHECK-NOTs.
58  CheckEOF,
59
60  /// Marks when parsing found a -NOT check combined with another CHECK suffix.
61  CheckBadNot,
62
63  /// Marks when parsing found a -COUNT directive with invalid count value.
64  CheckBadCount
65};
66
67class FileCheckType {
68  FileCheckKind Kind;
69  int Count; ///< optional Count for some checks
70
71public:
72  FileCheckType(FileCheckKind Kind = CheckNone) : Kind(Kind), Count(1) {}
73  FileCheckType(const FileCheckType &) = default;
74  FileCheckType &operator=(const FileCheckType &) = default;
75
76  operator FileCheckKind() const { return Kind; }
77
78  int getCount() const { return Count; }
79  FileCheckType &setCount(int C);
80
81  // \returns a description of \p Prefix.
82  std::string getDescription(StringRef Prefix) const;
83};
84} // namespace Check
85
86struct FileCheckDiag {
87  /// What is the FileCheck directive for this diagnostic?
88  Check::FileCheckType CheckTy;
89  /// Where is the FileCheck directive for this diagnostic?
90  unsigned CheckLine, CheckCol;
91  /// What type of match result does this diagnostic describe?
92  ///
93  /// A directive's supplied pattern is said to be either expected or excluded
94  /// depending on whether the pattern must have or must not have a match in
95  /// order for the directive to succeed.  For example, a CHECK directive's
96  /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
97  /// All match result types whose names end with "Excluded" are for excluded
98  /// patterns, and all others are for expected patterns.
99  ///
100  /// There might be more than one match result for a single pattern.  For
101  /// example, there might be several discarded matches
102  /// (MatchFoundButDiscarded) before either a good match
103  /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
104  /// and there might be a fuzzy match (MatchFuzzy) after the latter.
105  enum MatchType {
106    /// Indicates a good match for an expected pattern.
107    MatchFoundAndExpected,
108    /// Indicates a match for an excluded pattern.
109    MatchFoundButExcluded,
110    /// Indicates a match for an expected pattern, but the match is on the
111    /// wrong line.
112    MatchFoundButWrongLine,
113    /// Indicates a discarded match for an expected pattern.
114    MatchFoundButDiscarded,
115    /// Indicates no match for an excluded pattern.
116    MatchNoneAndExcluded,
117    /// Indicates no match for an expected pattern, but this might follow good
118    /// matches when multiple matches are expected for the pattern, or it might
119    /// follow discarded matches for the pattern.
120    MatchNoneButExpected,
121    /// Indicates a fuzzy match that serves as a suggestion for the next
122    /// intended match for an expected pattern with too few or no good matches.
123    MatchFuzzy,
124  } MatchTy;
125  /// The search range if MatchTy is MatchNoneAndExcluded or
126  /// MatchNoneButExpected, or the match range otherwise.
127  unsigned InputStartLine;
128  unsigned InputStartCol;
129  unsigned InputEndLine;
130  unsigned InputEndCol;
131  FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy,
132                SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange);
133};
134
135class FileCheckPatternContext;
136struct FileCheckString;
137
138/// FileCheck class takes the request and exposes various methods that
139/// use information from the request.
140class FileCheck {
141  FileCheckRequest Req;
142  std::unique_ptr<FileCheckPatternContext> PatternContext;
143  // C++17 TODO: make this a plain std::vector.
144  std::unique_ptr<std::vector<FileCheckString>> CheckStrings;
145
146public:
147  explicit FileCheck(FileCheckRequest Req);
148  ~FileCheck();
149
150  // Combines the check prefixes into a single regex so that we can efficiently
151  // scan for any of the set.
152  //
153  // The semantics are that the longest-match wins which matches our regex
154  // library.
155  Regex buildCheckPrefixRegex();
156
157  /// Reads the check file from \p Buffer and records the expected strings it
158  /// contains. Errors are reported against \p SM.
159  ///
160  /// Only expected strings whose prefix is one of those listed in \p PrefixRE
161  /// are recorded. \returns true in case of an error, false otherwise.
162  bool readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE);
163
164  bool ValidateCheckPrefixes();
165
166  /// Canonicalizes whitespaces in the file. Line endings are replaced with
167  /// UNIX-style '\n'.
168  StringRef CanonicalizeFile(MemoryBuffer &MB,
169                             SmallVectorImpl<char> &OutputBuffer);
170
171  /// Checks the input to FileCheck provided in the \p Buffer against the
172  /// expected strings read from the check file and record diagnostics emitted
173  /// in \p Diags. Errors are recorded against \p SM.
174  ///
175  /// \returns false if the input fails to satisfy the checks.
176  bool checkInput(SourceMgr &SM, StringRef Buffer,
177                  std::vector<FileCheckDiag> *Diags = nullptr);
178};
179
180} // namespace llvm
181
182#endif
183