FileCheck.cpp revision d8a5541a513695039d1eb83eeced05d51ce9f567
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 1981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/CommandLine.h" 2081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/MemoryBuffer.h" 2181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 22528700863adefca8de461ce28a7d903729fb96b4Chris Lattner#include "llvm/Support/Regex.h" 2381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/System/Signals.h" 26fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar#include "llvm/ADT/SmallString.h" 27eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include "llvm/ADT/StringMap.h" 28eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner#include <algorithm> 2981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 3081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3281cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3581cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3981cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 4081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 4181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 4288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 4388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 4488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 4588a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 46a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 47a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 48a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 49a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 509fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 5194638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SMLoc PatternLoc; 5294638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner 535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// FixedStr - If non-empty, this pattern is a fixed string match with the 545d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// specified fixed string. 552702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner StringRef FixedStr; 565d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 575d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner /// RegEx - If non-empty, this is a regex pattern. 585d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner std::string RegExStr; 59eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 60eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableUses - Entries in this vector map to uses of a variable in the 61eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain 62eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// "foobaz" and we'll get an entry in this vector that tells us to insert the 63eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// value of bar at offset 3. 64eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableUses; 65eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 66eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableDefs - Entries in this vector map to definitions of a variable in 67eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// the pattern, e.g. "foo[[bar:.*]]baz". In this case, the RegExStr will 68eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1. The 69eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// index indicates what parenthesized value captures the variable value. 70eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::vector<std::pair<StringRef, unsigned> > VariableDefs; 71eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 729fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 739fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 74a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern() { } 75a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 76a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner bool ParsePattern(StringRef PatternStr, SourceMgr &SM); 779fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 789fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 799fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 809fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 81eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// 82eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// The VariableTable StringMap provides the current values of filecheck 83eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// variables and is updated if this match defines new values. 84eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Match(StringRef Buffer, size_t &MatchLen, 85eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const; 86fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 87fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// PrintFailureInfo - Print additional information about a failure to match 88fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /// involving this pattern. 89fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 90fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 91fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 925d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate: 93eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr); 94eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM); 95ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 96ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of 97ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// matching this pattern at the start of \arg Buffer; a distance of zero 98ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar /// should correspond to a perfect match. 99ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned ComputeMatchDistance(StringRef Buffer, 100ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const; 1019fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 1029fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 103eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 104a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattnerbool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) { 10594638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner PatternLoc = SMLoc::getFromPointer(PatternStr.data()); 10694638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner 107a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 108a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 109a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 110a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 111a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 112a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 113a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 11494638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner SM.PrintMessage(PatternLoc, "found empty check string with prefix '" + 11594638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner CheckPrefix+":'", "error"); 116a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 117a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 118528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 1192702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // Check to see if this is a fixed string, or if it has regex pieces. 120eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() < 2 || 121eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (PatternStr.find("{{") == StringRef::npos && 122eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr.find("[[") == StringRef::npos)) { 1232702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner FixedStr = PatternStr; 1242702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return false; 1252702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 1262702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner 127eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Paren value #0 is for the fully matched string. Any new parenthesized 128eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // values add from their. 129eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned CurParen = 1; 130eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 1315d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Otherwise, there is at least one regex piece. Build up the regex pattern 1325d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // by escaping scary characters in fixed strings, building up one big regex. 133528700863adefca8de461ce28a7d903729fb96b4Chris Lattner while (!PatternStr.empty()) { 134eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // RegEx matches. 135eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() >= 2 && 136eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr[0] == '{' && PatternStr[1] == '{') { 137eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 138eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Otherwise, this is the start of a regex match. Scan for the }}. 139eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("}}"); 140eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 141eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 142eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "found start of regex string with no end '}}'", "error"); 143eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 144eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 145eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 146eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM)) 147eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 148eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 149528700863adefca8de461ce28a7d903729fb96b4Chris Lattner continue; 150528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 151528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 152eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .* 153eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // (or some other regex) and assigns it to the FileCheck variable 'foo'. The 154eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // second form is [[foo]] which is a reference to foo. The variable name 155964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject 156eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // it. This is to catch some common errors. 157eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (PatternStr.size() >= 2 && 158eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr[0] == '[' && PatternStr[1] == '[') { 159eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Verify that it is terminated properly. 160eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t End = PatternStr.find("]]"); 161eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (End == StringRef::npos) { 162eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 163eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid named regex reference, no ]] found", "error"); 164eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 165eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 166eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 167eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef MatchStr = PatternStr.substr(2, End-2); 168eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(End+2); 169eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 170eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Get the regex name (e.g. "foo"). 171eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t NameEnd = MatchStr.find(':'); 172eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef Name = MatchStr.substr(0, NameEnd); 173eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 174eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (Name.empty()) { 175eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 176eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex: empty name", "error"); 177eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 178eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 179eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 180eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Verify that the name is well formed. 181eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = Name.size(); i != e; ++i) 182964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar if (Name[i] != '_' && 183964ac012017451ff24c33e6b749ec3223e1d291aDaniel Dunbar (Name[i] < 'a' || Name[i] > 'z') && 184eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (Name[i] < 'A' || Name[i] > 'Z') && 185eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner (Name[i] < '0' || Name[i] > '9')) { 186eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i), 187eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex", "error"); 188eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 189eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 190eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 191eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Name can't start with a digit. 192eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (isdigit(Name[0])) { 193eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 194eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid name in named regex", "error"); 195eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 196eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 197eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 198eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo]]. 199eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (NameEnd == StringRef::npos) { 200eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableUses.push_back(std::make_pair(Name, RegExStr.size())); 201eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 202eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 203eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 204eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle [[foo:.*]]. 205eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableDefs.push_back(std::make_pair(Name, CurParen)); 206eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += '('; 207eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ++CurParen; 208eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 209eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM)) 210eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 211eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 212eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += ')'; 213528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 214528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 215eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Handle fixed string matches. 216eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Find the end, which is the start of the next regex. 217eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t FixedMatchEnd = PatternStr.find("{{"); 218eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[[")); 219eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr); 220eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner PatternStr = PatternStr.substr(FixedMatchEnd); 221eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner continue; 222528700863adefca8de461ce28a7d903729fb96b4Chris Lattner } 223528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 224528700863adefca8de461ce28a7d903729fb96b4Chris Lattner return false; 225528700863adefca8de461ce28a7d903729fb96b4Chris Lattner} 226adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 227eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnervoid Pattern::AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr) { 2285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Add the characters from FixedStr to the regex, escaping as needed. This 2295d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // avoids "leaning toothpicks" in common patterns. 2305d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) { 2315d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner switch (FixedStr[i]) { 2325d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // These are the special characters matched in "p_ere_exp". 2335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '(': 2345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case ')': 2355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '^': 2365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '$': 2375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '|': 2385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '*': 2395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '+': 2405d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '?': 2415d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '.': 2425d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '[': 2435d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '\\': 2445d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner case '{': 245eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += '\\'; 2465d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // FALL THROUGH. 2475d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner default: 248eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TheStr += FixedStr[i]; 2495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner break; 2505d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 2515d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner } 2525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner} 2535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 254eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnerbool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen, 255eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SourceMgr &SM) { 256eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Regex R(RegexStr); 257eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Error; 258eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!R.isValid(Error)) { 259eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), 260eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "invalid regex: " + Error, "error"); 261eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return true; 262eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 263eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 264eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExStr += RegexStr.str(); 265eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner CurParen += R.getNumMatches(); 266eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner return false; 267eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner} 2685d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner 269528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer. This 270528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match. If 271528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen. 272eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen, 273eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> &VariableTable) const { 2742702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner // If this is a fixed string pattern, just match it now. 2752702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner if (!FixedStr.empty()) { 2762702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner MatchLen = FixedStr.size(); 2772702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner return Buffer.find(FixedStr); 2782702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner } 279eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 2805d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Regex match. 281eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 282eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If there are variable uses, we need to create a temporary string with the 283eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // actual value. 284eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringRef RegExToMatch = RegExStr; 285eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string TmpStr; 286eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!VariableUses.empty()) { 287eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr = RegExStr; 288eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 289eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner unsigned InsertOffset = 0; 290eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 291fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef>::iterator it = 292fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar VariableTable.find(VariableUses[i].first); 293fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If the variable is undefined, return an error. 294fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (it == VariableTable.end()) 295fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar return StringRef::npos; 296fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 297eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Look up the value and escape it so that we can plop it into the regex. 298eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner std::string Value; 299fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar AddFixedStringToRegEx(it->second, Value); 300eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 301eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Plop it into the regex at the adjusted offset. 302eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset, 303eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Value.begin(), Value.end()); 304eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner InsertOffset += Value.size(); 305eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 306eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 307eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // Match the newly constructed regex. 308eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner RegExToMatch = TmpStr; 309eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner } 310eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 311eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 3125d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner SmallVector<StringRef, 4> MatchInfo; 313eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) 3145d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return StringRef::npos; 315a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 3165d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner // Successful regex match. 3175d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner assert(!MatchInfo.empty() && "Didn't get any match"); 3185d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner StringRef FullMatch = MatchInfo[0]; 319528700863adefca8de461ce28a7d903729fb96b4Chris Lattner 320eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner // If this defines any variables, remember their values. 321eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) { 322eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner assert(VariableDefs[i].second < MatchInfo.size() && 323eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner "Internal paren error"); 324eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second]; 32594638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner } 32694638f0081b6ec8c7cc5ad9fec8ddbdd6824d90dChris Lattner 3275d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner MatchLen = FullMatch.size(); 3285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner return FullMatch.data()-Buffer.data(); 329a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 330a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 331ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbarunsigned Pattern::ComputeMatchDistance(StringRef Buffer, 332ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar const StringMap<StringRef> &VariableTable) const { 333ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Just compute the number of matching characters. For regular expressions, we 334ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // just compare against the regex itself and hope for the best. 335ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // 336ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: One easy improvement here is have the regex lib generate a single 337ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // example regular expression which matches, and use that as the example 338ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // string. 339ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar StringRef ExampleString(FixedStr); 340ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (ExampleString.empty()) 341ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ExampleString = RegExStr; 342ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 3438cdf54c222e911f09b57ab0d8fdd3408979df91bDaniel Dunbar return Buffer.substr(0, ExampleString.size()).edit_distance(ExampleString); 344ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar} 345ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 346fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbarvoid Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, 347fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar const StringMap<StringRef> &VariableTable) const{ 348fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // If this was a regular expression using variables, print the current 349fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // variable values. 350fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (!VariableUses.empty()) { 351fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { 352fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringRef Var = VariableUses[i].first; 353fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef>::const_iterator it = VariableTable.find(Var); 354fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SmallString<256> Msg; 355fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar raw_svector_ostream OS(Msg); 356fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 357fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Check for undefined variable references. 358fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar if (it == VariableTable.end()) { 359fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS << "uses undefined variable \""; 360fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(Var) << "\"";; 361fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } else { 362fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS << "with variable \""; 363fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(Var) << "\" equal to \""; 364fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar OS.write_escaped(it->second) << "\""; 365fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 366fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 367fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note", 368fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar /*ShowLine=*/false); 369fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 370fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar } 371ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 372ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Attempt to find the closest/best fuzzy match. Usually an error happens 373ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // because some string in the output didn't exactly match. In these cases, we 374ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // would like to show the user a best guess at what "should have" matched, to 375ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // save them having to actually check the input manually. 376ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t NumLinesForward = 0; 377ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar size_t Best = StringRef::npos; 378ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double BestQuality = 0; 379ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 380ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Use an arbitrary 4k limit on how far we will search. 381ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar for (size_t i = 0, e = std::min(4096, int(Buffer.size())); i != e; ++i) { 382ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Buffer[i] == '\n') 383ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar ++NumLinesForward; 384ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 385d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // Patterns have leading whitespace stripped, so skip whitespace when 386d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman // looking for something which looks like a pattern. 387d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman if (Buffer[i] == ' ' || Buffer[i] == '\t') 388d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman continue; 389d8a5541a513695039d1eb83eeced05d51ce9f567Dan Gohman 390ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Compute the "quality" of this match as an arbitrary combination of the 391ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // match distance and the number of lines skipped to get to this match. 392ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable); 393ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar double Quality = Distance + (NumLinesForward / 100.); 394ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 395ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar if (Quality < BestQuality || Best == StringRef::npos) { 396ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar Best = i; 397ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar BestQuality = Quality; 398ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 399ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 400ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 401a76a7883b557c315f29dbf95155dd5ae0352fecfDaniel Dunbar if (Best != StringRef::npos && BestQuality < 50) { 402ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // Print the "possible intended match here" line if we found something 403ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // reasonable. 404ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best), 405ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar "possible intended match here", "note"); 406ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar 407ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // FIXME: If we wanted to be really friendly we would show why the match 408ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar // failed, as it can be hard to spot simple one character differences. 409ead2dacc9ee028906cb104c8c3d66ccbbebe6b10Daniel Dunbar } 410fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar} 411a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 412a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 413a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 414a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 4159fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 4169fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 4179fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 4189fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 4199fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 420207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 421207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 422207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 423207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 4245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 4255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 4265dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 4275dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 428f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// NotStrings - These are all of the strings that are disallowed from 429f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 430f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 431a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotStrings; 432f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 4339fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckString(const Pattern &P, SMLoc L, bool isCheckNext) 4349fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner : Pat(P), Loc(L), IsCheckNext(isCheckNext) {} 435207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 436207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 437adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 438adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// memory buffer, free it, and return a new one. 439adea46ed617982ea07fc3266d52717496c0076ceChris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 440adea46ed617982ea07fc3266d52717496c0076ceChris Lattner SmallVector<char, 16> NewFile; 441adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 442adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 443adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 444adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 445adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If C is not a horizontal whitespace, skip it. 446adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 447adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 448adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 449adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 450adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 451adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 452adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 453adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 454adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 455adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 456adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 457adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 458adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 459adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 460adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer::getMemBufferCopy(NewFile.data(), 461adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.data() + NewFile.size(), 462adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MB->getBufferIdentifier()); 463adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 464adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 465adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 466adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 467adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 46881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 46981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 47081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 47181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 472207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 47381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 47481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 47581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 47681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr); 47781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 47881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open check file '" << CheckFilename << "': " 47981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 48081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 48181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 482adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 483adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 484adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // buffer containing the CHECK lines. 485adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (!NoCanonicalizeWhiteSpace) 486adea46ed617982ea07fc3266d52717496c0076ceChris Lattner F = CanonicalizeInputFile(F); 487adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 48881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 48981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 490d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 49196077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 49281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 493a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotMatches; 494f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 49581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 49681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 49796077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find(CheckPrefix)); 49881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 49981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 50096077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) 50181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 50281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 50396077036f06478d96c123283a50cfba49858fd40Chris Lattner const char *CheckPrefixStart = Buffer.data(); 5045dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 5055dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 5065dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 507f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner bool IsCheckNext = false, IsCheckNot = false; 5085dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 509d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 51096077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer[CheckPrefix.size()] == ':') { 51196077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+1); 51296077036f06478d96c123283a50cfba49858fd40Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+6 && 51396077036f06478d96c123283a50cfba49858fd40Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) { 51496077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+7); 5155dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 516f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+5 && 517f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) { 518f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+6); 519f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner IsCheckNot = true; 5205dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 52196077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(1); 522d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 523d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 524d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner 52581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 52681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 527f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 52881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 52981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 53096077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 531a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 532e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman // Remember the location of the start of the pattern, for diagnostics. 533e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); 534e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman 535a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 536a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern P; 537a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (P.ParsePattern(Buffer.substr(0, EOL), SM)) 53881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 53981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 540a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 541a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 542f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 5435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 5445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 5455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 5465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 5475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ ": line", "error"); 5485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 5495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 5505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 551a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Handle CHECK-NOT. 552a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (IsCheckNot) { 553a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()), 554a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner P)); 555a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 556a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 557a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 5589fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 55981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 5609fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 561e546343799d1b7914024b62f6c188f5c0d66f7b3Dan Gohman PatternLoc, 5625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext)); 563f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner std::swap(NotMatches, CheckStrings.back().NotStrings); 56481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 56581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 56681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 567d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 568d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 56981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 57081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 57181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 572f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (!NotMatches.empty()) { 573f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner errs() << "error: '" << CheckPrefix 574f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner << "-NOT:' not supported after last check line.\n"; 575f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return true; 576f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 577f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 57881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 57981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 58081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 5815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 582fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringRef Buffer, 583fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar StringMap<StringRef> &VariableTable) { 5845dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 5855dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 5865dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 5875dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 5885dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 5895dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 59096077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 5915dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 59296077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here", 5935dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "note"); 594fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar 595fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar // Allow the pattern to print additional information if desired. 596fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable); 5975dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 5985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 5993711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 6003711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 6013711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) { 6025dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 6033711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 6045dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 6053711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 6063711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 6075dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 6085dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 6095dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 6105dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 6113711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 6123711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 6133711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 6143711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 6153711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 6165dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 6175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 6185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 61981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 62081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 62181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 62281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 62381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 62481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 62581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 62681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 627207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 62881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 62981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 63081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 63181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 63281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 63381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 63481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); 63581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 63681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open input file '" << InputFilename << "': " 63781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 63881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 63981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 64088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 64188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 64288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 64388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 64488a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 64581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 64681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 647eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner /// VariableTable - This holds all the current filecheck variables. 648eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner StringMap<StringRef> VariableTable; 649eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner 65081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 65181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 65296077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 65381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 654f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner const char *LastMatch = Buffer.data(); 655f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 65681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 657207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 65881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 65996077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef SearchFrom = Buffer; 66096077036f06478d96c123283a50cfba49858fd40Chris Lattner 66181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 6629fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner size_t MatchLen = 0; 663eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable)); 66481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 6655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If we didn't find a match, reject the input. 66696077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) { 667fafe93c8bcbc538573bc5e890f24f9869a11f846Daniel Dunbar PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable); 6685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 66981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 6703711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 6713711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch); 6723711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 6735dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If this check is a "CHECK-NEXT", verify that the previous match was on 6745dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // the previous line (i.e. that there is one newline between them). 6755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (CheckStr.IsCheckNext) { 6765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Count the number of newlines between the previous match and this one. 677f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner assert(LastMatch != F->getBufferStart() && 678f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner "CHECK-NEXT can't be the first check in a file"); 6795dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 6803711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion); 6815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines == 0) { 6820b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 6835dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+"-NEXT: is on the same line as previous match", 6845dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 68596077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 6860b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 6875dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 6885dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 6895dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 6905dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 6915dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 6925dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines != 1) { 6930b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 6945dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ 6955dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "-NEXT: is not on the line after the previous match", 6965dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 69796077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 6980b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 6995dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 7005dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 7015dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 7025dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 7035dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 704f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 705f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // If this match had "not strings", verify that they don't exist in the 706f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // skipped region. 707eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size(); 708eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner ChunkNo != e; ++ChunkNo) { 709a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner size_t MatchLen = 0; 710eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion, 711eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner MatchLen, 712eec96958cd53ebb61bebfd3af416ace380df6f6cChris Lattner VariableTable); 713f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (Pos == StringRef::npos) continue; 714f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 715f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), 716f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: string occurred!", "error"); 717528700863adefca8de461ce28a7d903729fb96b4Chris Lattner SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, 718f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: pattern specified here", "note"); 719f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return 1; 720f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 721f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 7225dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 72381115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // Otherwise, everything is good. Step over the matched text and remember 72481115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // the position after the match as the end of the last match. 7259fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(MatchLen); 72681115765218f1c1505ab6faf843ee4baf292d45fChris Lattner LastMatch = Buffer.data(); 72781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 72881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 72981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 73081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 731