FileCheck.cpp revision 178504b07b793b3fde46d950b8f10e0794193e02
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 193ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer#include "llvm/ADT/OwningPtr.h" 204ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/SmallString.h" 214ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/StringExtras.h" 224ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/ADT/StringMap.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" 30333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h" 31eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include <algorithm> 329756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <map> 339756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <string> 349756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky#include <vector> 3581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3881cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 3981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 4181cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 4281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 4381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 4581cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 4681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 4781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 4988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 5088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 5188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 52a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 53a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 54a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 55a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 569fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 5794638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SMLoc PatternLoc; 587112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 59824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen /// MatchEOF - When set, this pattern only matches the end of file. This is 60824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen /// used for trailing CHECK-NOTs. 61824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen bool MatchEOF; 62824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 6395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// MatchNot 6495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao bool MatchNot; 6595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 6695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// MatchDag 6795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao bool MatchDag; 6895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 695d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// FixedStr - If non-empty, this pattern is a fixed string match with the 705d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// specified fixed string. 712702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner StringRef FixedStr; 727112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 735d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// RegEx - If non-empty, this is a regex pattern. 745d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner std::string RegExStr; 757112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 7670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \brief Contains the number of line this pattern is in. 7770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber; 7870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 79eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableUses - Entries in this vector map to uses of a variable in the 80eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain 81eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// "foobaz" and we'll get an entry in this vector that tells us to insert the 82eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// value of bar at offset 3. 83eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableUses; 847112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 859756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// VariableDefs - Maps definitions of variables to their parenthesized 869756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// capture numbers. 879756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1. 889756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::map<StringRef, unsigned> VariableDefs; 897112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 909fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 917112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 9295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao Pattern(bool matchEOF = false) 9395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao : MatchEOF(matchEOF), MatchNot(false), MatchDag(false) { } 947112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 950fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao /// getLoc - Return the location in source code. 960fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao SMLoc getLoc() const { return PatternLoc; } 970fc7137f2f8a99cb749024c51e3247f4b24e1ee0Michael Liao 981e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky /// ParsePattern - Parse the given string into the Pattern. SM provides the 991e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky /// SourceMgr used for error reports, and LineNumber is the line number in 1001e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky /// the input file from which the pattern string was read. 1011e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky /// Returns true in case of an error, false otherwise. 10270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko bool ParsePattern(StringRef PatternStr, SourceMgr &SM, unsigned LineNumber); 1037112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1049fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 1059fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 1069fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 107eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// 108eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// The VariableTable StringMap provides the current values of filecheck 109eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// variables and is updated if this match defines new values. 110eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Match(StringRef Buffer, size_t &MatchLen, 111eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const; 112fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 113fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// PrintFailureInfo - Print additional information about a failure to match 114fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// involving this pattern. 115fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 116fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 117fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 118178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool hasVariable() const { return !(VariableUses.empty() && 119178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin VariableDefs.empty()); } 120178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 12195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao void setMatchNot(bool Not) { MatchNot = Not; } 12295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao bool getMatchNot() const { return MatchNot; } 12395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 12495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao void setMatchDag(bool Dag) { MatchDag = Dag; } 12595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao bool getMatchDag() const { return MatchDag; } 12695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 1275d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate: 128eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr); 1299756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM); 1309756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky void AddBackrefToRegEx(unsigned BackrefNum); 131ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 132ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of 133ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// matching this pattern at the start of \arg Buffer; a distance of zero 134ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// should correspond to a perfect match. 135ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned ComputeMatchDistance(StringRef Buffer, 136ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 13770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 13870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \brief Evaluates expression and stores the result to \p Value. 13970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko /// \return true on success. false when the expression has invalid syntax. 14070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko bool EvaluateExpression(StringRef Expr, std::string &Value) const; 1414db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 1424db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// \brief Finds the closing sequence of a regex variable usage or 1434db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// definition. Str has to point in the beginning of the definition 1444db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// (right after the opening sequence). 1454db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// \return offset of the closing sequence within Str, or npos if it was not 1464db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky /// found. 1474db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t FindRegexVarEnd(StringRef Str); 1489fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 1499fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 150eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 15170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienkobool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM, 15270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber) { 15370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko this->LineNumber = LineNumber; 15494638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner PatternLoc = SMLoc::getFromPointer(PatternStr.data()); 1557112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 156a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 157a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 158a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 159a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 1607112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 161a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 162a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 1633f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(PatternLoc, SourceMgr::DK_Error, 1643f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "found empty check string with prefix '" + 1653f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner CheckPrefix+":'"); 166a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 167a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 1687112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1692702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // Check to see if this is a fixed string, or if it has regex pieces. 1704f50517577bb74fb4d2a18ad613fd05aa48f564dTed Kremenek if (PatternStr.size() < 2 || 171eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (PatternStr.find("{{") == StringRef::npos && 172eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr.find("[[") == StringRef::npos)) { 1732702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner FixedStr = PatternStr; 1742702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return false; 1752702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 1767112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 177eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Paren value #0 is for the fully matched string. Any new parenthesized 17813a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner // values add from there. 179eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned CurParen = 1; 1807112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1815d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Otherwise, there is at least one regex piece. Build up the regex pattern 1825d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // by escaping scary characters in fixed strings, building up one big regex. 183528700863adefca8de461ce28a7d903729fb96b4Chris Lattner while (!PatternStr.empty()) { 184eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // RegEx matches. 18513a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner if (PatternStr.startswith("{{")) { 1861e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // This is the start of a regex match. Scan for the }}. 187eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("}}"); 188eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 189eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 1903f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 1913f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "found start of regex string with no end '}}'"); 192eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 193eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 1947112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 19542e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // Enclose {{}} patterns in parens just like [[]] even though we're not 19642e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // capturing the result for any purpose. This is required in case the 19742e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // expression contains an alternation like: CHECK: abc{{x|z}}def. We 19842e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner // want this to turn into: "abc(x|z)def" not "abcx|zdef". 19942e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner RegExStr += '('; 20042e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner ++CurParen; 20142e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner 202eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM)) 203eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 20442e31dfd4f3c7fe8f83c930cd3a1700cef6914eaChris Lattner RegExStr += ')'; 20513a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner 206eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 207528700863adefca8de461ce28a7d903729fb96b4Chris Lattner continue; 208528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 2097112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 210eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .* 211eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // (or some other regex) and assigns it to the FileCheck variable 'foo'. The 212eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // second form is [[foo]] which is a reference to foo. The variable name 213964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject 214eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // it. This is to catch some common errors. 21513a38c4cb4c90a6d2b5313a6517d6291cb924730Chris Lattner if (PatternStr.startswith("[[")) { 2164db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Find the closing bracket pair ending the match. End is going to be an 2174db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // offset relative to the beginning of the match string. 2184db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t End = FindRegexVarEnd(PatternStr.substr(2)); 2194db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 220eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 221eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 2223f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 2233f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid named regex reference, no ]] found"); 224eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 225eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2267112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 2274db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky StringRef MatchStr = PatternStr.substr(2, End); 2284db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky PatternStr = PatternStr.substr(End+4); 2297112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 230eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Get the regex name (e.g. "foo"). 231eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t NameEnd = MatchStr.find(':'); 232eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef Name = MatchStr.substr(0, NameEnd); 2337112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 234eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (Name.empty()) { 2353f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, 2363f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid name in named regex: empty name"); 237eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 238eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 239eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 24070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // Verify that the name/expression is well formed. FileCheck currently 24170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // supports @LINE, @LINE+number, @LINE-number expressions. The check here 24270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // is relaxed, more strict check is performed in \c EvaluateExpression. 24370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko bool IsExpression = false; 24470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko for (unsigned i = 0, e = Name.size(); i != e; ++i) { 24570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (i == 0 && Name[i] == '@') { 24670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (NameEnd != StringRef::npos) { 24770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 24870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko SourceMgr::DK_Error, 24970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko "invalid name in named regex definition"); 25070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return true; 25170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 25270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko IsExpression = true; 25370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko continue; 25470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 25570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Name[i] != '_' && !isalnum(Name[i]) && 25670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) { 257eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i), 2583f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, "invalid name in named regex"); 259eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 260eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 26170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 2627112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 263eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Name can't start with a digit. 26487d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei if (isdigit(static_cast<unsigned char>(Name[0]))) { 2653f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, 2663f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid name in named regex"); 267eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 268eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2697112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 270eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo]]. 271eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (NameEnd == StringRef::npos) { 2729756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky // Handle variables that were defined earlier on the same line by 2739756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky // emitting a backreference. 2749756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky if (VariableDefs.find(Name) != VariableDefs.end()) { 2759756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky unsigned VarParenNum = VariableDefs[Name]; 2769756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky if (VarParenNum < 1 || VarParenNum > 9) { 2779756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 2789756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SourceMgr::DK_Error, 2799756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky "Can't back-reference more than 9 variables"); 2809756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky return true; 2819756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } 2829756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky AddBackrefToRegEx(VarParenNum); 2839756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } else { 2849756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableUses.push_back(std::make_pair(Name, RegExStr.size())); 2859756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky } 286eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 287eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 2887112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 289eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo:.*]]. 2909756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableDefs[Name] = CurParen; 291eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += '('; 292eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ++CurParen; 2937112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 294eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM)) 295eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 296eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 297eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += ')'; 298528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 2997112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 300eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle fixed string matches. 301eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Find the end, which is the start of the next regex. 302eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t FixedMatchEnd = PatternStr.find("{{"); 303eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[[")); 304eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr); 305eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(FixedMatchEnd); 306528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 307528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 308528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return false; 309528700863adefca8de461ce28a7d903729fb96b4Chris Lattner} 310adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 311eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnervoid Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) { 3125d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Add the characters from FixedStr to the regex, escaping as needed. This 3135d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // avoids "leaning toothpicks" in common patterns. 3145d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) { 3155d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner switch (FixedStr[i]) { 3165d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // These are the special characters matched in "p_ere_exp". 3175d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '(': 3185d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case ')': 3195d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '^': 3205d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '$': 3215d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '|': 3225d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '*': 3235d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '+': 3245d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '?': 3255d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '.': 3265d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '[': 3275d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '\\': 3285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '{': 329eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += '\\'; 3305d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // FALL THROUGH. 3315d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner default: 332eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += FixedStr[i]; 3335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner break; 3345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 3355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 3365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner} 3375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 3389756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Benderskybool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, 339eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SourceMgr &SM) { 3409756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky Regex R(RS); 341eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Error; 342eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!R.isValid(Error)) { 3439756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error, 3443f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid regex: " + Error); 345eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 346eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 3477112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 3489756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky RegExStr += RS.str(); 349eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner CurParen += R.getNumMatches(); 350eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return false; 351eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner} 3525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 3539756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Benderskyvoid Pattern::AddBackrefToRegEx(unsigned BackrefNum) { 3549756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number"); 3559756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::string Backref = std::string("\\") + 3569756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky std::string(1, '0' + BackrefNum); 3579756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky RegExStr += Backref; 3589756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky} 3599756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky 36070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienkobool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const { 36170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // The only supported expression is @LINE([\+-]\d+)? 36270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!Expr.startswith("@LINE")) 36370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 36470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Expr = Expr.substr(StringRef("@LINE").size()); 36570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko int Offset = 0; 36670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!Expr.empty()) { 36770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Expr[0] == '+') 36870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Expr = Expr.substr(1); 36970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko else if (Expr[0] != '-') 37070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 37170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Expr.getAsInteger(10, Offset)) 37270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return false; 37370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 37470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Value = llvm::itostr(LineNumber + Offset); 37570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return true; 37670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko} 37770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 378528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer. This 379528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match. If 380528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen. 381eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen, 382eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const { 383824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen // If this is the EOF pattern, match it immediately. 384824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen if (MatchEOF) { 385824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen MatchLen = 0; 386824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen return Buffer.size(); 387824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 388824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 3892702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // If this is a fixed string pattern, just match it now. 3902702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (!FixedStr.empty()) { 3912702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner MatchLen = FixedStr.size(); 3922702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return Buffer.find(FixedStr); 3932702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 394eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 3955d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Regex match. 3967112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 397eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If there are variable uses, we need to create a temporary string with the 398eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // actual value. 399eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef RegExToMatch = RegExStr; 400eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string TmpStr; 401eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!VariableUses.empty()) { 402eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr = RegExStr; 4037112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 404eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned InsertOffset = 0; 405eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 406eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Value; 40770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 40870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (VariableUses[i].first[0] == '@') { 40970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (!EvaluateExpression(VariableUses[i].first, Value)) 41070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return StringRef::npos; 41170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 41270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringMap<StringRef>::iterator it = 41370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko VariableTable.find(VariableUses[i].first); 41470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // If the variable is undefined, return an error. 41570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (it == VariableTable.end()) 41670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko return StringRef::npos; 41770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 41870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // Look up the value and escape it so that we can plop it into the regex. 41970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko AddFixedStringToRegEx(it->second, Value); 42070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 4217112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 422eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Plop it into the regex at the adjusted offset. 423eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset, 424eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Value.begin(), Value.end()); 425eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner InsertOffset += Value.size(); 426eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 4277112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 428eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Match the newly constructed regex. 429eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExToMatch = TmpStr; 430eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 4317112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4327112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner SmallVector<StringRef, 4> MatchInfo; 434eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) 4355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return StringRef::npos; 4367112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Successful regex match. 4385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner assert(!MatchInfo.empty() && "Didn't get any match"); 4395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef FullMatch = MatchInfo[0]; 4407112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 441eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If this defines any variables, remember their values. 4429756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(), 4439756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky E = VariableDefs.end(); 4449756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky I != E; ++I) { 4459756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky assert(I->second < MatchInfo.size() && "Internal paren error"); 4469756ca7ba0c7f6c3b1e76ee12ca27ddca04be9d7Eli Bendersky VariableTable[I->first] = MatchInfo[I->second]; 44794638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner } 4487112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 4495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner MatchLen = FullMatch.size(); 4505d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return FullMatch.data()-Buffer.data(); 451a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 452a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 453ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbarunsigned Pattern::ComputeMatchDistance(StringRef Buffer, 454ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const { 455ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Just compute the number of matching characters. For regular expressions, we 456ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // just compare against the regex itself and hope for the best. 457ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // 458ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: One easy improvement here is have the regex lib generate a single 459ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // example regular expression which matches, and use that as the example 460ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // string. 461ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar StringRef ExampleString(FixedStr); 462ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (ExampleString.empty()) 463ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ExampleString = RegExStr; 464ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 4650806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar // Only compare up to the first line in the buffer, or the string size. 4660806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar StringRef BufferPrefix = Buffer.substr(0, ExampleString.size()); 4670806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar BufferPrefix = BufferPrefix.split('\n').first; 4680806f9ff5860ce351540ff2897dec1667154ca19Daniel Dunbar return BufferPrefix.edit_distance(ExampleString); 469ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar} 470ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 471fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbarvoid Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 472fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const{ 473fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If this was a regular expression using variables, print the current 474fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // variable values. 475fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (!VariableUses.empty()) { 476fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 477fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SmallString<256> Msg; 478fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar raw_svector_ostream OS(Msg); 47970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringRef Var = VariableUses[i].first; 48070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (Var[0] == '@') { 48170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko std::string Value; 48270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (EvaluateExpression(Var, Value)) { 48370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "with expression \""; 48470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\" equal to \""; 48570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Value) << "\""; 48670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 48770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "uses incorrect expression \""; 48870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\""; 48970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 490fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } else { 49170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko StringMap<StringRef>::const_iterator it = VariableTable.find(Var); 49270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 49370a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko // Check for undefined variable references. 49470a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (it == VariableTable.end()) { 49570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "uses undefined variable \""; 49670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\""; 49770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } else { 49870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS << "with variable \""; 49970a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(Var) << "\" equal to \""; 50070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko OS.write_escaped(it->second) << "\""; 50170a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko } 502fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 503fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 5043f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 5053f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner OS.str()); 506fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 507fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 508ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 509ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Attempt to find the closest/best fuzzy match. Usually an error happens 510ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // because some string in the output didn't exactly match. In these cases, we 511ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // would like to show the user a best guess at what "should have" matched, to 512ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // save them having to actually check the input manually. 513ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t NumLinesForward = 0; 514ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t Best = StringRef::npos; 515ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double BestQuality = 0; 516ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 517ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Use an arbitrary 4k limit on how far we will search. 518e3a1e506809acbddceb6840914879c498d454f26Dan Gohman for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) { 519ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Buffer[i] == '\n') 520ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ++NumLinesForward; 521ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 522d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // Patterns have leading whitespace stripped, so skip whitespace when 523d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // looking for something which looks like a pattern. 524d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman if (Buffer[i] == ' ' || Buffer[i] == '\t') 525d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman continue; 526d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman 527ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Compute the "quality" of this match as an arbitrary combination of the 528ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // match distance and the number of lines skipped to get to this match. 529ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable); 530ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double Quality = Distance + (NumLinesForward / 100.); 531ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 532ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Quality < BestQuality || Best == StringRef::npos) { 533ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar Best = i; 534ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar BestQuality = Quality; 535ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 536ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 537ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 5387a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // Print the "possible intended match here" line if we found something 5397a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // reasonable and not equal to what we showed in the "scanning from here" 5407a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar // line. 5417a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar if (Best && Best != StringRef::npos && BestQuality < 50) { 5427a68e0df0d2eb46f509ef086729e46a0e79e4750Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best), 5433f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Note, "possible intended match here"); 544ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 545ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: If we wanted to be really friendly we would show why the match 546ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // failed, as it can be hard to spot simple one character differences. 547ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 548fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar} 549a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 5504db6511779e70780f7b36bb7ef54276752f5f640Eli Benderskysize_t Pattern::FindRegexVarEnd(StringRef Str) { 5514db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Offset keeps track of the current offset within the input Str 5524db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t Offset = 0; 5534db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // [...] Nesting depth 5544db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky size_t BracketDepth = 0; 5554db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5564db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky while (!Str.empty()) { 5574db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky if (Str.startswith("]]") && BracketDepth == 0) 5584db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky return Offset; 5594db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky if (Str[0] == '\\') { 5604db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky // Backslash escapes the next char within regexes, so skip them both. 5614db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Str = Str.substr(2); 5624db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Offset += 2; 5634db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } else { 5644db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky switch (Str[0]) { 5654db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky default: 5664db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5674db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky case '[': 5684db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky BracketDepth++; 5694db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5704db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky case ']': 5714db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky assert(BracketDepth > 0 && "Invalid regex"); 5724db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky BracketDepth--; 5734db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky break; 5744db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5754db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Str = Str.substr(1); 5764db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky Offset++; 5774db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5784db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky } 5794db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5804db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky return StringRef::npos; 5814db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky} 5824db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 5834db6511779e70780f7b36bb7ef54276752f5f640Eli Bendersky 584a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 585a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 586a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 5879fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 5889fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 5899fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 5909fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 5919fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 5927112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 593207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 594207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 5957112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 5965dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 5975dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 5985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 5997112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 600178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin /// IsCheckLabel - This is true if this is a CHECK-LABEL: directive (as 601178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin /// opposed to a CHECK: directive. 602178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool IsCheckLabel; 603178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 60495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// DagNotStrings - These are all of the strings that are disallowed from 605f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 606f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 60795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<Pattern> DagNotStrings; 6087112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 609178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckString(const Pattern &P, SMLoc L, bool isCheckNext, bool isCheckLabel) 610178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin : Pat(P), Loc(L), IsCheckNext(isCheckNext), IsCheckLabel(isCheckLabel) {} 6117efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 61295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// Check - Match check string and its "not strings" and/or "dag strings". 613178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabel, 614178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t &MatchLen, StringMap<StringRef> &VariableTable) const; 6157efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 6167efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao /// CheckNext - Verify there is a single line in the given buffer. 6177efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao bool CheckNext(const SourceMgr &SM, StringRef Buffer) const; 6187efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 6197efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao /// CheckNot - Verify there's no "not strings" in the given buffer. 6207efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao bool CheckNot(const SourceMgr &SM, StringRef Buffer, 62195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const std::vector<const Pattern *> &NotStrings, 6227efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const; 62395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 62495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao /// CheckDag - Match "dag strings" and their mixed "not strings". 62595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t CheckDag(const SourceMgr &SM, StringRef Buffer, 62695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> &NotStrings, 62795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) const; 628207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 629207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 6304cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// Canonicalize whitespaces in the input file. Line endings are replaced 6314cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// with UNIX-style '\n'. 6324cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// 6334cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace 6344cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei/// characters to a single space. 6354cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyeistatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB, 6364cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei bool PreserveHorizontal) { 6374c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner SmallString<128> NewFile; 638adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 6397112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 640adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 641adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 6429f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi // Eliminate trailing dosish \r. 6439f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') { 6449f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi continue; 6459f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi } 6469f6e03fa1e05f7c59379e68d7626400ca508cfb0NAKAMURA Takumi 647c16f8c5e564fc2d69c75e85bdda66ad001d6b99eMichael Liao // If current char is not a horizontal whitespace or if horizontal 6484cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // whitespace canonicalization is disabled, dump it to output as is. 6494cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) { 650adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 651adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 652adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 6537112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 654adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 655adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 656adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 657adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 658adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 659adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 6607112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 661adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 662adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 6634c842dda3939c6b9f83ba7e8e19e43445cd9a832Chris Lattner MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier()); 6647112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 665adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 666adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 667adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 668adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 66981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 67081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 67181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 6721e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky/// Returns true in case of an error, false otherwise. 67381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 674207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 6753ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> File; 6763ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = 677dd5af27a74a01f0d03356cea15d3a403f4964f8bRafael Espindola MemoryBuffer::getFileOrSTDIN(CheckFilename, File)) { 6787112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov errs() << "Could not open check file '" << CheckFilename << "': " 679333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer << ec.message() << '\n'; 68081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 68181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 6827112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 683adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 6844cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // buffer containing the CHECK lines. Remove DOS style line endings. 6857cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer MemoryBuffer *F = 6867cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace); 6877112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 68881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 68981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 690d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 69196077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 69295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<Pattern> DagNotMatches; 6937112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 6941e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // LineNumber keeps track of the line on which CheckPrefix instances are 6951e5cbcb10adaca5c80121293b6c414d9285ebceeEli Bendersky // found. 69670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko unsigned LineNumber = 1; 69770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 69881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 69981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 70070a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko size_t PrefixLoc = Buffer.find(CheckPrefix); 70181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 70270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (PrefixLoc == StringRef::npos) 70381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 7047112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 70570a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko LineNumber += Buffer.substr(0, PrefixLoc).count('\n'); 70670a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 70770a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko Buffer = Buffer.substr(PrefixLoc); 70870a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko 70996077036f06478d96c123283a50cfba49858fd40Chris Lattner const char *CheckPrefixStart = Buffer.data(); 7107112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 7115dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 7125dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 713178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool IsCheckNext = false, IsCheckNot = false, IsCheckDag = false, 714178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin IsCheckLabel = false; 7157112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 716d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 71796077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer[CheckPrefix.size()] == ':') { 71896077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+1); 71996077036f06478d96c123283a50cfba49858fd40Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+6 && 72096077036f06478d96c123283a50cfba49858fd40Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) { 72130ce40e3f77d1432903c24caf816c54bb260d833Benjamin Kramer Buffer = Buffer.substr(CheckPrefix.size()+6); 7225dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 723f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+5 && 724f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) { 72530ce40e3f77d1432903c24caf816c54bb260d833Benjamin Kramer Buffer = Buffer.substr(CheckPrefix.size()+5); 726f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner IsCheckNot = true; 72795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } else if (Buffer.size() > CheckPrefix.size()+5 && 72895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao memcmp(Buffer.data()+CheckPrefix.size(), "-DAG:", 5) == 0) { 72995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao Buffer = Buffer.substr(CheckPrefix.size()+5); 73095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao IsCheckDag = true; 731178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } else if (Buffer.size() > CheckPrefix.size()+7 && 732178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin memcmp(Buffer.data()+CheckPrefix.size(), "-LABEL:", 7) == 0) { 733178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin Buffer = Buffer.substr(CheckPrefix.size()+7); 734178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin IsCheckLabel = true; 7355dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 73696077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(1); 737d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 738d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 7397112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 74081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 74181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 742f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 7437112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 74481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 74596077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 746a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 747e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman // Remember the location of the start of the pattern, for diagnostics. 748e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); 749e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman 750a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 751a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern P; 75270a870add82dab944b98ee1840fafff33795fc95Alexander Kornienko if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber)) 75381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 7547112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 755178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Verify that CHECK-LABEL lines do not define or use variables 756178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (IsCheckLabel && P.hasVariable()) { 757178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 758178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin SourceMgr::DK_Error, 759178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin "found '"+CheckPrefix+"-LABEL:' with variable definition" 760178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin " or use'"); 761178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return true; 762178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 763178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 76495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao P.setMatchNot(IsCheckNot); 76595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao P.setMatchDag(IsCheckDag); 76695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 767a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 768a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 7695dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 7705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 7715dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 7723f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Error, 7735dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 7743f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner CheckPrefix+ ": line"); 7755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 7765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 7777112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 77895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Handle CHECK-DAG/-NOT. 77995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (IsCheckDag || IsCheckNot) { 78095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao DagNotMatches.push_back(P); 781a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 782a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 7837112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 78481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 7859fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 786e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman PatternLoc, 787178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin IsCheckNext, 788178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin IsCheckLabel)); 78995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); 79081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 7917112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 79295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Add an EOF pattern for any trailing CHECK-DAG/-NOTs. 79395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (!DagNotMatches.empty()) { 794824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen CheckStrings.push_back(CheckString(Pattern(true), 795824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen SMLoc::getFromPointer(Buffer.data()), 796178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin false, 797824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen false)); 79895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); 799824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen } 800824c10ece26fd031591b1770acc8a6c2575a3ab8Jakob Stoklund Olesen 80181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 802d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 803d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 80481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 80581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 8067112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 80781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 80881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 80981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 81095ab32667456b13ad56634cc7554cde8a50db95aMichael Liaostatic void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc, 81195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern &Pat, StringRef Buffer, 812fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef> &VariableTable) { 8135dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 81495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Loc, SourceMgr::DK_Error, 8153f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "expected string not found in input"); 8167112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 8185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 81996077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 8207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8213f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 8223f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "scanning from here"); 823fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 824fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Allow the pattern to print additional information if desired. 82595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao Pat.PrintFailureInfo(SM, Buffer, VariableTable); 82695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao} 82795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 82895ab32667456b13ad56634cc7554cde8a50db95aMichael Liaostatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 82995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef Buffer, 83095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) { 83195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable); 8325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 8335dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 8343711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 8353711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 8363711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) { 8375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 8383711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 8395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 8403711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 8413711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 8427112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 8447112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 8455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 8463711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 8473711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 8483711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 8493711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 8503711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 8515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 8525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 8535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 8547efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaosize_t CheckString::Check(const SourceMgr &SM, StringRef Buffer, 855178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool IsLabel, size_t &MatchLen, 8567efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const { 85795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t LastPos = 0; 85895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> NotStrings; 85995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 860178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (!IsLabel) { 861178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Match "dag strings" (with mixed "not strings" if any). 862178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable); 863178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (LastPos == StringRef::npos) 864178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return StringRef::npos; 865178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 86695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 86795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Match itself from the last position after matching CHECK-DAG. 86895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef MatchBuffer = Buffer.substr(LastPos); 86995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); 8707efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (MatchPos == StringRef::npos) { 87195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, *this, MatchBuffer, VariableTable); 8727efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return StringRef::npos; 8737efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 87495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos += LastPos; 8757efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 876178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (!IsLabel) { 877178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos); 8787efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 879178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // If this check is a "CHECK-NEXT", verify that the previous match was on 880178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // the previous line (i.e. that there is one newline between them). 881178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (CheckNext(SM, SkippedRegion)) 882178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return StringRef::npos; 8837efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 884178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // If this match had "not strings", verify that they don't exist in the 885178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // skipped region. 886178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) 887178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return StringRef::npos; 888178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 8897efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 8907efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return MatchPos; 8917efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 8927efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 8937efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaobool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { 8947efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (!IsCheckNext) 8957efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 8967efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 8977efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao // Count the number of newlines between the previous match and this one. 8987efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao assert(Buffer.data() != 8997efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.getMemoryBuffer( 9007efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.FindBufferContainingLoc( 9017efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SMLoc::getFromPointer(Buffer.data())))->getBufferStart() && 9027efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "CHECK-NEXT can't be the first check in a file"); 9037efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9047efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao unsigned NumNewLines = CountNumNewlinesBetween(Buffer); 9057efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9067efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (NumNewLines == 0) { 9077efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(Loc, SourceMgr::DK_Error, CheckPrefix+ 9087efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "-NEXT: is on the same line as previous match"); 9097efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), 9107efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Note, "'next' match was here"); 9117efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 9127efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "previous match ended here"); 9137efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 9147efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 9157efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9167efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (NumNewLines != 1) { 9177efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(Loc, SourceMgr::DK_Error, CheckPrefix+ 9187efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "-NEXT: is not on the line after the previous match"); 9197efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), 9207efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Note, "'next' match was here"); 9217efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 9227efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao "previous match ended here"); 9237efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 9247efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 9257efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9267efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 9277efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 9287efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9297efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liaobool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, 93095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const std::vector<const Pattern *> &NotStrings, 9317efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao StringMap<StringRef> &VariableTable) const { 9327efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao for (unsigned ChunkNo = 0, e = NotStrings.size(); 9337efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao ChunkNo != e; ++ChunkNo) { 93495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern *Pat = NotStrings[ChunkNo]; 93595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao assert(Pat->getMatchNot() && "Expect CHECK-NOT!"); 93695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 9377efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao size_t MatchLen = 0; 93895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable); 9397efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9407efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao if (Pos == StringRef::npos) continue; 9417efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9427efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos), 9437efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao SourceMgr::DK_Error, 9447efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao CheckPrefix+"-NOT: string occurred!"); 94595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note, 9467efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao CheckPrefix+"-NOT: pattern specified here"); 9477efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return true; 9487efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao } 9497efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 9507efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao return false; 9517efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao} 9527efbbd61eb0aa85ec189db8f02c85ad9078946e9Michael Liao 95395ab32667456b13ad56634cc7554cde8a50db95aMichael Liaosize_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, 95495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao std::vector<const Pattern *> &NotStrings, 95595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringMap<StringRef> &VariableTable) const { 95695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (DagNotStrings.empty()) 95795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return 0; 95895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 95995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t LastPos = 0; 96095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t StartPos = LastPos; 96195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 96295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao for (unsigned ChunkNo = 0, e = DagNotStrings.size(); 96395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao ChunkNo != e; ++ChunkNo) { 96495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao const Pattern &Pat = DagNotStrings[ChunkNo]; 96595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 96695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao assert((Pat.getMatchDag() ^ Pat.getMatchNot()) && 96795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao "Invalid CHECK-DAG or CHECK-NOT!"); 96895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 96995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (Pat.getMatchNot()) { 97095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao NotStrings.push_back(&Pat); 97195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao continue; 97295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 97395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 97495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao assert(Pat.getMatchDag() && "Expect CHECK-DAG!"); 97595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 97695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t MatchLen = 0, MatchPos; 97795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 97895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // CHECK-DAG always matches from the start. 97995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef MatchBuffer = Buffer.substr(StartPos); 98095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); 98195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // With a group of CHECK-DAGs, a single mismatching means the match on 98295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // that group of CHECK-DAGs fails immediately. 98395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (MatchPos == StringRef::npos) { 98495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable); 98595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 98695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 98795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Re-calc it as the offset relative to the start of the original string. 98895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao MatchPos += StartPos; 98995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 99095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (!NotStrings.empty()) { 99195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (MatchPos < LastPos) { 99295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Reordered? 99395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos), 99495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SourceMgr::DK_Error, 99595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao CheckPrefix+"-DAG: found a match of CHECK-DAG" 99695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " reordering across a CHECK-NOT"); 99795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos), 99895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SourceMgr::DK_Note, 99995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao CheckPrefix+"-DAG: the farthest match of CHECK-DAG" 100095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " is found here"); 100195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note, 100295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao CheckPrefix+"-NOT: the crossed pattern specified" 100395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " here"); 100495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note, 100595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao CheckPrefix+"-DAG: the reordered pattern specified" 100695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao " here"); 100795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 100895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 100995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // All subsequent CHECK-DAGs should be matched from the farthest 101095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // position of all precedent CHECK-DAGs (including this one.) 101195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StartPos = LastPos; 101295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to 101395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // CHECK-DAG, verify that there's no 'not' strings occurred in that 101495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // region. 101595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos); 101695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao size_t Pos = CheckNot(SM, SkippedRegion, NotStrings, VariableTable); 101795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao if (Pos != StringRef::npos) 101895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return StringRef::npos; 101995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Clear "not strings". 102095ab32667456b13ad56634cc7554cde8a50db95aMichael Liao NotStrings.clear(); 102195ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 102295ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 102395ab32667456b13ad56634cc7554cde8a50db95aMichael Liao // Update the last position with CHECK-DAG matches. 102495ab32667456b13ad56634cc7554cde8a50db95aMichael Liao LastPos = std::max(MatchPos + MatchLen, LastPos); 102595ab32667456b13ad56634cc7554cde8a50db95aMichael Liao } 102695ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 102795ab32667456b13ad56634cc7554cde8a50db95aMichael Liao return LastPos; 102895ab32667456b13ad56634cc7554cde8a50db95aMichael Liao} 102995ab32667456b13ad56634cc7554cde8a50db95aMichael Liao 103081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 103181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 103281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 103381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 103481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 103581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 10367112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 103781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 1038207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 103981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 104081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 104181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 104281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 10433ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> File; 10443ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = 1045dd5af27a74a01f0d03356cea15d3a403f4964f8bRafael Espindola MemoryBuffer::getFileOrSTDIN(InputFilename, File)) { 10467112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov errs() << "Could not open input file '" << InputFilename << "': " 1047333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer << ec.message() << '\n'; 10487f8e76f5140be7cc9ed1cb66cdcdedfa28147641Eli Bendersky return 2; 104981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 10507112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 10517cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer if (File->getBufferSize() == 0) { 10521aac1864cfb66ae3d322ff7e28738d03bc1d1bfcChris Lattner errs() << "FileCheck error: '" << InputFilename << "' is empty.\n"; 10537f8e76f5140be7cc9ed1cb66cdcdedfa28147641Eli Bendersky return 2; 10541aac1864cfb66ae3d322ff7e28738d03bc1d1bfcChris Lattner } 10557cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer 105688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 10574cc74fcba06ce43ee325510dc6137bd050f96c68Guy Benyei // Remove DOS style line endings. 10587cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer MemoryBuffer *F = 10597cdba152bbe4debfb58ed6d9559ef77aae8a0b31Benjamin Kramer CanonicalizeInputFile(File.take(), NoCanonicalizeWhiteSpace); 10607112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 106181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 10627112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1063eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableTable - This holds all the current filecheck variables. 1064eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> VariableTable; 10657112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 106681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 106781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 106896077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 10697112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1070178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin bool hasError = false; 10717112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1072178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin unsigned i = 0, j = 0, e = CheckStrings.size(); 1073178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1074178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin while (true) { 1075178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin StringRef CheckRegion; 1076178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (j == e) { 1077178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = Buffer; 1078178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } else { 1079178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin const CheckString &CheckLabelStr = CheckStrings[j]; 1080178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (!CheckLabelStr.IsCheckLabel) { 1081178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin ++j; 1082178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin continue; 1083178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1084178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1085178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG 1086178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchLabelLen = 0; 1087178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchLabelPos = CheckLabelStr.Check(SM, Buffer, true, 1088178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin MatchLabelLen, VariableTable); 1089178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (MatchLabelPos == StringRef::npos) { 1090178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin hasError = true; 1091178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 1092178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 10937112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1094178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen); 1095178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen); 1096178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin ++j; 1097178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 10985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 1099178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin for ( ; i != j; ++i) { 1100178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin const CheckString &CheckStr = CheckStrings[i]; 1101178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1102178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // Check each string within the scanned region, including a second check 1103178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG) 1104178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchLen = 0; 1105178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen, 1106178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin VariableTable); 1107178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1108178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (MatchPos == StringRef::npos) { 1109178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin hasError = true; 1110178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin i = j; 1111178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 1112178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1113178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1114178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin CheckRegion = CheckRegion.substr(MatchPos + MatchLen); 1115178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin } 1116178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin 1117178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin if (j == e) 1118178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin break; 111981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 11207112c86fc208145334aaa04812c794ce6feef416Mikhail Glushenkov 1121178504b07b793b3fde46d950b8f10e0794193e02Stephen Lin return hasError ? 1 : 0; 112281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 1123