FileCheckForTest.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434
  1. //===- FileCheckForTest.cpp - Check that File's Contents match what is expected --===//
  2. ///////////////////////////////////////////////////////////////////////////////
  3. // //
  4. // FileCheckForTest.cpp //
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. // This file is distributed under the University of Illinois Open Source //
  7. // License. See LICENSE.TXT for details. //
  8. // //
  9. // This is effectively a touched up FileCheck.cpp file suitable for running //
  10. // in-memory as part of a unit test suite. //
  11. // //
  12. // FileCheck does a line-by line check of a file that validates whether it //
  13. // contains the expected content. This is useful for regression tests etc. //
  14. // //
  15. // This program exits with an error status of 2 on error, exit status of 0 if//
  16. // the file matched the expected contents, and exit status of 1 if it did not//
  17. // contain the expected contents. //
  18. // //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. #include "llvm/ADT/SmallString.h"
  21. #include "llvm/ADT/StringExtras.h"
  22. #include "llvm/ADT/StringMap.h"
  23. #include "llvm/ADT/StringSet.h"
  24. #include "llvm/Support/FileSystem.h"
  25. #include "llvm/Support/MemoryBuffer.h"
  26. #include "llvm/Support/Regex.h"
  27. #include "llvm/Support/Signals.h"
  28. #include "llvm/Support/SourceMgr.h"
  29. #include "llvm/Support/raw_ostream.h"
  30. #include <algorithm>
  31. #include <cctype>
  32. #include <map>
  33. #include <string>
  34. #include <system_error>
  35. #include <vector>
  36. // HLSL Change
  37. #include <dxc/Support/WinIncludes.h>
  38. #include "llvm/Support/MSFileSystem.h"
  39. #include "dxc/Test/DxcTestUtils.h"
  40. // End HLSL Change
  41. using namespace llvm;
  42. typedef std::vector<std::string>::const_iterator prefix_iterator;
  43. namespace Check {
  44. enum CheckType {
  45. CheckNone = 0,
  46. CheckPlain,
  47. CheckNext,
  48. CheckSame,
  49. CheckNot,
  50. CheckDAG,
  51. CheckLabel,
  52. /// MatchEOF - When set, this pattern only matches the end of file. This is
  53. /// used for trailing CHECK-NOTs.
  54. CheckEOF
  55. };
  56. }
  57. //===----------------------------------------------------------------------===//
  58. // Pattern Handling Code.
  59. //===----------------------------------------------------------------------===//
  60. class Pattern {
  61. SMLoc PatternLoc;
  62. Check::CheckType CheckTy;
  63. /// FixedStr - If non-empty, this pattern is a fixed string match with the
  64. /// specified fixed string.
  65. StringRef FixedStr;
  66. /// RegEx - If non-empty, this is a regex pattern.
  67. std::string RegExStr;
  68. /// \brief Contains the number of line this pattern is in.
  69. unsigned LineNumber;
  70. /// VariableUses - Entries in this vector map to uses of a variable in the
  71. /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain
  72. /// "foobaz" and we'll get an entry in this vector that tells us to insert the
  73. /// value of bar at offset 3.
  74. std::vector<std::pair<StringRef, unsigned> > VariableUses;
  75. /// VariableDefs - Maps definitions of variables to their parenthesized
  76. /// capture numbers.
  77. /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
  78. std::map<StringRef, unsigned> VariableDefs;
  79. public:
  80. Pattern(Check::CheckType Ty)
  81. : CheckTy(Ty) { }
  82. /// getLoc - Return the location in source code.
  83. SMLoc getLoc() const { return PatternLoc; }
  84. /// ParsePattern - Parse the given string into the Pattern. Prefix provides
  85. /// which prefix is being matched, SM provides the SourceMgr used for error
  86. /// reports, and LineNumber is the line number in the input file from which
  87. /// the pattern string was read. Returns true in case of an error, false
  88. /// otherwise.
  89. bool ParsePattern(raw_ostream &OS, StringRef PatternStr,
  90. StringRef Prefix,
  91. SourceMgr &SM,
  92. unsigned LineNumber);
  93. /// Match - Match the pattern string against the input buffer Buffer. This
  94. /// returns the position that is matched or npos if there is no match. If
  95. /// there is a match, the size of the matched string is returned in MatchLen.
  96. ///
  97. /// The VariableTable StringMap provides the current values of filecheck
  98. /// variables and is updated if this match defines new values.
  99. size_t Match(StringRef Buffer, size_t &MatchLen,
  100. StringMap<StringRef> &VariableTable) const;
  101. /// PrintFailureInfo - Print additional information about a failure to match
  102. /// involving this pattern.
  103. void PrintFailureInfo(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  104. const StringMap<StringRef> &VariableTable) const;
  105. bool hasVariable() const {
  106. return !(VariableUses.empty() &&
  107. VariableDefs.empty());
  108. }
  109. Check::CheckType getCheckTy() const { return CheckTy; }
  110. private:
  111. bool AddRegExToRegEx(raw_ostream &OS, StringRef RS, unsigned &CurParen, SourceMgr &SM);
  112. void AddBackrefToRegEx(unsigned BackrefNum);
  113. /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
  114. /// matching this pattern at the start of \arg Buffer; a distance of zero
  115. /// should correspond to a perfect match.
  116. unsigned ComputeMatchDistance(StringRef Buffer,
  117. const StringMap<StringRef> &VariableTable) const;
  118. /// \brief Evaluates expression and stores the result to \p Value.
  119. /// \return true on success. false when the expression has invalid syntax.
  120. bool EvaluateExpression(StringRef Expr, std::string &Value) const;
  121. /// \brief Finds the closing sequence of a regex variable usage or
  122. /// definition. Str has to point in the beginning of the definition
  123. /// (right after the opening sequence).
  124. /// \return offset of the closing sequence within Str, or npos if it was not
  125. /// found.
  126. size_t FindRegexVarEnd(raw_ostream &OS, StringRef Str, SourceMgr &SM);
  127. };
  128. bool Pattern::ParsePattern(raw_ostream &OS, StringRef PatternStr,
  129. StringRef Prefix,
  130. SourceMgr &SM,
  131. unsigned LineNumber) {
  132. this->LineNumber = LineNumber;
  133. PatternLoc = SMLoc::getFromPointer(PatternStr.data());
  134. // Ignore trailing whitespace.
  135. while (!PatternStr.empty() &&
  136. (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
  137. PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
  138. // Check that there is something on the line.
  139. if (PatternStr.empty()) {
  140. SM.PrintMessage(OS, PatternLoc, SourceMgr::DK_Error,
  141. "found empty check string with prefix '" +
  142. Prefix + ":'");
  143. return true;
  144. }
  145. // Check to see if this is a fixed string, or if it has regex pieces.
  146. if (PatternStr.size() < 2 ||
  147. (PatternStr.find("{{") == StringRef::npos &&
  148. PatternStr.find("[[") == StringRef::npos)) {
  149. FixedStr = PatternStr;
  150. return false;
  151. }
  152. // Paren value #0 is for the fully matched string. Any new parenthesized
  153. // values add from there.
  154. unsigned CurParen = 1;
  155. // Otherwise, there is at least one regex piece. Build up the regex pattern
  156. // by escaping scary characters in fixed strings, building up one big regex.
  157. while (!PatternStr.empty()) {
  158. // RegEx matches.
  159. if (PatternStr.startswith("{{")) {
  160. // This is the start of a regex match. Scan for the }}.
  161. size_t End = PatternStr.find("}}");
  162. if (End == StringRef::npos) {
  163. SM.PrintMessage(OS, SMLoc::getFromPointer(PatternStr.data()),
  164. SourceMgr::DK_Error,
  165. "found start of regex string with no end '}}'");
  166. return true;
  167. }
  168. // Enclose {{}} patterns in parens just like [[]] even though we're not
  169. // capturing the result for any purpose. This is required in case the
  170. // expression contains an alternation like: CHECK: abc{{x|z}}def. We
  171. // want this to turn into: "abc(x|z)def" not "abcx|zdef".
  172. RegExStr += '(';
  173. ++CurParen;
  174. if (AddRegExToRegEx(OS, PatternStr.substr(2, End - 2), CurParen, SM))
  175. return true;
  176. RegExStr += ')';
  177. PatternStr = PatternStr.substr(End + 2);
  178. continue;
  179. }
  180. // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
  181. // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
  182. // second form is [[foo]] which is a reference to foo. The variable name
  183. // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
  184. // it. This is to catch some common errors.
  185. if (PatternStr.startswith("[[")) {
  186. // Find the closing bracket pair ending the match. End is going to be an
  187. // offset relative to the beginning of the match string.
  188. size_t End = FindRegexVarEnd(OS, PatternStr.substr(2), SM);
  189. if (End == StringRef::npos) {
  190. SM.PrintMessage(OS, SMLoc::getFromPointer(PatternStr.data()),
  191. SourceMgr::DK_Error,
  192. "invalid named regex reference, no ]] found");
  193. return true;
  194. }
  195. StringRef MatchStr = PatternStr.substr(2, End);
  196. PatternStr = PatternStr.substr(End + 4);
  197. // Get the regex name (e.g. "foo").
  198. size_t NameEnd = MatchStr.find(':');
  199. StringRef Name = MatchStr.substr(0, NameEnd);
  200. if (Name.empty()) {
  201. SM.PrintMessage(OS, SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
  202. "invalid name in named regex: empty name");
  203. return true;
  204. }
  205. // Verify that the name/expression is well formed. FileCheck currently
  206. // supports @LINE, @LINE+number, @LINE-number expressions. The check here
  207. // is relaxed, more strict check is performed in \c EvaluateExpression.
  208. bool IsExpression = false;
  209. for (unsigned i = 0, e = Name.size(); i != e; ++i) {
  210. if (i == 0 && Name[i] == '@') {
  211. if (NameEnd != StringRef::npos) {
  212. SM.PrintMessage(OS, SMLoc::getFromPointer(Name.data()),
  213. SourceMgr::DK_Error,
  214. "invalid name in named regex definition");
  215. return true;
  216. }
  217. IsExpression = true;
  218. continue;
  219. }
  220. if (Name[i] != '_' && !isalnum(Name[i]) &&
  221. (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
  222. SM.PrintMessage(OS, SMLoc::getFromPointer(Name.data() + i),
  223. SourceMgr::DK_Error, "invalid name in named regex");
  224. return true;
  225. }
  226. }
  227. // Name can't start with a digit.
  228. if (isdigit(static_cast<unsigned char>(Name[0]))) {
  229. SM.PrintMessage(OS, SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
  230. "invalid name in named regex");
  231. return true;
  232. }
  233. // Handle [[foo]].
  234. if (NameEnd == StringRef::npos) {
  235. // Handle variables that were defined earlier on the same line by
  236. // emitting a backreference.
  237. if (VariableDefs.find(Name) != VariableDefs.end()) {
  238. unsigned VarParenNum = VariableDefs[Name];
  239. if (VarParenNum < 1 || VarParenNum > 9) {
  240. SM.PrintMessage(OS, SMLoc::getFromPointer(Name.data()),
  241. SourceMgr::DK_Error,
  242. "Can't back-reference more than 9 variables");
  243. return true;
  244. }
  245. AddBackrefToRegEx(VarParenNum);
  246. }
  247. else {
  248. VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
  249. }
  250. continue;
  251. }
  252. // Handle [[foo:.*]].
  253. VariableDefs[Name] = CurParen;
  254. RegExStr += '(';
  255. ++CurParen;
  256. if (AddRegExToRegEx(OS, MatchStr.substr(NameEnd + 1), CurParen, SM))
  257. return true;
  258. RegExStr += ')';
  259. }
  260. // Handle fixed string matches.
  261. // Find the end, which is the start of the next regex.
  262. size_t FixedMatchEnd = PatternStr.find("{{");
  263. FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
  264. RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
  265. PatternStr = PatternStr.substr(FixedMatchEnd);
  266. }
  267. return false;
  268. }
  269. bool Pattern::AddRegExToRegEx(raw_ostream &OS, StringRef RS, unsigned &CurParen,
  270. SourceMgr &SM) {
  271. Regex R(RS);
  272. std::string Error;
  273. if (!R.isValid(Error)) {
  274. SM.PrintMessage(OS, SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
  275. "invalid regex: " + Error);
  276. return true;
  277. }
  278. RegExStr += RS.str();
  279. CurParen += R.getNumMatches();
  280. return false;
  281. }
  282. void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
  283. assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
  284. std::string Backref = std::string("\\") +
  285. std::string(1, '0' + BackrefNum);
  286. RegExStr += Backref;
  287. }
  288. bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
  289. // The only supported expression is @LINE([\+-]\d+)?
  290. if (!Expr.startswith("@LINE"))
  291. return false;
  292. Expr = Expr.substr(StringRef("@LINE").size());
  293. int Offset = 0;
  294. if (!Expr.empty()) {
  295. if (Expr[0] == '+')
  296. Expr = Expr.substr(1);
  297. else if (Expr[0] != '-')
  298. return false;
  299. if (Expr.getAsInteger(10, Offset))
  300. return false;
  301. }
  302. Value = llvm::itostr(LineNumber + Offset);
  303. return true;
  304. }
  305. /// Match - Match the pattern string against the input buffer Buffer. This
  306. /// returns the position that is matched or npos if there is no match. If
  307. /// there is a match, the size of the matched string is returned in MatchLen.
  308. size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
  309. StringMap<StringRef> &VariableTable) const {
  310. // If this is the EOF pattern, match it immediately.
  311. if (CheckTy == Check::CheckEOF) {
  312. MatchLen = 0;
  313. return Buffer.size();
  314. }
  315. // If this is a fixed string pattern, just match it now.
  316. if (!FixedStr.empty()) {
  317. MatchLen = FixedStr.size();
  318. return Buffer.find(FixedStr);
  319. }
  320. // Regex match.
  321. // If there are variable uses, we need to create a temporary string with the
  322. // actual value.
  323. StringRef RegExToMatch = RegExStr;
  324. std::string TmpStr;
  325. if (!VariableUses.empty()) {
  326. TmpStr = RegExStr;
  327. unsigned InsertOffset = 0;
  328. for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
  329. std::string Value;
  330. if (VariableUses[i].first[0] == '@') {
  331. if (!EvaluateExpression(VariableUses[i].first, Value))
  332. return StringRef::npos;
  333. }
  334. else {
  335. StringMap<StringRef>::iterator it =
  336. VariableTable.find(VariableUses[i].first);
  337. // If the variable is undefined, return an error.
  338. if (it == VariableTable.end())
  339. return StringRef::npos;
  340. // Look up the value and escape it so that we can put it into the regex.
  341. Value += Regex::escape(it->second);
  342. }
  343. // Plop it into the regex at the adjusted offset.
  344. TmpStr.insert(TmpStr.begin() + VariableUses[i].second + InsertOffset,
  345. Value.begin(), Value.end());
  346. InsertOffset += Value.size();
  347. }
  348. // Match the newly constructed regex.
  349. RegExToMatch = TmpStr;
  350. }
  351. SmallVector<StringRef, 4> MatchInfo;
  352. if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
  353. return StringRef::npos;
  354. // Successful regex match.
  355. assert(!MatchInfo.empty() && "Didn't get any match");
  356. StringRef FullMatch = MatchInfo[0];
  357. // If this defines any variables, remember their values.
  358. for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(),
  359. E = VariableDefs.end();
  360. I != E; ++I) {
  361. assert(I->second < MatchInfo.size() && "Internal paren error");
  362. VariableTable[I->first] = MatchInfo[I->second];
  363. }
  364. MatchLen = FullMatch.size();
  365. return FullMatch.data() - Buffer.data();
  366. }
  367. unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
  368. const StringMap<StringRef> &VariableTable) const {
  369. // Just compute the number of matching characters. For regular expressions, we
  370. // just compare against the regex itself and hope for the best.
  371. //
  372. // FIXME: One easy improvement here is have the regex lib generate a single
  373. // example regular expression which matches, and use that as the example
  374. // string.
  375. StringRef ExampleString(FixedStr);
  376. if (ExampleString.empty())
  377. ExampleString = RegExStr;
  378. // Only compare up to the first line in the buffer, or the string size.
  379. StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
  380. BufferPrefix = BufferPrefix.split('\n').first;
  381. return BufferPrefix.edit_distance(ExampleString);
  382. }
  383. void Pattern::PrintFailureInfo(raw_ostream &ErrOS, const SourceMgr &SM, StringRef Buffer,
  384. const StringMap<StringRef> &VariableTable) const {
  385. // If this was a regular expression using variables, print the current
  386. // variable values.
  387. if (!VariableUses.empty()) {
  388. for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
  389. SmallString<256> Msg;
  390. raw_svector_ostream OS(Msg);
  391. StringRef Var = VariableUses[i].first;
  392. if (Var[0] == '@') {
  393. std::string Value;
  394. if (EvaluateExpression(Var, Value)) {
  395. OS << "with expression \"";
  396. OS.write_escaped(Var) << "\" equal to \"";
  397. OS.write_escaped(Value) << "\"";
  398. }
  399. else {
  400. OS << "uses incorrect expression \"";
  401. OS.write_escaped(Var) << "\"";
  402. }
  403. }
  404. else {
  405. StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
  406. // Check for undefined variable references.
  407. if (it == VariableTable.end()) {
  408. OS << "uses undefined variable \"";
  409. OS.write_escaped(Var) << "\"";
  410. }
  411. else {
  412. OS << "with variable \"";
  413. OS.write_escaped(Var) << "\" equal to \"";
  414. OS.write_escaped(it->second) << "\"";
  415. }
  416. }
  417. SM.PrintMessage(ErrOS, SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
  418. OS.str());
  419. }
  420. }
  421. // Attempt to find the closest/best fuzzy match. Usually an error happens
  422. // because some string in the output didn't exactly match. In these cases, we
  423. // would like to show the user a best guess at what "should have" matched, to
  424. // save them having to actually check the input manually.
  425. size_t NumLinesForward = 0;
  426. size_t Best = StringRef::npos;
  427. double BestQuality = 0;
  428. // Use an arbitrary 4k limit on how far we will search.
  429. for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
  430. if (Buffer[i] == '\n')
  431. ++NumLinesForward;
  432. // Patterns have leading whitespace stripped, so skip whitespace when
  433. // looking for something which looks like a pattern.
  434. if (Buffer[i] == ' ' || Buffer[i] == '\t')
  435. continue;
  436. // Compute the "quality" of this match as an arbitrary combination of the
  437. // match distance and the number of lines skipped to get to this match.
  438. unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
  439. double Quality = Distance + (NumLinesForward / 100.);
  440. if (Quality < BestQuality || Best == StringRef::npos) {
  441. Best = i;
  442. BestQuality = Quality;
  443. }
  444. }
  445. // Print the "possible intended match here" line if we found something
  446. // reasonable and not equal to what we showed in the "scanning from here"
  447. // line.
  448. if (Best && Best != StringRef::npos && BestQuality < 50) {
  449. SM.PrintMessage(ErrOS, SMLoc::getFromPointer(Buffer.data() + Best),
  450. SourceMgr::DK_Note, "possible intended match here");
  451. // FIXME: If we wanted to be really friendly we would show why the match
  452. // failed, as it can be hard to spot simple one character differences.
  453. }
  454. }
  455. size_t Pattern::FindRegexVarEnd(raw_ostream &OS, StringRef Str, SourceMgr &SM) {
  456. // Offset keeps track of the current offset within the input Str
  457. size_t Offset = 0;
  458. // [...] Nesting depth
  459. size_t BracketDepth = 0;
  460. while (!Str.empty()) {
  461. if (Str.startswith("]]") && BracketDepth == 0)
  462. return Offset;
  463. if (Str[0] == '\\') {
  464. // Backslash escapes the next char within regexes, so skip them both.
  465. Str = Str.substr(2);
  466. Offset += 2;
  467. }
  468. else {
  469. switch (Str[0]) {
  470. default:
  471. break;
  472. case '[':
  473. BracketDepth++;
  474. break;
  475. case ']':
  476. if (BracketDepth == 0) {
  477. SM.PrintMessage(OS, SMLoc::getFromPointer(Str.data()),
  478. SourceMgr::DK_Error,
  479. "missing closing \"]\" for regex variable");
  480. exit(1);
  481. }
  482. BracketDepth--;
  483. break;
  484. }
  485. Str = Str.substr(1);
  486. Offset++;
  487. }
  488. }
  489. return StringRef::npos;
  490. }
  491. //===----------------------------------------------------------------------===//
  492. // Check Strings.
  493. //===----------------------------------------------------------------------===//
  494. /// CheckString - This is a check that we found in the input file.
  495. struct CheckString {
  496. /// Pat - The pattern to match.
  497. Pattern Pat;
  498. /// Prefix - Which prefix name this check matched.
  499. StringRef Prefix;
  500. /// Loc - The location in the match file that the check string was specified.
  501. SMLoc Loc;
  502. /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
  503. /// as opposed to a CHECK: directive.
  504. Check::CheckType CheckTy;
  505. /// DagNotStrings - These are all of the strings that are disallowed from
  506. /// occurring between this match string and the previous one (or start of
  507. /// file).
  508. std::vector<Pattern> DagNotStrings;
  509. CheckString(const Pattern &P,
  510. StringRef S,
  511. SMLoc L,
  512. Check::CheckType Ty)
  513. : Pat(P), Prefix(S), Loc(L), CheckTy(Ty) {}
  514. /// Check - Match check string and its "not strings" and/or "dag strings".
  515. size_t Check(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
  516. size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
  517. /// CheckNext - Verify there is a single line in the given buffer.
  518. bool CheckNext(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer) const;
  519. /// CheckSame - Verify there is no newline in the given buffer.
  520. bool CheckSame(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer) const;
  521. /// CheckNot - Verify there's no "not strings" in the given buffer.
  522. bool CheckNot(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  523. const std::vector<const Pattern *> &NotStrings,
  524. StringMap<StringRef> &VariableTable) const;
  525. /// CheckDag - Match "dag strings" and their mixed "not strings".
  526. size_t CheckDag(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  527. std::vector<const Pattern *> &NotStrings,
  528. StringMap<StringRef> &VariableTable) const;
  529. };
  530. /// Canonicalize whitespaces in the input file. Line endings are replaced
  531. /// with UNIX-style '\n'.
  532. ///
  533. /// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
  534. /// characters to a single space.
  535. static std::unique_ptr<MemoryBuffer>
  536. CanonicalizeInputFile(std::unique_ptr<MemoryBuffer> MB,
  537. bool PreserveHorizontal) {
  538. SmallString<128> NewFile;
  539. NewFile.reserve(MB->getBufferSize());
  540. for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
  541. Ptr != End; ++Ptr) {
  542. // Eliminate trailing dosish \r.
  543. if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
  544. continue;
  545. }
  546. // If current char is not a horizontal whitespace or if horizontal
  547. // whitespace canonicalization is disabled, dump it to output as is.
  548. if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
  549. NewFile.push_back(*Ptr);
  550. continue;
  551. }
  552. // Otherwise, add one space and advance over neighboring space.
  553. NewFile.push_back(' ');
  554. while (Ptr + 1 != End &&
  555. (Ptr[1] == ' ' || Ptr[1] == '\t'))
  556. ++Ptr;
  557. }
  558. return std::unique_ptr<MemoryBuffer>(
  559. MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier()));
  560. }
  561. static bool IsPartOfWord(char c) {
  562. return (isalnum(c) || c == '-' || c == '_');
  563. }
  564. // Get the size of the prefix extension.
  565. static size_t CheckTypeSize(Check::CheckType Ty) {
  566. switch (Ty) {
  567. case Check::CheckNone:
  568. return 0;
  569. case Check::CheckPlain:
  570. return sizeof(":") - 1;
  571. case Check::CheckNext:
  572. return sizeof("-NEXT:") - 1;
  573. case Check::CheckSame:
  574. return sizeof("-SAME:") - 1;
  575. case Check::CheckNot:
  576. return sizeof("-NOT:") - 1;
  577. case Check::CheckDAG:
  578. return sizeof("-DAG:") - 1;
  579. case Check::CheckLabel:
  580. return sizeof("-LABEL:") - 1;
  581. case Check::CheckEOF:
  582. llvm_unreachable("Should not be using EOF size");
  583. }
  584. llvm_unreachable("Bad check type");
  585. }
  586. static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
  587. char NextChar = Buffer[Prefix.size()];
  588. // Verify that the : is present after the prefix.
  589. if (NextChar == ':')
  590. return Check::CheckPlain;
  591. if (NextChar != '-')
  592. return Check::CheckNone;
  593. StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
  594. if (Rest.startswith("NEXT:"))
  595. return Check::CheckNext;
  596. if (Rest.startswith("SAME:"))
  597. return Check::CheckSame;
  598. if (Rest.startswith("NOT:"))
  599. return Check::CheckNot;
  600. if (Rest.startswith("DAG:"))
  601. return Check::CheckDAG;
  602. if (Rest.startswith("LABEL:"))
  603. return Check::CheckLabel;
  604. return Check::CheckNone;
  605. }
  606. // From the given position, find the next character after the word.
  607. static size_t SkipWord(StringRef Str, size_t Loc) {
  608. while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
  609. ++Loc;
  610. return Loc;
  611. }
  612. // Try to find the first match in buffer for any prefix. If a valid match is
  613. // found, return that prefix and set its type and location. If there are almost
  614. // matches (e.g. the actual prefix string is found, but is not an actual check
  615. // string), but no valid match, return an empty string and set the position to
  616. // resume searching from. If no partial matches are found, return an empty
  617. // string and the location will be StringRef::npos. If one prefix is a substring
  618. // of another, the maximal match should be found. e.g. if "A" and "AA" are
  619. // prefixes then AA-CHECK: should match the second one.
  620. StringRef FindFirstCandidateMatch(StringRef &Buffer,
  621. Check::CheckType &CheckTy,
  622. size_t &CheckLoc,
  623. const std::vector<std::string> &CheckPrefixes) {
  624. StringRef FirstPrefix;
  625. size_t FirstLoc = StringRef::npos;
  626. size_t SearchLoc = StringRef::npos;
  627. Check::CheckType FirstTy = Check::CheckNone;
  628. CheckTy = Check::CheckNone;
  629. CheckLoc = StringRef::npos;
  630. for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
  631. I != E; ++I) {
  632. StringRef Prefix(*I);
  633. size_t PrefixLoc = Buffer.find(Prefix);
  634. if (PrefixLoc == StringRef::npos)
  635. continue;
  636. // Track where we are searching for invalid prefixes that look almost right.
  637. // We need to only advance to the first partial match on the next attempt
  638. // since a partial match could be a substring of a later, valid prefix.
  639. // Need to skip to the end of the word, otherwise we could end up
  640. // matching a prefix in a substring later.
  641. if (PrefixLoc < SearchLoc)
  642. SearchLoc = SkipWord(Buffer, PrefixLoc);
  643. // We only want to find the first match to avoid skipping some.
  644. if (PrefixLoc > FirstLoc)
  645. continue;
  646. // If one matching check-prefix is a prefix of another, choose the
  647. // longer one.
  648. if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
  649. continue;
  650. StringRef Rest = Buffer.drop_front(PrefixLoc);
  651. // Make sure we have actually found the prefix, and not a word containing
  652. // it. This should also prevent matching the wrong prefix when one is a
  653. // substring of another.
  654. if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
  655. FirstTy = Check::CheckNone;
  656. else
  657. FirstTy = FindCheckType(Rest, Prefix);
  658. FirstLoc = PrefixLoc;
  659. FirstPrefix = Prefix;
  660. }
  661. // If the first prefix is invalid, we should continue the search after it.
  662. if (FirstTy == Check::CheckNone) {
  663. CheckLoc = SearchLoc;
  664. return "";
  665. }
  666. CheckTy = FirstTy;
  667. CheckLoc = FirstLoc;
  668. return FirstPrefix;
  669. }
  670. static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
  671. unsigned &LineNumber,
  672. Check::CheckType &CheckTy,
  673. size_t &CheckLoc,
  674. const std::vector<std::string> &CheckPrefixes) {
  675. while (!Buffer.empty()) {
  676. StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc, CheckPrefixes);
  677. // If we found a real match, we are done.
  678. if (!Prefix.empty()) {
  679. LineNumber += Buffer.substr(0, CheckLoc).count('\n');
  680. return Prefix;
  681. }
  682. // We didn't find any almost matches either, we are also done.
  683. if (CheckLoc == StringRef::npos)
  684. return StringRef();
  685. LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
  686. // Advance to the last possible match we found and try again.
  687. Buffer = Buffer.drop_front(CheckLoc + 1);
  688. }
  689. return StringRef();
  690. }
  691. static void PrintCheckFailed(raw_ostream &OS, const SourceMgr &SM, const SMLoc &Loc,
  692. const Pattern &Pat, StringRef Buffer,
  693. StringMap<StringRef> &VariableTable) {
  694. // Otherwise, we have an error, emit an error message.
  695. SM.PrintMessage(OS, Loc, SourceMgr::DK_Error,
  696. "expected string not found in input");
  697. // Print the "scanning from here" line. If the current position is at the
  698. // end of a line, advance to the start of the next line.
  699. Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
  700. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
  701. "scanning from here");
  702. // Allow the pattern to print additional information if desired.
  703. Pat.PrintFailureInfo(OS, SM, Buffer, VariableTable);
  704. }
  705. static void PrintCheckFailed(raw_ostream &OS, const SourceMgr &SM, const CheckString &CheckStr,
  706. StringRef Buffer,
  707. StringMap<StringRef> &VariableTable) {
  708. PrintCheckFailed(OS, SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
  709. }
  710. /// CountNumNewlinesBetween - Count the number of newlines in the specified
  711. /// range.
  712. static unsigned CountNumNewlinesBetween(StringRef Range,
  713. const char *&FirstNewLine) {
  714. unsigned NumNewLines = 0;
  715. while (1) {
  716. // Scan for newline.
  717. Range = Range.substr(Range.find_first_of("\n\r"));
  718. if (Range.empty()) return NumNewLines;
  719. ++NumNewLines;
  720. // Handle \n\r and \r\n as a single newline.
  721. if (Range.size() > 1 &&
  722. (Range[1] == '\n' || Range[1] == '\r') &&
  723. (Range[0] != Range[1]))
  724. Range = Range.substr(1);
  725. Range = Range.substr(1);
  726. if (NumNewLines == 1)
  727. FirstNewLine = Range.begin();
  728. }
  729. }
  730. size_t CheckString::Check(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  731. bool IsLabelScanMode, size_t &MatchLen,
  732. StringMap<StringRef> &VariableTable) const {
  733. size_t LastPos = 0;
  734. std::vector<const Pattern *> NotStrings;
  735. // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
  736. // bounds; we have not processed variable definitions within the bounded block
  737. // yet so cannot handle any final CHECK-DAG yet; this is handled when going
  738. // over the block again (including the last CHECK-LABEL) in normal mode.
  739. if (!IsLabelScanMode) {
  740. // Match "dag strings" (with mixed "not strings" if any).
  741. LastPos = CheckDag(OS, SM, Buffer, NotStrings, VariableTable);
  742. if (LastPos == StringRef::npos)
  743. return StringRef::npos;
  744. }
  745. // Match itself from the last position after matching CHECK-DAG.
  746. StringRef MatchBuffer = Buffer.substr(LastPos);
  747. size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
  748. if (MatchPos == StringRef::npos) {
  749. PrintCheckFailed(OS, SM, *this, MatchBuffer, VariableTable);
  750. return StringRef::npos;
  751. }
  752. // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
  753. // or CHECK-NOT
  754. if (!IsLabelScanMode) {
  755. StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
  756. // If this check is a "CHECK-NEXT", verify that the previous match was on
  757. // the previous line (i.e. that there is one newline between them).
  758. if (CheckNext(OS, SM, SkippedRegion))
  759. return StringRef::npos;
  760. // If this check is a "CHECK-SAME", verify that the previous match was on
  761. // the same line (i.e. that there is no newline between them).
  762. if (CheckSame(OS, SM, SkippedRegion))
  763. return StringRef::npos;
  764. // If this match had "not strings", verify that they don't exist in the
  765. // skipped region.
  766. if (CheckNot(OS, SM, SkippedRegion, NotStrings, VariableTable))
  767. return StringRef::npos;
  768. }
  769. return LastPos + MatchPos;
  770. }
  771. bool CheckString::CheckNext(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer) const {
  772. if (CheckTy != Check::CheckNext)
  773. return false;
  774. // Count the number of newlines between the previous match and this one.
  775. assert(Buffer.data() !=
  776. SM.getMemoryBuffer(
  777. SM.FindBufferContainingLoc(
  778. SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
  779. "CHECK-NEXT can't be the first check in a file");
  780. const char *FirstNewLine = nullptr;
  781. unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
  782. if (NumNewLines == 0) {
  783. SM.PrintMessage(OS, Loc, SourceMgr::DK_Error, Prefix +
  784. "-NEXT: is on the same line as previous match");
  785. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.end()),
  786. SourceMgr::DK_Note, "'next' match was here");
  787. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
  788. "previous match ended here");
  789. return true;
  790. }
  791. if (NumNewLines != 1) {
  792. SM.PrintMessage(OS, Loc, SourceMgr::DK_Error, Prefix +
  793. "-NEXT: is not on the line after the previous match");
  794. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.end()),
  795. SourceMgr::DK_Note, "'next' match was here");
  796. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
  797. "previous match ended here");
  798. SM.PrintMessage(OS, SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
  799. "non-matching line after previous match is here");
  800. return true;
  801. }
  802. return false;
  803. }
  804. bool CheckString::CheckSame(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer) const {
  805. if (CheckTy != Check::CheckSame)
  806. return false;
  807. // Count the number of newlines between the previous match and this one.
  808. assert(Buffer.data() !=
  809. SM.getMemoryBuffer(SM.FindBufferContainingLoc(
  810. SMLoc::getFromPointer(Buffer.data())))
  811. ->getBufferStart() &&
  812. "CHECK-SAME can't be the first check in a file");
  813. const char *FirstNewLine = nullptr;
  814. unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
  815. if (NumNewLines != 0) {
  816. SM.PrintMessage(OS, Loc, SourceMgr::DK_Error,
  817. Prefix +
  818. "-SAME: is not on the same line as the previous match");
  819. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
  820. "'next' match was here");
  821. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
  822. "previous match ended here");
  823. return true;
  824. }
  825. return false;
  826. }
  827. bool CheckString::CheckNot(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  828. const std::vector<const Pattern *> &NotStrings,
  829. StringMap<StringRef> &VariableTable) const {
  830. for (unsigned ChunkNo = 0, e = NotStrings.size();
  831. ChunkNo != e; ++ChunkNo) {
  832. const Pattern *Pat = NotStrings[ChunkNo];
  833. assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
  834. size_t MatchLen = 0;
  835. size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
  836. if (Pos == StringRef::npos) continue;
  837. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data() + Pos),
  838. SourceMgr::DK_Error,
  839. Prefix + "-NOT: string occurred!");
  840. SM.PrintMessage(OS, Pat->getLoc(), SourceMgr::DK_Note,
  841. Prefix + "-NOT: pattern specified here");
  842. return true;
  843. }
  844. return false;
  845. }
  846. size_t CheckString::CheckDag(raw_ostream &OS, const SourceMgr &SM, StringRef Buffer,
  847. std::vector<const Pattern *> &NotStrings,
  848. StringMap<StringRef> &VariableTable) const {
  849. if (DagNotStrings.empty())
  850. return 0;
  851. size_t LastPos = 0;
  852. size_t StartPos = LastPos;
  853. for (unsigned ChunkNo = 0, e = DagNotStrings.size();
  854. ChunkNo != e; ++ChunkNo) {
  855. const Pattern &Pat = DagNotStrings[ChunkNo];
  856. assert((Pat.getCheckTy() == Check::CheckDAG ||
  857. Pat.getCheckTy() == Check::CheckNot) &&
  858. "Invalid CHECK-DAG or CHECK-NOT!");
  859. if (Pat.getCheckTy() == Check::CheckNot) {
  860. NotStrings.push_back(&Pat);
  861. continue;
  862. }
  863. assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
  864. size_t MatchLen = 0, MatchPos;
  865. // CHECK-DAG always matches from the start.
  866. StringRef MatchBuffer = Buffer.substr(StartPos);
  867. MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
  868. // With a group of CHECK-DAGs, a single mismatching means the match on
  869. // that group of CHECK-DAGs fails immediately.
  870. if (MatchPos == StringRef::npos) {
  871. PrintCheckFailed(OS, SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
  872. return StringRef::npos;
  873. }
  874. // Re-calc it as the offset relative to the start of the original string.
  875. MatchPos += StartPos;
  876. if (!NotStrings.empty()) {
  877. if (MatchPos < LastPos) {
  878. // Reordered?
  879. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data() + MatchPos),
  880. SourceMgr::DK_Error,
  881. Prefix + "-DAG: found a match of CHECK-DAG"
  882. " reordering across a CHECK-NOT");
  883. SM.PrintMessage(OS, SMLoc::getFromPointer(Buffer.data() + LastPos),
  884. SourceMgr::DK_Note,
  885. Prefix + "-DAG: the farthest match of CHECK-DAG"
  886. " is found here");
  887. SM.PrintMessage(OS, NotStrings[0]->getLoc(), SourceMgr::DK_Note,
  888. Prefix + "-NOT: the crossed pattern specified"
  889. " here");
  890. SM.PrintMessage(OS, Pat.getLoc(), SourceMgr::DK_Note,
  891. Prefix + "-DAG: the reordered pattern specified"
  892. " here");
  893. return StringRef::npos;
  894. }
  895. // All subsequent CHECK-DAGs should be matched from the farthest
  896. // position of all precedent CHECK-DAGs (including this one.)
  897. StartPos = LastPos;
  898. // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
  899. // CHECK-DAG, verify that there's no 'not' strings occurred in that
  900. // region.
  901. StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
  902. if (CheckNot(OS, SM, SkippedRegion, NotStrings, VariableTable))
  903. return StringRef::npos;
  904. // Clear "not strings".
  905. NotStrings.clear();
  906. }
  907. // Update the last position with CHECK-DAG matches.
  908. LastPos = std::max(MatchPos + MatchLen, LastPos);
  909. }
  910. return LastPos;
  911. }
  912. class FileCheckForTestImpl {
  913. public:
  914. std::string CheckFilename;
  915. /// File to check (defaults to stdin)
  916. std::string InputFilename;
  917. /// Prefix to use from check file (defaults to 'CHECK')
  918. std::vector<std::string> CheckPrefixes;
  919. /// Do not treat all horizontal whitespace as equivalent
  920. bool NoCanonicalizeWhiteSpace;
  921. /// Add an implicit negative check with this pattern to every
  922. /// positive check. This can be used to ensure that no instances of
  923. /// this pattern occur which are not matched by a positive pattern
  924. std::vector<std::string> ImplicitCheckNot;
  925. /// Allow the input file to be empty. This is useful when making
  926. /// checks that some error message does not occur, for example.
  927. bool AllowEmptyInput;
  928. /// String to read in place of standard input.
  929. std::string InputForStdin;
  930. /// Output stream.
  931. std::string test_outs_str;
  932. llvm::raw_string_ostream test_outs;
  933. /// Error stream.
  934. std::string test_errs_str;
  935. llvm::raw_string_ostream test_errs;
  936. FileCheckForTestImpl() : test_outs(test_outs_str), test_errs(test_errs_str) {}
  937. // A check prefix must contain only alphanumeric, hyphens and underscores.
  938. static bool ValidateCheckPrefix(StringRef CheckPrefix) {
  939. Regex Validator("^[a-zA-Z0-9_-]*$");
  940. return Validator.match(CheckPrefix);
  941. }
  942. bool ValidateCheckPrefixes() {
  943. StringSet<> PrefixSet;
  944. for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
  945. I != E; ++I) {
  946. StringRef Prefix(*I);
  947. // Reject empty prefixes.
  948. if (Prefix == "")
  949. return false;
  950. if (!PrefixSet.insert(Prefix).second)
  951. return false;
  952. if (!ValidateCheckPrefix(Prefix))
  953. return false;
  954. }
  955. return true;
  956. }
  957. // I don't think there's a way to specify an initial value for cl::list,
  958. // so if nothing was specified, add the default
  959. void AddCheckPrefixIfNeeded() {
  960. if (CheckPrefixes.empty())
  961. CheckPrefixes.push_back("CHECK");
  962. }
  963. /// ReadCheckFile - Read the check file, which specifies the sequence of
  964. /// expected strings. The strings are added to the CheckStrings vector.
  965. /// Returns true in case of an error, false otherwise.
  966. bool ReadCheckFile(SourceMgr &SM,
  967. std::vector<CheckString> &CheckStrings) {
  968. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
  969. MemoryBuffer::getFileOrSTDIN(CheckFilename);
  970. if (std::error_code EC = FileOrErr.getError()) {
  971. test_errs << "Could not open check file '" << CheckFilename
  972. << "': " << EC.message() << '\n';
  973. return true;
  974. }
  975. // If we want to canonicalize whitespace, strip excess whitespace from the
  976. // buffer containing the CHECK lines. Remove DOS style line endings.
  977. std::unique_ptr<MemoryBuffer> F = CanonicalizeInputFile(
  978. std::move(FileOrErr.get()), NoCanonicalizeWhiteSpace);
  979. // Find all instances of CheckPrefix followed by : in the file.
  980. StringRef Buffer = F->getBuffer();
  981. SM.AddNewSourceBuffer(std::move(F), SMLoc());
  982. std::vector<Pattern> ImplicitNegativeChecks;
  983. for (const auto &PatternString : ImplicitCheckNot) {
  984. // Create a buffer with fake command line content in order to display the
  985. // command line option responsible for the specific implicit CHECK-NOT.
  986. std::string Prefix = std::string("-") + /*ImplicitCheckNot.ArgStr + */"='";
  987. std::string Suffix = "'";
  988. std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
  989. Prefix + PatternString + Suffix, "command line");
  990. StringRef PatternInBuffer =
  991. CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
  992. SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
  993. ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
  994. ImplicitNegativeChecks.back().ParsePattern(test_errs, PatternInBuffer,
  995. "IMPLICIT-CHECK", SM, 0);
  996. }
  997. std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
  998. // LineNumber keeps track of the line on which CheckPrefix instances are
  999. // found.
  1000. unsigned LineNumber = 1;
  1001. while (1) {
  1002. Check::CheckType CheckTy;
  1003. size_t PrefixLoc;
  1004. // See if a prefix occurs in the memory buffer.
  1005. StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
  1006. LineNumber,
  1007. CheckTy,
  1008. PrefixLoc, CheckPrefixes);
  1009. if (UsedPrefix.empty())
  1010. break;
  1011. Buffer = Buffer.drop_front(PrefixLoc);
  1012. // Location to use for error messages.
  1013. const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
  1014. // PrefixLoc is to the start of the prefix. Skip to the end.
  1015. Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
  1016. // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
  1017. // leading and trailing whitespace.
  1018. Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
  1019. // Scan ahead to the end of line.
  1020. size_t EOL = Buffer.find_first_of("\n\r");
  1021. // Remember the location of the start of the pattern, for diagnostics.
  1022. SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
  1023. // Parse the pattern.
  1024. Pattern P(CheckTy);
  1025. if (P.ParsePattern(test_errs, Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
  1026. return true;
  1027. // Verify that CHECK-LABEL lines do not define or use variables
  1028. if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
  1029. SM.PrintMessage(test_errs, SMLoc::getFromPointer(UsedPrefixStart),
  1030. SourceMgr::DK_Error,
  1031. "found '" + UsedPrefix + "-LABEL:'"
  1032. " with variable definition or use");
  1033. return true;
  1034. }
  1035. Buffer = Buffer.substr(EOL);
  1036. // Verify that CHECK-NEXT lines have at least one CHECK line before them.
  1037. if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
  1038. CheckStrings.empty()) {
  1039. StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
  1040. SM.PrintMessage(test_errs, SMLoc::getFromPointer(UsedPrefixStart),
  1041. SourceMgr::DK_Error,
  1042. "found '" + UsedPrefix + "-" + Type + "' without previous '"
  1043. + UsedPrefix + ": line");
  1044. return true;
  1045. }
  1046. // Handle CHECK-DAG/-NOT.
  1047. if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
  1048. DagNotMatches.push_back(P);
  1049. continue;
  1050. }
  1051. // Okay, add the string we captured to the output vector and move on.
  1052. CheckStrings.emplace_back(P, UsedPrefix, PatternLoc, CheckTy);
  1053. std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
  1054. DagNotMatches = ImplicitNegativeChecks;
  1055. }
  1056. // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
  1057. // prefix as a filler for the error message.
  1058. if (!DagNotMatches.empty()) {
  1059. CheckStrings.emplace_back(Pattern(Check::CheckEOF), *CheckPrefixes.begin(),
  1060. SMLoc::getFromPointer(Buffer.data()),
  1061. Check::CheckEOF);
  1062. std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
  1063. }
  1064. if (CheckStrings.empty()) {
  1065. test_errs << "error: no check strings found with prefix"
  1066. << (CheckPrefixes.size() > 1 ? "es " : " ");
  1067. prefix_iterator I = CheckPrefixes.begin();
  1068. prefix_iterator E = CheckPrefixes.end();
  1069. if (I != E) {
  1070. test_errs << "\'" << *I << ":'";
  1071. ++I;
  1072. }
  1073. for (; I != E; ++I)
  1074. test_errs << ", \'" << *I << ":'";
  1075. test_errs << '\n';
  1076. return true;
  1077. }
  1078. return false;
  1079. }
  1080. int run_main() {
  1081. // HLSL Change Starts
  1082. llvm::sys::fs::MSFileSystem* msfPtr;
  1083. HRESULT hr;
  1084. if (!SUCCEEDED(hr = CreateMSFileSystemForDisk(&msfPtr)))
  1085. return 1;
  1086. std::unique_ptr<llvm::sys::fs::MSFileSystem> msf(msfPtr);
  1087. llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
  1088. // HLSL Change Ends
  1089. if (!ValidateCheckPrefixes()) {
  1090. test_errs << "Supplied check-prefix is invalid! Prefixes must be unique and "
  1091. "start with a letter and contain only alphanumeric characters, "
  1092. "hyphens and underscores\n";
  1093. return 2;
  1094. }
  1095. AddCheckPrefixIfNeeded();
  1096. SourceMgr SM;
  1097. // Read the expected strings from the check file.
  1098. std::vector<CheckString> CheckStrings;
  1099. if (ReadCheckFile(SM, CheckStrings))
  1100. return 2;
  1101. // Open the file to check and add it to SourceMgr.
  1102. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
  1103. InputFilename.size() == 0 ?
  1104. MemoryBuffer::getMemBuffer(MemoryBufferRef(StringRef(InputForStdin), "-")) :
  1105. MemoryBuffer::getFile(InputFilename);
  1106. if (std::error_code EC = FileOrErr.getError()) {
  1107. errs() << "Could not open input file '" << InputFilename
  1108. << "': " << EC.message() << '\n';
  1109. return 2;
  1110. }
  1111. std::unique_ptr<MemoryBuffer> &File = FileOrErr.get();
  1112. if (File->getBufferSize() == 0 && !AllowEmptyInput) {
  1113. errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
  1114. return 2;
  1115. }
  1116. // Remove duplicate spaces in the input file if requested.
  1117. // Remove DOS style line endings.
  1118. std::unique_ptr<MemoryBuffer> F =
  1119. CanonicalizeInputFile(std::move(File), NoCanonicalizeWhiteSpace);
  1120. // Check that we have all of the expected strings, in order, in the input
  1121. // file.
  1122. StringRef Buffer = F->getBuffer();
  1123. SM.AddNewSourceBuffer(std::move(F), SMLoc());
  1124. /// VariableTable - This holds all the current filecheck variables.
  1125. StringMap<StringRef> VariableTable;
  1126. bool hasError = false;
  1127. unsigned i = 0, j = 0, e = CheckStrings.size();
  1128. while (true) {
  1129. StringRef CheckRegion;
  1130. if (j == e) {
  1131. CheckRegion = Buffer;
  1132. }
  1133. else {
  1134. const CheckString &CheckLabelStr = CheckStrings[j];
  1135. if (CheckLabelStr.CheckTy != Check::CheckLabel) {
  1136. ++j;
  1137. continue;
  1138. }
  1139. // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
  1140. size_t MatchLabelLen = 0;
  1141. size_t MatchLabelPos = CheckLabelStr.Check(test_errs, SM, Buffer, true,
  1142. MatchLabelLen, VariableTable);
  1143. if (MatchLabelPos == StringRef::npos) {
  1144. hasError = true;
  1145. break;
  1146. }
  1147. CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
  1148. Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
  1149. ++j;
  1150. }
  1151. for (; i != j; ++i) {
  1152. const CheckString &CheckStr = CheckStrings[i];
  1153. // Check each string within the scanned region, including a second check
  1154. // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
  1155. size_t MatchLen = 0;
  1156. size_t MatchPos = CheckStr.Check(test_errs, SM, CheckRegion, false, MatchLen,
  1157. VariableTable);
  1158. if (MatchPos == StringRef::npos) {
  1159. hasError = true;
  1160. i = j;
  1161. break;
  1162. }
  1163. CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
  1164. }
  1165. if (j == e)
  1166. break;
  1167. }
  1168. return hasError ? 1 : 0;
  1169. }
  1170. }; // class FileCheckForTestImpl
  1171. FileCheckForTest::FileCheckForTest() {
  1172. AllowEmptyInput = false;
  1173. NoCanonicalizeWhiteSpace = false;
  1174. }
  1175. int FileCheckForTest::Run() {
  1176. FileCheckForTestImpl I;
  1177. I.CheckFilename = CheckFilename;
  1178. I.InputFilename = InputFilename;
  1179. I.CheckPrefixes = CheckPrefixes;
  1180. I.NoCanonicalizeWhiteSpace = NoCanonicalizeWhiteSpace;
  1181. I.ImplicitCheckNot = ImplicitCheckNot;
  1182. I.AllowEmptyInput = AllowEmptyInput;
  1183. I.InputForStdin = InputForStdin;
  1184. int result = I.run_main();
  1185. test_outs = I.test_outs.str();
  1186. test_errs = I.test_errs.str();
  1187. return result;
  1188. }