[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode
[llvm-core.git] / utils / FileCheck / FileCheck.cpp
blob8ce1d9cbd0900556ba8801370f12eeb37275fbdc
1 //===- FileCheck.cpp - Check that File's Contents match what is expected --===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // FileCheck does a line-by line check of a file that validates whether it
11 // contains the expected content. This is useful for regression tests etc.
13 // This program exits with an exit status of 2 on error, exit status of 0 if
14 // the file matched the expected contents, and exit status of 1 if it did not
15 // contain the expected contents.
17 //===----------------------------------------------------------------------===//
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/InitLLVM.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/Support/FileCheck.h"
23 using namespace llvm;
25 static cl::opt<std::string>
26 CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
28 static cl::opt<std::string>
29 InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
30 cl::init("-"), cl::value_desc("filename"));
32 static cl::list<std::string> CheckPrefixes(
33 "check-prefix",
34 cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
35 static cl::alias CheckPrefixesAlias(
36 "check-prefixes", cl::aliasopt(CheckPrefixes), cl::CommaSeparated,
37 cl::NotHidden,
38 cl::desc(
39 "Alias for -check-prefix permitting multiple comma separated values"));
41 static cl::opt<bool> NoCanonicalizeWhiteSpace(
42 "strict-whitespace",
43 cl::desc("Do not treat all horizontal whitespace as equivalent"));
45 static cl::list<std::string> ImplicitCheckNot(
46 "implicit-check-not",
47 cl::desc("Add an implicit negative check with this pattern to every\n"
48 "positive check. This can be used to ensure that no instances of\n"
49 "this pattern occur which are not matched by a positive pattern"),
50 cl::value_desc("pattern"));
52 static cl::list<std::string> GlobalDefines("D", cl::Prefix,
53 cl::desc("Define a variable to be used in capture patterns."),
54 cl::value_desc("VAR=VALUE"));
56 static cl::opt<bool> AllowEmptyInput(
57 "allow-empty", cl::init(false),
58 cl::desc("Allow the input file to be empty. This is useful when making\n"
59 "checks that some error message does not occur, for example."));
61 static cl::opt<bool> MatchFullLines(
62 "match-full-lines", cl::init(false),
63 cl::desc("Require all positive matches to cover an entire input line.\n"
64 "Allows leading and trailing whitespace if --strict-whitespace\n"
65 "is not also passed."));
67 static cl::opt<bool> EnableVarScope(
68 "enable-var-scope", cl::init(false),
69 cl::desc("Enables scope for regex variables. Variables with names that\n"
70 "do not start with '$' will be reset at the beginning of\n"
71 "each CHECK-LABEL block."));
73 static cl::opt<bool> AllowDeprecatedDagOverlap(
74 "allow-deprecated-dag-overlap", cl::init(false),
75 cl::desc("Enable overlapping among matches in a group of consecutive\n"
76 "CHECK-DAG directives. This option is deprecated and is only\n"
77 "provided for convenience as old tests are migrated to the new\n"
78 "non-overlapping CHECK-DAG implementation.\n"));
80 static cl::opt<bool> Verbose("v", cl::init(false),
81 cl::desc("Print directive pattern matches.\n"));
83 static cl::opt<bool> VerboseVerbose(
84 "vv", cl::init(false),
85 cl::desc("Print information helpful in diagnosing internal FileCheck\n"
86 "issues. Implies -v.\n"));
87 static const char * DumpInputEnv = "FILECHECK_DUMP_INPUT_ON_FAILURE";
89 static cl::opt<bool> DumpInputOnFailure(
90 "dump-input-on-failure", cl::init(std::getenv(DumpInputEnv)),
91 cl::desc("Dump original input to stderr before failing.\n"
92 "The value can be also controlled using\n"
93 "FILECHECK_DUMP_INPUT_ON_FAILURE environment variable.\n"));
95 typedef cl::list<std::string>::const_iterator prefix_iterator;
103 static void DumpCommandLine(int argc, char **argv) {
104 errs() << "FileCheck command line: ";
105 for (int I = 0; I < argc; I++)
106 errs() << " " << argv[I];
107 errs() << "\n";
110 int main(int argc, char **argv) {
111 InitLLVM X(argc, argv);
112 cl::ParseCommandLineOptions(argc, argv);
114 FileCheckRequest Req;
115 for (auto Prefix : CheckPrefixes)
116 Req.CheckPrefixes.push_back(Prefix);
118 for (auto CheckNot : ImplicitCheckNot)
119 Req.ImplicitCheckNot.push_back(CheckNot);
121 for (auto G : GlobalDefines)
122 Req.GlobalDefines.push_back(G);
124 Req.AllowEmptyInput = AllowEmptyInput;
125 Req.EnableVarScope = EnableVarScope;
126 Req.AllowDeprecatedDagOverlap = AllowDeprecatedDagOverlap;
127 Req.Verbose = Verbose;
128 Req.VerboseVerbose = VerboseVerbose;
129 Req.NoCanonicalizeWhiteSpace = NoCanonicalizeWhiteSpace;
130 Req.MatchFullLines = MatchFullLines;
132 if (VerboseVerbose)
133 Req.Verbose = true;
135 FileCheck FC(Req);
136 if (!FC.ValidateCheckPrefixes()) {
137 errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
138 "start with a letter and contain only alphanumeric characters, "
139 "hyphens and underscores\n";
140 return 2;
143 Regex PrefixRE = FC.buildCheckPrefixRegex();
144 std::string REError;
145 if (!PrefixRE.isValid(REError)) {
146 errs() << "Unable to combine check-prefix strings into a prefix regular "
147 "expression! This is likely a bug in FileCheck's verification of "
148 "the check-prefix strings. Regular expression parsing failed "
149 "with the following error: "
150 << REError << "\n";
151 return 2;
155 SourceMgr SM;
157 // Read the expected strings from the check file.
158 ErrorOr<std::unique_ptr<MemoryBuffer>> CheckFileOrErr =
159 MemoryBuffer::getFileOrSTDIN(CheckFilename);
160 if (std::error_code EC = CheckFileOrErr.getError()) {
161 errs() << "Could not open check file '" << CheckFilename
162 << "': " << EC.message() << '\n';
163 return 2;
165 MemoryBuffer &CheckFile = *CheckFileOrErr.get();
167 SmallString<4096> CheckFileBuffer;
168 StringRef CheckFileText = FC.CanonicalizeFile(CheckFile, CheckFileBuffer);
170 SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
171 CheckFileText, CheckFile.getBufferIdentifier()),
172 SMLoc());
174 std::vector<FileCheckString> CheckStrings;
175 if (FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings))
176 return 2;
178 // Open the file to check and add it to SourceMgr.
179 ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
180 MemoryBuffer::getFileOrSTDIN(InputFilename);
181 if (std::error_code EC = InputFileOrErr.getError()) {
182 errs() << "Could not open input file '" << InputFilename
183 << "': " << EC.message() << '\n';
184 return 2;
186 MemoryBuffer &InputFile = *InputFileOrErr.get();
188 if (InputFile.getBufferSize() == 0 && !AllowEmptyInput) {
189 errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
190 DumpCommandLine(argc, argv);
191 return 2;
194 SmallString<4096> InputFileBuffer;
195 StringRef InputFileText = FC.CanonicalizeFile(InputFile, InputFileBuffer);
197 SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
198 InputFileText, InputFile.getBufferIdentifier()),
199 SMLoc());
201 int ExitCode =
202 FC.CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1;
203 if (ExitCode == 1 && DumpInputOnFailure)
204 errs() << "Full input was:\n<<<<<<\n" << InputFileText << "\n>>>>>>\n";
206 return ExitCode;