FileCheck.cpp revision 5d6a05f4d4faea0c0c96fbf2bb57655df2839b34
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"
2681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm;
2781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
2881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string>
2981cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
3081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
3181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string>
3281cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner              cl::init("-"), cl::value_desc("filename"));
3481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
3581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string>
3681cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"),
3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner            cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
3881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
3988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool>
4088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace",
4188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner              cl::desc("Do not treat all horizontal whitespace as equivalent"));
4288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner
43a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===//
44a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code.
45a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===//
46a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
479fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern {
485d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  /// FixedStr - If non-empty, this pattern is a fixed string match with the
495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  /// specified fixed string.
502702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  StringRef FixedStr;
515d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner
525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  /// RegEx - If non-empty, this is a regex pattern.
535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  std::string RegExStr;
549fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic:
559fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner
56a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  Pattern() { }
57a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
58a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  bool ParsePattern(StringRef PatternStr, SourceMgr &SM);
599fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner
609fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  /// Match - Match the pattern string against the input buffer Buffer.  This
619fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  /// returns the position that is matched or npos if there is no match.  If
629fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  /// there is a match, the size of the matched string is returned in MatchLen.
63528700863adefca8de461ce28a7d903729fb96b4Chris Lattner  size_t Match(StringRef Buffer, size_t &MatchLen) const;
645d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner
655d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnerprivate:
665d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  void AddFixedStringToRegEx(StringRef FixedStr);
679fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner};
689fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner
69a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattnerbool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
70a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  // Ignore trailing whitespace.
71a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  while (!PatternStr.empty() &&
72a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
73a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    PatternStr = PatternStr.substr(0, PatternStr.size()-1);
74a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
75a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  // Check that there is something on the line.
76a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  if (PatternStr.empty()) {
77a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
78a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner                    "found empty check string with prefix '"+CheckPrefix+":'",
79a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner                    "error");
80a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    return true;
81a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  }
82528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
832702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  // Check to see if this is a fixed string, or if it has regex pieces.
842702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  if (PatternStr.size() < 2 || PatternStr.find("{{") == StringRef::npos) {
852702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner    FixedStr = PatternStr;
862702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner    return false;
872702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  }
882702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner
895d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // Otherwise, there is at least one regex piece.  Build up the regex pattern
905d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // by escaping scary characters in fixed strings, building up one big regex.
91528700863adefca8de461ce28a7d903729fb96b4Chris Lattner  while (!PatternStr.empty()) {
92528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    // Handle fixed string matches.
93528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    if (PatternStr.size() < 2 ||
94528700863adefca8de461ce28a7d903729fb96b4Chris Lattner        PatternStr[0] != '{' || PatternStr[1] != '{') {
95528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      // Find the end, which is the start of the next regex.
96528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      size_t FixedMatchEnd = PatternStr.find("{{");
975d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner      AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd));
98528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      PatternStr = PatternStr.substr(FixedMatchEnd);
99528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      continue;
100528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    }
101528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
102528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    // Otherwise, this is the start of a regex match.  Scan for the }}.
103528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    size_t End = PatternStr.find("}}");
104528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    if (End == StringRef::npos) {
105528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
106528700863adefca8de461ce28a7d903729fb96b4Chris Lattner                      "found start of regex string with no end '}}'", "error");
107528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      return true;
108528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    }
109528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
1105d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    StringRef RegexStr = PatternStr.substr(2, End-2);
1115d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    Regex R(RegexStr);
112528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    std::string Error;
113528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    if (!R.isValid(Error)) {
114528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()+2),
115528700863adefca8de461ce28a7d903729fb96b4Chris Lattner                      "invalid regex: " + Error, "error");
116528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      return true;
117528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    }
118528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
1195d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    RegExStr += RegexStr.str();
120528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    PatternStr = PatternStr.substr(End+2);
121528700863adefca8de461ce28a7d903729fb96b4Chris Lattner  }
122528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
123528700863adefca8de461ce28a7d903729fb96b4Chris Lattner  return false;
124528700863adefca8de461ce28a7d903729fb96b4Chris Lattner}
125adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
1265d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattnervoid Pattern::AddFixedStringToRegEx(StringRef FixedStr) {
1275d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // Add the characters from FixedStr to the regex, escaping as needed.  This
1285d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // avoids "leaning toothpicks" in common patterns.
1295d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  for (unsigned i = 0, e = FixedStr.size(); i != e; ++i) {
1305d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    switch (FixedStr[i]) {
1315d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    // These are the special characters matched in "p_ere_exp".
1325d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '(':
1335d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case ')':
1345d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '^':
1355d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '$':
1365d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '|':
1375d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '*':
1385d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '+':
1395d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '?':
1405d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '.':
1415d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '[':
1425d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '\\':
1435d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    case '{':
1445d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner      RegExStr += '\\';
1455d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner      // FALL THROUGH.
1465d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    default:
1475d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner      RegExStr += FixedStr[i];
1485d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner      break;
1495d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    }
1505d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  }
1515d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner}
1525d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner
1535d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner
154528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// Match - Match the pattern string against the input buffer Buffer.  This
155528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// returns the position that is matched or npos if there is no match.  If
156528700863adefca8de461ce28a7d903729fb96b4Chris Lattner/// there is a match, the size of the matched string is returned in MatchLen.
157528700863adefca8de461ce28a7d903729fb96b4Chris Lattnersize_t Pattern::Match(StringRef Buffer, size_t &MatchLen) const {
1582702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  // If this is a fixed string pattern, just match it now.
1592702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  if (!FixedStr.empty()) {
1602702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner    MatchLen = FixedStr.size();
1612702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner    return Buffer.find(FixedStr);
1622702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner  }
1632702e6aa53f603b20c3e46364bc1756788bd291aChris Lattner
1645d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // Regex match.
1655d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  SmallVector<StringRef, 4> MatchInfo;
1665d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  if (!Regex(RegExStr, Regex::Sub|Regex::Newline).match(Buffer, &MatchInfo))
1675d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner    return StringRef::npos;
168a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
1695d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  // Successful regex match.
1705d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  assert(!MatchInfo.empty() && "Didn't get any match");
1715d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  StringRef FullMatch = MatchInfo[0];
172528700863adefca8de461ce28a7d903729fb96b4Chris Lattner
1735d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  MatchLen = FullMatch.size();
1745d6a05f4d4faea0c0c96fbf2bb57655df2839b34Chris Lattner  return FullMatch.data()-Buffer.data();
175a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner}
176a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
177a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
178a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===//
179a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings.
180a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===//
1819fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner
1829fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file.
1839fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString {
1849fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  /// Pat - The pattern to match.
1859fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  Pattern Pat;
186207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner
187207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner  /// Loc - The location in the match file that the check string was specified.
188207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner  SMLoc Loc;
189207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner
1905dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
1915dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  /// to a CHECK: directive.
1925dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  bool IsCheckNext;
1935dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
194f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  /// NotStrings - These are all of the strings that are disallowed from
195f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  /// occurring between this match string and the previous one (or start of
196f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  /// file).
197a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  std::vector<std::pair<SMLoc, Pattern> > NotStrings;
198f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
1999fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner  CheckString(const Pattern &P, SMLoc L, bool isCheckNext)
2009fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner    : Pat(P), Loc(L), IsCheckNext(isCheckNext) {}
201207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner};
202207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner
203adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
204adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// memory buffer, free it, and return a new one.
205adea46ed617982ea07fc3266d52717496c0076ceChris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
206adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  SmallVector<char, 16> NewFile;
207adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  NewFile.reserve(MB->getBufferSize());
208adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
209adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
210adea46ed617982ea07fc3266d52717496c0076ceChris Lattner       Ptr != End; ++Ptr) {
211adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    // If C is not a horizontal whitespace, skip it.
212adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    if (*Ptr != ' ' && *Ptr != '\t') {
213adea46ed617982ea07fc3266d52717496c0076ceChris Lattner      NewFile.push_back(*Ptr);
214adea46ed617982ea07fc3266d52717496c0076ceChris Lattner      continue;
215adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    }
216adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
217adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    // Otherwise, add one space and advance over neighboring space.
218adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    NewFile.push_back(' ');
219adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    while (Ptr+1 != End &&
220adea46ed617982ea07fc3266d52717496c0076ceChris Lattner           (Ptr[1] == ' ' || Ptr[1] == '\t'))
221adea46ed617982ea07fc3266d52717496c0076ceChris Lattner      ++Ptr;
222adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  }
223adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
224adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  // Free the old buffer and return a new one.
225adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  MemoryBuffer *MB2 =
226adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    MemoryBuffer::getMemBufferCopy(NewFile.data(),
227adea46ed617982ea07fc3266d52717496c0076ceChris Lattner                                   NewFile.data() + NewFile.size(),
228adea46ed617982ea07fc3266d52717496c0076ceChris Lattner                                   MB->getBufferIdentifier());
229adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
230adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  delete MB;
231adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  return MB2;
232adea46ed617982ea07fc3266d52717496c0076ceChris Lattner}
233adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
23481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
23581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of
23681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings.  The strings are added to the CheckStrings vector.
23781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM,
238207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner                          std::vector<CheckString> &CheckStrings) {
23981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  // Open the check file, and tell SourceMgr about it.
24081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  std::string ErrorStr;
24181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  MemoryBuffer *F =
24281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
24381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  if (F == 0) {
24481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    errs() << "Could not open check file '" << CheckFilename << "': "
24581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner           << ErrorStr << '\n';
24681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    return true;
24781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  }
248adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
249adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  // If we want to canonicalize whitespace, strip excess whitespace from the
250adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  // buffer containing the CHECK lines.
251adea46ed617982ea07fc3266d52717496c0076ceChris Lattner  if (!NoCanonicalizeWhiteSpace)
252adea46ed617982ea07fc3266d52717496c0076ceChris Lattner    F = CanonicalizeInputFile(F);
253adea46ed617982ea07fc3266d52717496c0076ceChris Lattner
25481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  SM.AddNewSourceBuffer(F, SMLoc());
25581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
256d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner  // Find all instances of CheckPrefix followed by : in the file.
25796077036f06478d96c123283a50cfba49858fd40Chris Lattner  StringRef Buffer = F->getBuffer();
25881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
259a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner  std::vector<std::pair<SMLoc, Pattern> > NotMatches;
260f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
26181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  while (1) {
26281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // See if Prefix occurs in the memory buffer.
26396077036f06478d96c123283a50cfba49858fd40Chris Lattner    Buffer = Buffer.substr(Buffer.find(CheckPrefix));
26481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
26581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // If we didn't find a match, we're done.
26696077036f06478d96c123283a50cfba49858fd40Chris Lattner    if (Buffer.empty())
26781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner      break;
26881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
26996077036f06478d96c123283a50cfba49858fd40Chris Lattner    const char *CheckPrefixStart = Buffer.data();
2705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
2715dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // When we find a check prefix, keep track of whether we find CHECK: or
2725dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // CHECK-NEXT:
273f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    bool IsCheckNext = false, IsCheckNot = false;
2745dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
275d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner    // Verify that the : is present after the prefix.
27696077036f06478d96c123283a50cfba49858fd40Chris Lattner    if (Buffer[CheckPrefix.size()] == ':') {
27796077036f06478d96c123283a50cfba49858fd40Chris Lattner      Buffer = Buffer.substr(CheckPrefix.size()+1);
27896077036f06478d96c123283a50cfba49858fd40Chris Lattner    } else if (Buffer.size() > CheckPrefix.size()+6 &&
27996077036f06478d96c123283a50cfba49858fd40Chris Lattner               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
28096077036f06478d96c123283a50cfba49858fd40Chris Lattner      Buffer = Buffer.substr(CheckPrefix.size()+7);
2815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      IsCheckNext = true;
282f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    } else if (Buffer.size() > CheckPrefix.size()+5 &&
283f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
284f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      Buffer = Buffer.substr(CheckPrefix.size()+6);
285f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      IsCheckNot = true;
2865dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    } else {
28796077036f06478d96c123283a50cfba49858fd40Chris Lattner      Buffer = Buffer.substr(1);
288d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner      continue;
289d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner    }
290d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner
29181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // Okay, we found the prefix, yay.  Remember the rest of the line, but
29281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // ignore leading and trailing whitespace.
293f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
29481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
29581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // Scan ahead to the end of line.
29696077036f06478d96c123283a50cfba49858fd40Chris Lattner    size_t EOL = Buffer.find_first_of("\n\r");
297a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
298a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    // Parse the pattern.
299a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    Pattern P;
300a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
30181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner      return true;
30281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
303a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    Buffer = Buffer.substr(EOL);
304a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
305f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
3065dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
3075dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    if (IsCheckNext && CheckStrings.empty()) {
3085dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
3095dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
3105dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                      CheckPrefix+ ": line", "error");
3115dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      return true;
3125dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    }
3135dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
314a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    // Handle CHECK-NOT.
315a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    if (IsCheckNot) {
316a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
317a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner                                          P));
318a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner      continue;
319a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner    }
320a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner
3219fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner
32281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // Okay, add the string we captured to the output vector and move on.
3239fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner    CheckStrings.push_back(CheckString(P,
32496077036f06478d96c123283a50cfba49858fd40Chris Lattner                                       SMLoc::getFromPointer(Buffer.data()),
3255dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                                       IsCheckNext));
326f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    std::swap(NotMatches, CheckStrings.back().NotStrings);
32781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  }
32881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
32981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  if (CheckStrings.empty()) {
330d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner    errs() << "error: no check strings found with prefix '" << CheckPrefix
331d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner           << ":'\n";
33281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    return true;
33381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  }
33481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
335f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  if (!NotMatches.empty()) {
336f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    errs() << "error: '" << CheckPrefix
337f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner           << "-NOT:' not supported after last check line.\n";
338f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    return true;
339f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  }
340f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
34181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  return false;
34281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner}
34381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
3445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
34596077036f06478d96c123283a50cfba49858fd40Chris Lattner                             StringRef Buffer) {
3465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  // Otherwise, we have an error, emit an error message.
3475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
3485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                  "error");
3495dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
3505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  // Print the "scanning from here" line.  If the current position is at the
3515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  // end of a line, advance to the start of the next line.
35296077036f06478d96c123283a50cfba49858fd40Chris Lattner  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
3535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
35496077036f06478d96c123283a50cfba49858fd40Chris Lattner  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
3555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                  "note");
3565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner}
3575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
3583711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified
3593711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range.
3603711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) {
3615dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  unsigned NumNewLines = 0;
3623711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner  while (1) {
3635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // Scan for newline.
3643711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner    Range = Range.substr(Range.find_first_of("\n\r"));
3653711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner    if (Range.empty()) return NumNewLines;
3665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
3675dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    ++NumNewLines;
3685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
3695dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // Handle \n\r and \r\n as a single newline.
3703711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner    if (Range.size() > 1 &&
3713711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner        (Range[1] == '\n' || Range[1] == '\r') &&
3723711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner        (Range[0] != Range[1]))
3733711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner      Range = Range.substr(1);
3743711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner    Range = Range.substr(1);
3755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner  }
3765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner}
3775dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
37881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) {
37981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  sys::PrintStackTraceOnErrorSignal();
38081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  PrettyStackTraceProgram X(argc, argv);
38181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  cl::ParseCommandLineOptions(argc, argv);
38281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
38381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  SourceMgr SM;
38481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
38581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  // Read the expected strings from the check file.
386207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner  std::vector<CheckString> CheckStrings;
38781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  if (ReadCheckFile(SM, CheckStrings))
38881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    return 2;
38981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
39081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  // Open the file to check and add it to SourceMgr.
39181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  std::string ErrorStr;
39281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  MemoryBuffer *F =
39381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
39481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  if (F == 0) {
39581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    errs() << "Could not open input file '" << InputFilename << "': "
39681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner           << ErrorStr << '\n';
39781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    return true;
39881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  }
39988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner
40088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner  // Remove duplicate spaces in the input file if requested.
40188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner  if (!NoCanonicalizeWhiteSpace)
40288a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner    F = CanonicalizeInputFile(F);
40388a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner
40481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  SM.AddNewSourceBuffer(F, SMLoc());
40581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
40681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  // Check that we have all of the expected strings, in order, in the input
40781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  // file.
40896077036f06478d96c123283a50cfba49858fd40Chris Lattner  StringRef Buffer = F->getBuffer();
40981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
410f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner  const char *LastMatch = Buffer.data();
411f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
41281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
413207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner    const CheckString &CheckStr = CheckStrings[StrNo];
41481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
41596077036f06478d96c123283a50cfba49858fd40Chris Lattner    StringRef SearchFrom = Buffer;
41696077036f06478d96c123283a50cfba49858fd40Chris Lattner
41781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    // Find StrNo in the file.
4189fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner    size_t MatchLen = 0;
4199fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner    Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen));
42081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
4215dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // If we didn't find a match, reject the input.
42296077036f06478d96c123283a50cfba49858fd40Chris Lattner    if (Buffer.empty()) {
42396077036f06478d96c123283a50cfba49858fd40Chris Lattner      PrintCheckFailed(SM, CheckStr, SearchFrom);
4245dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      return 1;
42581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner    }
4263711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner
4273711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);
4283711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner
4295dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // If this check is a "CHECK-NEXT", verify that the previous match was on
4305dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    // the previous line (i.e. that there is one newline between them).
4315dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    if (CheckStr.IsCheckNext) {
4325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      // Count the number of newlines between the previous match and this one.
433f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      assert(LastMatch != F->getBufferStart() &&
434f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner             "CHECK-NEXT can't be the first check in a file");
4355dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
4363711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
4375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      if (NumNewLines == 0) {
4380b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner        SM.PrintMessage(CheckStr.Loc,
4395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                    CheckPrefix+"-NEXT: is on the same line as previous match",
4405dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        "error");
44196077036f06478d96c123283a50cfba49858fd40Chris Lattner        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
4420b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner                        "'next' match was here", "note");
4435dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
4445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        "previous match was here", "note");
4455dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner        return 1;
4465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      }
4475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
4485dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      if (NumNewLines != 1) {
4490b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner        SM.PrintMessage(CheckStr.Loc,
4505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        CheckPrefix+
4515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        "-NEXT: is not on the line after the previous match",
4525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        "error");
45396077036f06478d96c123283a50cfba49858fd40Chris Lattner        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
4540b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner                        "'next' match was here", "note");
4555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
4565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner                        "previous match was here", "note");
4575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner        return 1;
4585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner      }
4595dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner    }
460f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
461f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    // If this match had "not strings", verify that they don't exist in the
462f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    // skipped region.
463528700863adefca8de461ce28a7d903729fb96b4Chris Lattner    for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size(); ChunkNo != e; ++ChunkNo) {
464a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner      size_t MatchLen = 0;
465528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion, MatchLen);
466f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      if (Pos == StringRef::npos) continue;
467f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
468f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
469f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner                      CheckPrefix+"-NOT: string occurred!", "error");
470528700863adefca8de461ce28a7d903729fb96b4Chris Lattner      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
471f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner                      CheckPrefix+"-NOT: pattern specified here", "note");
472f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner      return 1;
473f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner    }
474f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner
4755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner
47681115765218f1c1505ab6faf843ee4baf292d45fChris Lattner    // Otherwise, everything is good.  Step over the matched text and remember
47781115765218f1c1505ab6faf843ee4baf292d45fChris Lattner    // the position after the match as the end of the last match.
4789fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner    Buffer = Buffer.substr(MatchLen);
47981115765218f1c1505ab6faf843ee4baf292d45fChris Lattner    LastMatch = Buffer.data();
48081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  }
48181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner
48281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner  return 0;
48381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner}
484