181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===- FileCheck.cpp - Check that File's Contents match what is expected --===// 281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// The LLVM Compiler Infrastructure 481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// This file is distributed under the University of Illinois Open Source 681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// License. See LICENSE.TXT for details. 781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===----------------------------------------------------------------------===// 981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// FileCheck does a line-by line check of a file that validates whether it 1181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// contains the expected content. This is useful for regression tests etc. 1281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// This program exits with an error status of 2 on error, exit status of 0 if 1481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// the file matched the expected contents, and exit status of 1 if it did not 1581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// contain the expected contents. 1681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner// 1781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner//===----------------------------------------------------------------------===// 1881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 194ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/SmallString.h" 204ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/StringExtras.h" 214ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/StringMap.h" 22ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault#include "llvm/ADT/StringSet.h" 2381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/CommandLine.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/MemoryBuffer.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 26528700863adefca8de461ce28a7d903729fb96b4Chris Lattner#include "llvm/Support/Regex.h" 274ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/Support/Signals.h" 2881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 30eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include <algorithm> 31e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 329756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <map> 339756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <string> 34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error> 359756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <vector> 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3981cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 4081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 4281cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 4381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 4481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 45ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic cl::list<std::string> 46ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt ArsenaultCheckPrefixes("check-prefix", 47ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 4881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 5088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 5188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 5288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 53ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaulttypedef cl::list<std::string>::const_iterator prefix_iterator; 54ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 55a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 56a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 57a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 58a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 594f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenaultnamespace Check { 604f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault enum CheckType { 614f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckNone = 0, 624f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckPlain, 634f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckNext, 644f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckNot, 654f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckDAG, 664f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckLabel, 674f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 684f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault /// MatchEOF - When set, this pattern only matches the end of file. This is 694f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault /// used for trailing CHECK-NOTs. 704f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckEOF 714f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault }; 724f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault} 734f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 749fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 7594638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SMLoc PatternLoc; 767112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 774f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Check::CheckType CheckTy; 7895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 795d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// FixedStr - If non-empty, this pattern is a fixed string match with the 805d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// specified fixed string. 812702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner StringRef FixedStr; 827112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 835d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// RegEx - If non-empty, this is a regex pattern. 845d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner std::string RegExStr; 857112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \brief Contains the number of line this pattern is in. 8770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber; 8870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 89eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableUses - Entries in this vector map to uses of a variable in the 90eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain 91eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// "foobaz" and we'll get an entry in this vector that tells us to insert the 92eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// value of bar at offset 3. 93eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableUses; 947112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 959756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// VariableDefs - Maps definitions of variables to their parenthesized 969756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// capture numbers. 979756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1. 989756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::map<StringRef, unsigned> VariableDefs; 997112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1009fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 1017112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1024f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Pattern(Check::CheckType Ty) 1034f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault : CheckTy(Ty) { } 1047112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1050fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao /// getLoc - Return the location in source code. 1060fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao SMLoc getLoc() const { return PatternLoc; } 1070fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao 108ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// ParsePattern - Parse the given string into the Pattern. Prefix provides 109ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// which prefix is being matched, SM provides the SourceMgr used for error 110ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// reports, and LineNumber is the line number in the input file from which 111ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// the pattern string was read. Returns true in case of an error, false 112ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// otherwise. 113ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault bool ParsePattern(StringRef PatternStr, 114ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix, 115ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SourceMgr &SM, 116ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault unsigned LineNumber); 1177112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1189fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 1199fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 1209fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 121eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// 122eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// The VariableTable StringMap provides the current values of filecheck 123eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// variables and is updated if this match defines new values. 124eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Match(StringRef Buffer, size_t &MatchLen, 125eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const; 126fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 127fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// PrintFailureInfo - Print additional information about a failure to match 128fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// involving this pattern. 129fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 130fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 131fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 132178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool hasVariable() const { return !(VariableUses.empty() && 133178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin VariableDefs.empty()); } 134178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1354f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Check::CheckType getCheckTy() const { return CheckTy; } 13695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 1375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate: 1389756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM); 1399756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky void AddBackrefToRegEx(unsigned BackrefNum); 140ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 141ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of 142ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// matching this pattern at the start of \arg Buffer; a distance of zero 143ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// should correspond to a perfect match. 144ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned ComputeMatchDistance(StringRef Buffer, 145ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 14670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 14770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \brief Evaluates expression and stores the result to \p Value. 14870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \return true on success. false when the expression has invalid syntax. 14970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko bool EvaluateExpression(StringRef Expr, std::string &Value) const; 1504db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 1514db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// \brief Finds the closing sequence of a regex variable usage or 1524db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// definition. Str has to point in the beginning of the definition 1534db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// (right after the opening sequence). 1544db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// \return offset of the closing sequence within Str, or npos if it was not 1554db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// found. 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM); 1579fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 1589fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 159eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 160ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultbool Pattern::ParsePattern(StringRef PatternStr, 161ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix, 162ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SourceMgr &SM, 16370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber) { 16470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko this->LineNumber = LineNumber; 16594638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner PatternLoc = SMLoc::getFromPointer(PatternStr.data()); 1667112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 167a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 168a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 169a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 170a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 1717112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 172a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 173a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 1743f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(PatternLoc, SourceMgr::DK_Error, 1753f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "found empty check string with prefix '" + 176ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + ":'"); 177a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 178a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 1797112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1802702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // Check to see if this is a fixed string, or if it has regex pieces. 1814f50517577bb74fb4d2a18ad613fd05aa48f564dTed Kremenek if (PatternStr.size() < 2 || 182eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (PatternStr.find("{{") == StringRef::npos && 183eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr.find("[[") == StringRef::npos)) { 1842702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner FixedStr = PatternStr; 1852702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return false; 1862702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 1877112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 188eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Paren value #0 is for the fully matched string. Any new parenthesized 18913a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner // values add from there. 190eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned CurParen = 1; 1917112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1925d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Otherwise, there is at least one regex piece. Build up the regex pattern 1935d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // by escaping scary characters in fixed strings, building up one big regex. 194528700863adefca8de461ce28a7d903729fb96b4Chris Lattner while (!PatternStr.empty()) { 195eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // RegEx matches. 19613a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner if (PatternStr.startswith("{{")) { 1971e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // This is the start of a regex match. Scan for the }}. 198eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("}}"); 199eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 200eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 2013f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 2023f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "found start of regex string with no end '}}'"); 203eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 204eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2057112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 20642e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // Enclose {{}} patterns in parens just like [[]] even though we're not 20742e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // capturing the result for any purpose. This is required in case the 20842e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // expression contains an alternation like: CHECK: abc{{x|z}}def. We 20942e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // want this to turn into: "abc(x|z)def" not "abcx|zdef". 21042e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner RegExStr += '('; 21142e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner ++CurParen; 21242e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner 213eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM)) 214eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 21542e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner RegExStr += ')'; 21613a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner 217eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 218528700863adefca8de461ce28a7d903729fb96b4Chris Lattner continue; 219528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 2207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 221eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .* 222eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // (or some other regex) and assigns it to the FileCheck variable 'foo'. The 223eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // second form is [[foo]] which is a reference to foo. The variable name 224964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject 225eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // it. This is to catch some common errors. 22613a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner if (PatternStr.startswith("[[")) { 2274db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Find the closing bracket pair ending the match. End is going to be an 2284db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // offset relative to the beginning of the match string. 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines size_t End = FindRegexVarEnd(PatternStr.substr(2), SM); 2304db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 231eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 232eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 2333f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 2343f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid named regex reference, no ]] found"); 235eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 236eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2377112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 2384db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky StringRef MatchStr = PatternStr.substr(2, End); 2394db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky PatternStr = PatternStr.substr(End+4); 2407112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 241eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Get the regex name (e.g. "foo"). 242eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t NameEnd = MatchStr.find(':'); 243eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef Name = MatchStr.substr(0, NameEnd); 2447112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 245eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (Name.empty()) { 2463f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, 2473f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid name in named regex: empty name"); 248eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 249eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 250eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 25170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // Verify that the name/expression is well formed. FileCheck currently 25270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // supports @LINE, @LINE+number, @LINE-number expressions. The check here 25370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // is relaxed, more strict check is performed in \c EvaluateExpression. 25470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko bool IsExpression = false; 25570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko for (unsigned i = 0, e = Name.size(); i != e; ++i) { 25670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (i == 0 && Name[i] == '@') { 25770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (NameEnd != StringRef::npos) { 25870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 25970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko SourceMgr::DK_Error, 26070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko "invalid name in named regex definition"); 26170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return true; 26270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 26370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko IsExpression = true; 26470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko continue; 26570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 26670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Name[i] != '_' && !isalnum(Name[i]) && 26770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) { 268eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i), 2693f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, "invalid name in named regex"); 270eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 271eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 27270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 2737112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 274eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Name can't start with a digit. 27587d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei if (isdigit(static_cast<unsigned char>(Name[0]))) { 2763f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, 2773f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid name in named regex"); 278eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 279eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2807112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 281eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo]]. 282eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (NameEnd == StringRef::npos) { 2839756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky // Handle variables that were defined earlier on the same line by 2849756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky // emitting a backreference. 2859756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky if (VariableDefs.find(Name) != VariableDefs.end()) { 2869756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky unsigned VarParenNum = VariableDefs[Name]; 2879756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky if (VarParenNum < 1 || VarParenNum > 9) { 2889756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 2899756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SourceMgr::DK_Error, 2909756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky "Can't back-reference more than 9 variables"); 2919756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky return true; 2929756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } 2939756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky AddBackrefToRegEx(VarParenNum); 2949756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } else { 2959756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableUses.push_back(std::make_pair(Name, RegExStr.size())); 2969756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } 297eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 298eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2997112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 300eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo:.*]]. 3019756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableDefs[Name] = CurParen; 302eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += '('; 303eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ++CurParen; 3047112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 305eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM)) 306eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 307eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 308eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += ')'; 309528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 3107112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 311eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle fixed string matches. 312eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Find the end, which is the start of the next regex. 313eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t FixedMatchEnd = PatternStr.find("{{"); 314eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[[")); 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd)); 316eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(FixedMatchEnd); 317528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 318528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 319528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return false; 320528700863adefca8de461ce28a7d903729fb96b4Chris Lattner} 321adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 3229756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Benderskybool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, 323eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SourceMgr &SM) { 3249756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky Regex R(RS); 325eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Error; 326eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!R.isValid(Error)) { 3279756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error, 3283f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid regex: " + Error); 329eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 330eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 3317112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3329756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky RegExStr += RS.str(); 333eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner CurParen += R.getNumMatches(); 334eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return false; 335eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner} 3365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 3379756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Benderskyvoid Pattern::AddBackrefToRegEx(unsigned BackrefNum) { 3389756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number"); 3399756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::string Backref = std::string("\\") + 3409756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::string(1, '0' + BackrefNum); 3419756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky RegExStr += Backref; 3429756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky} 3439756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky 34470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienkobool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const { 34570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // The only supported expression is @LINE([\+-]\d+)? 34670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!Expr.startswith("@LINE")) 34770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 34870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Expr = Expr.substr(StringRef("@LINE").size()); 34970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko int Offset = 0; 35070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!Expr.empty()) { 35170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Expr[0] == '+') 35270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Expr = Expr.substr(1); 35370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko else if (Expr[0] != '-') 35470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 35570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Expr.getAsInteger(10, Offset)) 35670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 35770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 35870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Value = llvm::itostr(LineNumber + Offset); 35970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return true; 36070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko} 36170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 362528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer. This 363528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match. If 364528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen. 365eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen, 366eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const { 367824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen // If this is the EOF pattern, match it immediately. 3684f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if (CheckTy == Check::CheckEOF) { 369824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen MatchLen = 0; 370824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen return Buffer.size(); 371824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 372824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 3732702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // If this is a fixed string pattern, just match it now. 3742702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (!FixedStr.empty()) { 3752702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner MatchLen = FixedStr.size(); 3762702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return Buffer.find(FixedStr); 3772702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 378eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 3795d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Regex match. 3807112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 381eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If there are variable uses, we need to create a temporary string with the 382eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // actual value. 383eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef RegExToMatch = RegExStr; 384eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string TmpStr; 385eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!VariableUses.empty()) { 386eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr = RegExStr; 3877112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 388eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned InsertOffset = 0; 389eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 390eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Value; 39170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 39270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (VariableUses[i].first[0] == '@') { 39370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!EvaluateExpression(VariableUses[i].first, Value)) 39470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return StringRef::npos; 39570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 39670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringMap<StringRef>::iterator it = 39770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko VariableTable.find(VariableUses[i].first); 39870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // If the variable is undefined, return an error. 39970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (it == VariableTable.end()) 40070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return StringRef::npos; 40170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Look up the value and escape it so that we can put it into the regex. 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value += Regex::escape(it->second); 40470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 4057112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 406eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Plop it into the regex at the adjusted offset. 407eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset, 408eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Value.begin(), Value.end()); 409eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner InsertOffset += Value.size(); 410eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 4117112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 412eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Match the newly constructed regex. 413eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExToMatch = TmpStr; 414eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 4157112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4167112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4175d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner SmallVector<StringRef, 4> MatchInfo; 418eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) 4195d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return StringRef::npos; 4207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4215d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Successful regex match. 4225d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner assert(!MatchInfo.empty() && "Didn't get any match"); 4235d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef FullMatch = MatchInfo[0]; 4247112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 425eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If this defines any variables, remember their values. 4269756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(), 4279756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky E = VariableDefs.end(); 4289756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky I != E; ++I) { 4299756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky assert(I->second < MatchInfo.size() && "Internal paren error"); 4309756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableTable[I->first] = MatchInfo[I->second]; 43194638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner } 4327112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner MatchLen = FullMatch.size(); 4345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return FullMatch.data()-Buffer.data(); 435a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 436a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 437ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbarunsigned Pattern::ComputeMatchDistance(StringRef Buffer, 438ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const { 439ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Just compute the number of matching characters. For regular expressions, we 440ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // just compare against the regex itself and hope for the best. 441ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // 442ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: One easy improvement here is have the regex lib generate a single 443ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // example regular expression which matches, and use that as the example 444ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // string. 445ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar StringRef ExampleString(FixedStr); 446ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (ExampleString.empty()) 447ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ExampleString = RegExStr; 448ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 4490806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar // Only compare up to the first line in the buffer, or the string size. 4500806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar StringRef BufferPrefix = Buffer.substr(0, ExampleString.size()); 4510806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar BufferPrefix = BufferPrefix.split('\n').first; 4520806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar return BufferPrefix.edit_distance(ExampleString); 453ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar} 454ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 455fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbarvoid Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 456fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const{ 457fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If this was a regular expression using variables, print the current 458fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // variable values. 459fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (!VariableUses.empty()) { 460fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 461fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SmallString<256> Msg; 462fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar raw_svector_ostream OS(Msg); 46370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringRef Var = VariableUses[i].first; 46470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Var[0] == '@') { 46570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko std::string Value; 46670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (EvaluateExpression(Var, Value)) { 46770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "with expression \""; 46870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\" equal to \""; 46970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Value) << "\""; 47070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 47170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "uses incorrect expression \""; 47270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\""; 47370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 474fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } else { 47570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringMap<StringRef>::const_iterator it = VariableTable.find(Var); 47670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 47770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // Check for undefined variable references. 47870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (it == VariableTable.end()) { 47970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "uses undefined variable \""; 48070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\""; 48170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 48270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "with variable \""; 48370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\" equal to \""; 48470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(it->second) << "\""; 48570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 486fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 487fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 4883f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 4893f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner OS.str()); 490fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 491fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 492ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 493ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Attempt to find the closest/best fuzzy match. Usually an error happens 494ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // because some string in the output didn't exactly match. In these cases, we 495ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // would like to show the user a best guess at what "should have" matched, to 496ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // save them having to actually check the input manually. 497ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t NumLinesForward = 0; 498ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t Best = StringRef::npos; 499ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double BestQuality = 0; 500ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 501ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Use an arbitrary 4k limit on how far we will search. 502e3a1e506809acbddceb6840914879c498d454f26Dan Gohman for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) { 503ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Buffer[i] == '\n') 504ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ++NumLinesForward; 505ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 506d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // Patterns have leading whitespace stripped, so skip whitespace when 507d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // looking for something which looks like a pattern. 508d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman if (Buffer[i] == ' ' || Buffer[i] == '\t') 509d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman continue; 510d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman 511ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Compute the "quality" of this match as an arbitrary combination of the 512ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // match distance and the number of lines skipped to get to this match. 513ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable); 514ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double Quality = Distance + (NumLinesForward / 100.); 515ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 516ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Quality < BestQuality || Best == StringRef::npos) { 517ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar Best = i; 518ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar BestQuality = Quality; 519ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 520ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 521ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 5227a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // Print the "possible intended match here" line if we found something 5237a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // reasonable and not equal to what we showed in the "scanning from here" 5247a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // line. 5257a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar if (Best && Best != StringRef::npos && BestQuality < 50) { 5267a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best), 5273f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Note, "possible intended match here"); 528ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 529ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: If we wanted to be really friendly we would show why the match 530ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // failed, as it can be hard to spot simple one character differences. 531ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 532fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar} 533a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinessize_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) { 5354db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Offset keeps track of the current offset within the input Str 5364db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t Offset = 0; 5374db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // [...] Nesting depth 5384db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t BracketDepth = 0; 5394db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5404db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky while (!Str.empty()) { 5414db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky if (Str.startswith("]]") && BracketDepth == 0) 5424db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky return Offset; 5434db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky if (Str[0] == '\\') { 5444db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Backslash escapes the next char within regexes, so skip them both. 5454db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Str = Str.substr(2); 5464db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Offset += 2; 5474db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } else { 5484db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky switch (Str[0]) { 5494db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky default: 5504db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5514db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky case '[': 5524db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky BracketDepth++; 5534db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5544db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky case ']': 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BracketDepth == 0) { 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SM.PrintMessage(SMLoc::getFromPointer(Str.data()), 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SourceMgr::DK_Error, 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "missing closing \"]\" for regex variable"); 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines exit(1); 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 5614db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky BracketDepth--; 5624db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5634db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5644db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Str = Str.substr(1); 5654db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Offset++; 5664db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5674db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5684db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5694db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky return StringRef::npos; 5704db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky} 5714db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5724db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 573a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 574a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 575a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 5769fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 5779fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 5789fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 5799fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 5809fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 5817112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 582ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault /// Prefix - Which prefix name this check matched. 583ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix; 584ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 585207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 586207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 5877112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 5884f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive, 5894f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault /// as opposed to a CHECK: directive. 5904f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Check::CheckType CheckTy; 591178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 59295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// DagNotStrings - These are all of the strings that are disallowed from 593f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 594f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 59595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<Pattern> DagNotStrings; 5967112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 597ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 598ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckString(const Pattern &P, 599ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef S, 600ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SMLoc L, 601ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Check::CheckType Ty) 602ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault : Pat(P), Prefix(S), Loc(L), CheckTy(Ty) {} 6037efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 60495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// Check - Match check string and its "not strings" and/or "dag strings". 605e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode, 606178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t &MatchLen, StringMap<StringRef> &VariableTable) const; 6077efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 6087efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao /// CheckNext - Verify there is a single line in the given buffer. 6097efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao bool CheckNext(const SourceMgr &SM, StringRef Buffer) const; 6107efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 6117efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao /// CheckNot - Verify there's no "not strings" in the given buffer. 6127efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao bool CheckNot(const SourceMgr &SM, StringRef Buffer, 61395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const std::vector<const Pattern *> &NotStrings, 6147efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const; 61595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 61695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// CheckDag - Match "dag strings" and their mixed "not strings". 61795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t CheckDag(const SourceMgr &SM, StringRef Buffer, 61895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> &NotStrings, 61995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) const; 620207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 621207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 6224cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// Canonicalize whitespaces in the input file. Line endings are replaced 6234cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// with UNIX-style '\n'. 6244cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// 6254cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace 6264cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// characters to a single space. 6274cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyeistatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB, 6284cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei bool PreserveHorizontal) { 6294c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner SmallString<128> NewFile; 630adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 6317112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 632adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 633adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 6349f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi // Eliminate trailing dosish \r. 6359f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') { 6369f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi continue; 6379f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi } 6389f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi 639c16f8c5e564fc2d69c75e85bdda66ad001d6b99eMichael Liao // If current char is not a horizontal whitespace or if horizontal 6404cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // whitespace canonicalization is disabled, dump it to output as is. 6414cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) { 642adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 643adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 644adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 6457112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 646adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 647adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 648adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 649adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 650adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 651adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 6527112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 653adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 654adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 6554c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier()); 6567112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 657adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 658adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 659adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 660adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 6614f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenaultstatic bool IsPartOfWord(char c) { 6624f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return (isalnum(c) || c == '-' || c == '_'); 6634f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault} 6644f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 665ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// Get the size of the prefix extension. 666ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic size_t CheckTypeSize(Check::CheckType Ty) { 667ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault switch (Ty) { 668ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckNone: 669ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return 0; 670ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 671ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckPlain: 672ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return sizeof(":") - 1; 673ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 674ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckNext: 675ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return sizeof("-NEXT:") - 1; 676ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 677ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckNot: 678ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return sizeof("-NOT:") - 1; 679ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 680ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckDAG: 681ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return sizeof("-DAG:") - 1; 682ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 683ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckLabel: 684ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return sizeof("-LABEL:") - 1; 685ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 686ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault case Check::CheckEOF: 687ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault llvm_unreachable("Should not be using EOF size"); 688ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 689ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 690ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault llvm_unreachable("Bad check type"); 691ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 692ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 693ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) { 69453bb26f61c65b6f63e9aa2950429bb889683bc11Matt Arsenault char NextChar = Buffer[Prefix.size()]; 6954f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 6964f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault // Verify that the : is present after the prefix. 697ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (NextChar == ':') 6984f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckPlain; 6994f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 700ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (NextChar != '-') 7014f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckNone; 7024f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 70353bb26f61c65b6f63e9aa2950429bb889683bc11Matt Arsenault StringRef Rest = Buffer.drop_front(Prefix.size() + 1); 704ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (Rest.startswith("NEXT:")) 7054f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckNext; 7064f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 707ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (Rest.startswith("NOT:")) 7084f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckNot; 7094f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 710ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (Rest.startswith("DAG:")) 7114f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckDAG; 7124f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 713ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (Rest.startswith("LABEL:")) 7144f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckLabel; 7154f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault 7164f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault return Check::CheckNone; 7174f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault} 71881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 719ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// From the given position, find the next character after the word. 720ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic size_t SkipWord(StringRef Str, size_t Loc) { 721ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault while (Loc < Str.size() && IsPartOfWord(Str[Loc])) 722ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault ++Loc; 723ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return Loc; 724ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 725ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 726ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// Try to find the first match in buffer for any prefix. If a valid match is 727ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// found, return that prefix and set its type and location. If there are almost 728ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// matches (e.g. the actual prefix string is found, but is not an actual check 729ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// string), but no valid match, return an empty string and set the position to 730ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// resume searching from. If no partial matches are found, return an empty 731ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// string and the location will be StringRef::npos. If one prefix is a substring 732ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// of another, the maximal match should be found. e.g. if "A" and "AA" are 733ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// prefixes then AA-CHECK: should match the second one. 734ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic StringRef FindFirstCandidateMatch(StringRef &Buffer, 735ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Check::CheckType &CheckTy, 736ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t &CheckLoc) { 737ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef FirstPrefix; 738ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t FirstLoc = StringRef::npos; 739ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t SearchLoc = StringRef::npos; 740ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Check::CheckType FirstTy = Check::CheckNone; 741ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 742ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckTy = Check::CheckNone; 743ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckLoc = StringRef::npos; 744ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 745ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end(); 746ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault I != E; ++I) { 747ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix(*I); 748ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t PrefixLoc = Buffer.find(Prefix); 749ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 750ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (PrefixLoc == StringRef::npos) 751ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault continue; 752ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 753ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Track where we are searching for invalid prefixes that look almost right. 754ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // We need to only advance to the first partial match on the next attempt 755ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // since a partial match could be a substring of a later, valid prefix. 756ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Need to skip to the end of the word, otherwise we could end up 757ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // matching a prefix in a substring later. 758ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (PrefixLoc < SearchLoc) 759ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SearchLoc = SkipWord(Buffer, PrefixLoc); 760ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 761ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // We only want to find the first match to avoid skipping some. 762ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (PrefixLoc > FirstLoc) 763ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault continue; 7640ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov // If one matching check-prefix is a prefix of another, choose the 7650ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov // longer one. 7660ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size()) 7670ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov continue; 768ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 769ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Rest = Buffer.drop_front(PrefixLoc); 770ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Make sure we have actually found the prefix, and not a word containing 771ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // it. This should also prevent matching the wrong prefix when one is a 772ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // substring of another. 773ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1])) 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FirstTy = Check::CheckNone; 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FirstTy = FindCheckType(Rest, Prefix); 777ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 778ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault FirstLoc = PrefixLoc; 7790ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov FirstPrefix = Prefix; 780ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 781ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 7820ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov // If the first prefix is invalid, we should continue the search after it. 7830ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov if (FirstTy == Check::CheckNone) { 784ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckLoc = SearchLoc; 7850ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov return ""; 786ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 787ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 7880ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov CheckTy = FirstTy; 7890ab53c711295f0469c86db088dc895238da801aaAlexey Samsonov CheckLoc = FirstLoc; 790ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return FirstPrefix; 791ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 792ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 793ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic StringRef FindFirstMatchingPrefix(StringRef &Buffer, 794ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault unsigned &LineNumber, 795ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Check::CheckType &CheckTy, 796ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t &CheckLoc) { 797ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault while (!Buffer.empty()) { 798ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc); 799ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // If we found a real match, we are done. 800ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (!Prefix.empty()) { 801ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault LineNumber += Buffer.substr(0, CheckLoc).count('\n'); 802ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return Prefix; 803ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 804ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 805ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // We didn't find any almost matches either, we are also done. 806ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (CheckLoc == StringRef::npos) 807ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return StringRef(); 808ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 809ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n'); 810ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 811ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Advance to the last possible match we found and try again. 812ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Buffer = Buffer.drop_front(CheckLoc + 1); 813ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 814ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 815ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return StringRef(); 816ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 817ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 81881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 81981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 8201e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky/// Returns true in case of an error, false otherwise. 82181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 822207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 823cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer::getFileOrSTDIN(CheckFilename); 825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = FileOrErr.getError()) { 826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << "Could not open check file '" << CheckFilename 827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "': " << EC.message() << '\n'; 82881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 82981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 8307112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 831adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 8324cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // buffer containing the CHECK lines. Remove DOS style line endings. 833cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer *F = CanonicalizeInputFile(FileOrErr.get().release(), 834cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines NoCanonicalizeWhiteSpace); 8357112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 83681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 83781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 838d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 83996077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 84095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<Pattern> DagNotMatches; 8417112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8421e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // LineNumber keeps track of the line on which CheckPrefix instances are 8431e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // found. 84470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber = 1; 84570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 84681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 847ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Check::CheckType CheckTy; 848ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault size_t PrefixLoc; 849ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 850ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // See if a prefix occurs in the memory buffer. 851ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer, 852ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault LineNumber, 853ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckTy, 854ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault PrefixLoc); 855ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (UsedPrefix.empty()) 85681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 8577112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 858ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Buffer = Buffer.drop_front(PrefixLoc); 85970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 860ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Location to use for error messages. 861ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1); 86270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 863ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // PrefixLoc is to the start of the prefix. Skip to the end. 864ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy)); 8657112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8664f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault // Okay, we found the prefix, yay. Remember the rest of the line, but ignore 8674f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault // leading and trailing whitespace. 868f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 8697112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 87081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 87196077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 872a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 873e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman // Remember the location of the start of the pattern, for diagnostics. 874e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); 875e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman 876a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 8774f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Pattern P(CheckTy); 878ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber)) 87981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 8807112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 881178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Verify that CHECK-LABEL lines do not define or use variables 8824f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if ((CheckTy == Check::CheckLabel) && P.hasVariable()) { 883ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart), 884178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin SourceMgr::DK_Error, 885ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault "found '" + UsedPrefix + "-LABEL:'" 886ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault " with variable definition or use"); 887178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return true; 888178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 889178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 890a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 891a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 8925dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 8934f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) { 894ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart), 8953f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 896ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault "found '" + UsedPrefix + "-NEXT:' without previous '" 897ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault + UsedPrefix + ": line"); 8985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 8995dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 9007112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 90195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Handle CHECK-DAG/-NOT. 9024f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) { 90395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao DagNotMatches.push_back(P); 904a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 905a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 9067112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 90781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 9089fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 909ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault UsedPrefix, 910e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman PatternLoc, 9114f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckTy)); 91295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); 91381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 9147112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 915ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first 916ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault // prefix as a filler for the error message. 91795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (!DagNotMatches.empty()) { 9184f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF), 919ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckPrefixes[0], 920824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen SMLoc::getFromPointer(Buffer.data()), 9214f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Check::CheckEOF)); 92295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); 923824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 924824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 92581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 926ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault errs() << "error: no check strings found with prefix" 927ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault << (CheckPrefixes.size() > 1 ? "es " : " "); 928ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) { 929ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix(CheckPrefixes[I]); 930ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault errs() << '\'' << Prefix << ":'"; 931ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (I != N - 1) 932ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault errs() << ", "; 933ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 934ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 935ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault errs() << '\n'; 93681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 93781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 9387112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 93981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 94081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 94181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 94295ab32667456b13ad56634cc7554cde8a50db95aMichael Liaostatic void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc, 94395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern &Pat, StringRef Buffer, 944fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef> &VariableTable) { 9455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 94695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Loc, SourceMgr::DK_Error, 9473f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "expected string not found in input"); 9487112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 9495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 9505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 95196077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 9527112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 9533f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 9543f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "scanning from here"); 955fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 956fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Allow the pattern to print additional information if desired. 95795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao Pat.PrintFailureInfo(SM, Buffer, VariableTable); 95895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao} 95995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 96095ab32667456b13ad56634cc7554cde8a50db95aMichael Liaostatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 96195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef Buffer, 96295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) { 96395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable); 9645dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 9655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 9663711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 9673711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 968dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic unsigned CountNumNewlinesBetween(StringRef Range, 969dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *&FirstNewLine) { 9705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 9713711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 9725dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 9733711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 9743711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 9757112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 9765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 9777112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 9785dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 9793711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 9803711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 9813711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 9823711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 9833711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (NumNewLines == 1) 986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FirstNewLine = Range.begin(); 9875dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 9885dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 9895dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 9907efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaosize_t CheckString::Check(const SourceMgr &SM, StringRef Buffer, 991e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin bool IsLabelScanMode, size_t &MatchLen, 9927efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const { 99395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t LastPos = 0; 99495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> NotStrings; 99595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 996e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL 997e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // bounds; we have not processed variable definitions within the bounded block 998e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // yet so cannot handle any final CHECK-DAG yet; this is handled when going 999e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // over the block again (including the last CHECK-LABEL) in normal mode. 1000e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin if (!IsLabelScanMode) { 1001e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // Match "dag strings" (with mixed "not strings" if any). 1002e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable); 1003e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin if (LastPos == StringRef::npos) 1004e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin return StringRef::npos; 1005e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin } 100695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 100795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Match itself from the last position after matching CHECK-DAG. 100895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef MatchBuffer = Buffer.substr(LastPos); 100995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); 10107efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (MatchPos == StringRef::npos) { 101195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, *this, MatchBuffer, VariableTable); 10127efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return StringRef::npos; 10137efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 101495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos += LastPos; 10157efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 1016e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT 1017e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin // or CHECK-NOT 1018e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin if (!IsLabelScanMode) { 1019178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos); 10207efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 1021178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // If this check is a "CHECK-NEXT", verify that the previous match was on 1022178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // the previous line (i.e. that there is one newline between them). 1023178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (CheckNext(SM, SkippedRegion)) 1024178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return StringRef::npos; 10257efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 1026178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // If this match had "not strings", verify that they don't exist in the 1027178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // skipped region. 1028178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) 1029178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return StringRef::npos; 1030178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 10317efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10327efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return MatchPos; 10337efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 10347efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10357efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaobool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { 10364f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if (CheckTy != Check::CheckNext) 10377efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 10387efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10397efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao // Count the number of newlines between the previous match and this one. 10407efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao assert(Buffer.data() != 10417efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.getMemoryBuffer( 10427efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.FindBufferContainingLoc( 10437efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SMLoc::getFromPointer(Buffer.data())))->getBufferStart() && 10447efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "CHECK-NEXT can't be the first check in a file"); 10457efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 1046cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const char *FirstNewLine = nullptr; 1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine); 10487efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10497efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (NumNewLines == 0) { 1050ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix + 10517efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "-NEXT: is on the same line as previous match"); 10527efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), 10537efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Note, "'next' match was here"); 10547efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 10557efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "previous match ended here"); 10567efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 10577efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 10587efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10597efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (NumNewLines != 1) { 1060ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix + 10617efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "-NEXT: is not on the line after the previous match"); 10627efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), 10637efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Note, "'next' match was here"); 10647efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 10657efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "previous match ended here"); 1066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note, 1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "non-matching line after previous match is here"); 10687efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 10697efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 10707efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10717efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 10727efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 10737efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10747efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaobool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, 107595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const std::vector<const Pattern *> &NotStrings, 10767efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const { 10777efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao for (unsigned ChunkNo = 0, e = NotStrings.size(); 10787efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao ChunkNo != e; ++ChunkNo) { 107995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern *Pat = NotStrings[ChunkNo]; 10804f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!"); 108195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 10827efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao size_t MatchLen = 0; 108395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable); 10847efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10857efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (Pos == StringRef::npos) continue; 10867efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10877efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos), 10887efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Error, 1089ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-NOT: string occurred!"); 109095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note, 1091ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-NOT: pattern specified here"); 10927efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 10937efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 10947efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 10957efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 10967efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 10977efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 109895ab32667456b13ad56634cc7554cde8a50db95aMichael Liaosize_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, 109995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> &NotStrings, 110095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) const { 110195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (DagNotStrings.empty()) 110295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return 0; 110395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 110495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t LastPos = 0; 110595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t StartPos = LastPos; 110695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 110795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao for (unsigned ChunkNo = 0, e = DagNotStrings.size(); 110895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao ChunkNo != e; ++ChunkNo) { 110995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern &Pat = DagNotStrings[ChunkNo]; 111095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 11114f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault assert((Pat.getCheckTy() == Check::CheckDAG || 11124f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault Pat.getCheckTy() == Check::CheckNot) && 111395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao "Invalid CHECK-DAG or CHECK-NOT!"); 111495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 11154f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if (Pat.getCheckTy() == Check::CheckNot) { 111695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao NotStrings.push_back(&Pat); 111795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao continue; 111895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 111995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 11204f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!"); 112195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 112295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t MatchLen = 0, MatchPos; 112395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 112495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // CHECK-DAG always matches from the start. 112595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef MatchBuffer = Buffer.substr(StartPos); 112695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); 112795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // With a group of CHECK-DAGs, a single mismatching means the match on 112895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // that group of CHECK-DAGs fails immediately. 112995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (MatchPos == StringRef::npos) { 113095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable); 113195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 113295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 113395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Re-calc it as the offset relative to the start of the original string. 113495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos += StartPos; 113595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 113695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (!NotStrings.empty()) { 113795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (MatchPos < LastPos) { 113895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Reordered? 113995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos), 114095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SourceMgr::DK_Error, 1141ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-DAG: found a match of CHECK-DAG" 114295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " reordering across a CHECK-NOT"); 114395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos), 114495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SourceMgr::DK_Note, 1145ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-DAG: the farthest match of CHECK-DAG" 114695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " is found here"); 114795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note, 1148ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-NOT: the crossed pattern specified" 114995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " here"); 115095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note, 1151ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Prefix + "-DAG: the reordered pattern specified" 115295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " here"); 115395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 115495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 115595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // All subsequent CHECK-DAGs should be matched from the farthest 115695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // position of all precedent CHECK-DAGs (including this one.) 115795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StartPos = LastPos; 115895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to 115995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // CHECK-DAG, verify that there's no 'not' strings occurred in that 116095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // region. 116195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos); 1162e57343b6365df5b7318c5076f917ad40cf621555Tim Northover if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) 116395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 116495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Clear "not strings". 116595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao NotStrings.clear(); 116695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 116795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 116895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Update the last position with CHECK-DAG matches. 116995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao LastPos = std::max(MatchPos + MatchLen, LastPos); 117095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 117195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 117295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return LastPos; 117395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao} 117495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 1175ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// A check prefix must contain only alphanumeric, hyphens and underscores. 1176ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic bool ValidateCheckPrefix(StringRef CheckPrefix) { 1177ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault Regex Validator("^[a-zA-Z0-9_-]*$"); 1178ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return Validator.match(CheckPrefix); 1179ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 1180ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1181ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic bool ValidateCheckPrefixes() { 1182ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringSet<> PrefixSet; 1183ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1184ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end(); 1185ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault I != E; ++I) { 1186ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault StringRef Prefix(*I); 1187ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1188ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (!PrefixSet.insert(Prefix)) 1189ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return false; 1190ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1191ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (!ValidateCheckPrefix(Prefix)) 1192ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return false; 1193ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault } 1194ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1195ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault return true; 1196ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault} 1197ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 1198ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// I don't think there's a way to specify an initial value for cl::list, 1199ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault// so if nothing was specified, add the default 1200ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenaultstatic void AddCheckPrefixIfNeeded() { 1201ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (CheckPrefixes.empty()) 1202ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault CheckPrefixes.push_back("CHECK"); 1203d9a84efe44db2f4d983e49bc7370fc8cef449214Rui Ueyama} 1204d9a84efe44db2f4d983e49bc7370fc8cef449214Rui Ueyama 120581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 120681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 120781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 120881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 120981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 1210ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault if (!ValidateCheckPrefixes()) { 1211ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault errs() << "Supplied check-prefix is invalid! Prefixes must be unique and " 1212ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault "start with a letter and contain only alphanumeric characters, " 1213ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault "hyphens and underscores\n"; 1214d9a84efe44db2f4d983e49bc7370fc8cef449214Rui Ueyama return 2; 1215d9a84efe44db2f4d983e49bc7370fc8cef449214Rui Ueyama } 1216d9a84efe44db2f4d983e49bc7370fc8cef449214Rui Ueyama 1217ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault AddCheckPrefixIfNeeded(); 1218ee4f5eae1c416eddbecbb2d742e2bb8dc0032bf6Matt Arsenault 121981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 12207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 122181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 1222207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 122381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 122481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 122581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 122681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 1227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 1228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer::getFileOrSTDIN(InputFilename); 1229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = FileOrErr.getError()) { 1230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines errs() << "Could not open input file '" << InputFilename 1231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines << "': " << EC.message() << '\n'; 12327f8e76f5140be7cc9ed1cb66cdcdedfa28147641Eli Bendersky return 2; 123381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 1234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MemoryBuffer> File = std::move(FileOrErr.get()); 12357112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 12367cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer if (File->getBufferSize() == 0) { 12371aac1864cfb66ae3d322ff7e28738d03bc1d1bfcChris Lattner errs() << "FileCheck error: '" << InputFilename << "' is empty.\n"; 12387f8e76f5140be7cc9ed1cb66cdcdedfa28147641Eli Bendersky return 2; 12391aac1864cfb66ae3d322ff7e28738d03bc1d1bfcChris Lattner } 12407cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer 124188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 12424cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // Remove DOS style line endings. 12437cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer MemoryBuffer *F = 124436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CanonicalizeInputFile(File.release(), NoCanonicalizeWhiteSpace); 12457112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 124681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 12477112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1248eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableTable - This holds all the current filecheck variables. 1249eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> VariableTable; 12507112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 125181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 125281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 125396077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 12547112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1255178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool hasError = false; 12567112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1257178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin unsigned i = 0, j = 0, e = CheckStrings.size(); 1258178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1259178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin while (true) { 1260178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin StringRef CheckRegion; 1261178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (j == e) { 1262178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = Buffer; 1263178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } else { 1264178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin const CheckString &CheckLabelStr = CheckStrings[j]; 12654f67afc3d67d9a68f1b37767c9c2966a775186bdMatt Arsenault if (CheckLabelStr.CheckTy != Check::CheckLabel) { 1266178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin ++j; 1267178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin continue; 1268178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1269178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1270178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG 1271178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchLabelLen = 0; 1272e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin size_t MatchLabelPos = CheckLabelStr.Check(SM, Buffer, true, 1273178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin MatchLabelLen, VariableTable); 1274178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (MatchLabelPos == StringRef::npos) { 1275178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin hasError = true; 1276178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 1277178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 12787112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1279178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen); 1280178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen); 1281178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin ++j; 1282178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 12835dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 1284178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin for ( ; i != j; ++i) { 1285178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin const CheckString &CheckStr = CheckStrings[i]; 1286178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1287178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Check each string within the scanned region, including a second check 1288178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG) 1289178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchLen = 0; 1290e5f740cc4f994c0db13a66de699bf95ccf24130eStephen Lin size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen, 1291178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin VariableTable); 1292178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1293178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (MatchPos == StringRef::npos) { 1294178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin hasError = true; 1295178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin i = j; 1296178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 1297178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1298178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1299178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = CheckRegion.substr(MatchPos + MatchLen); 1300178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1301178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1302178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (j == e) 1303178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 130481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 13057112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1306178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return hasError ? 1 : 0; 130781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 1308