FileCheck.cpp revision adea46ed617982ea07fc3266d52717496c0076ce
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" 2281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/SourceMgr.h" 2381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/Support/raw_ostream.h" 2481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner#include "llvm/System/Signals.h" 2581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerusing namespace llvm; 2681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 2781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 2881cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required); 2981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3181cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerInputFilename("input-file", cl::desc("File to check (defaults to stdin)"), 3281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::init("-"), cl::value_desc("filename")); 3381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic cl::opt<std::string> 3581cb8caa3eb482d45e0fd54f8022384256619178Chris LattnerCheckPrefix("check-prefix", cl::init("CHECK"), 3681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::desc("Prefix to use from check file (defaults to 'CHECK')")); 3781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattnerstatic cl::opt<bool> 3988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris LattnerNoCanonicalizeWhiteSpace("strict-whitespace", 4088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner cl::desc("Do not treat all horizontal whitespace as equivalent")); 4188a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 42a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 43a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Pattern Handling Code. 44a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 45a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 469fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerclass Pattern { 47207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Str - The string to match. 48adea46ed617982ea07fc3266d52717496c0076ceChris Lattner StringRef Str; 499fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerpublic: 509fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 51a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern() { } 52a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 53a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner bool ParsePattern(StringRef PatternStr, SourceMgr &SM); 549fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 559fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Match - Match the pattern string against the input buffer Buffer. This 569fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// returns the position that is matched or npos if there is no match. If 579fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// there is a match, the size of the matched string is returned in MatchLen. 589fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner size_t Match(StringRef Buffer, size_t &MatchLen) const { 599fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner MatchLen = Str.size(); 609fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner return Buffer.find(Str); 619fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner } 629fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner}; 639fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 64a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattnerbool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) { 65a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Ignore trailing whitespace. 66a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner while (!PatternStr.empty() && 67a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 68a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner PatternStr = PatternStr.substr(0, PatternStr.size()-1); 69a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 70a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Check that there is something on the line. 71a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (PatternStr.empty()) { 72a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 73a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner "found empty check string with prefix '"+CheckPrefix+":'", 74a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner "error"); 75a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return true; 76a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 77adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 78a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 79a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 80adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Str = PatternStr; 81a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner return false; 82a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner} 83a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 84a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 85a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 86a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner// Check Strings. 87a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner//===----------------------------------------------------------------------===// 889fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 899fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner/// CheckString - This is a check that we found in the input file. 909fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattnerstruct CheckString { 919fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner /// Pat - The pattern to match. 929fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Pattern Pat; 93207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 94207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner /// Loc - The location in the match file that the check string was specified. 95207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner SMLoc Loc; 96207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 975dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed 985dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner /// to a CHECK: directive. 995dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner bool IsCheckNext; 1005dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 101f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// NotStrings - These are all of the strings that are disallowed from 102f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// occurring between this match string and the previous one (or start of 103f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner /// file). 104a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotStrings; 105f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 1069fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckString(const Pattern &P, SMLoc L, bool isCheckNext) 1079fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner : Pat(P), Loc(L), IsCheckNext(isCheckNext) {} 108207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner}; 109207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner 110adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified 111adea46ed617982ea07fc3266d52717496c0076ceChris Lattner/// memory buffer, free it, and return a new one. 112adea46ed617982ea07fc3266d52717496c0076ceChris Lattnerstatic MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { 113adea46ed617982ea07fc3266d52717496c0076ceChris Lattner SmallVector<char, 16> NewFile; 114adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.reserve(MB->getBufferSize()); 115adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 116adea46ed617982ea07fc3266d52717496c0076ceChris Lattner for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd(); 117adea46ed617982ea07fc3266d52717496c0076ceChris Lattner Ptr != End; ++Ptr) { 118adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If C is not a horizontal whitespace, skip it. 119adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (*Ptr != ' ' && *Ptr != '\t') { 120adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(*Ptr); 121adea46ed617982ea07fc3266d52717496c0076ceChris Lattner continue; 122adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 123adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 124adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Otherwise, add one space and advance over neighboring space. 125adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.push_back(' '); 126adea46ed617982ea07fc3266d52717496c0076ceChris Lattner while (Ptr+1 != End && 127adea46ed617982ea07fc3266d52717496c0076ceChris Lattner (Ptr[1] == ' ' || Ptr[1] == '\t')) 128adea46ed617982ea07fc3266d52717496c0076ceChris Lattner ++Ptr; 129adea46ed617982ea07fc3266d52717496c0076ceChris Lattner } 130adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 131adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // Free the old buffer and return a new one. 132adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer *MB2 = 133adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MemoryBuffer::getMemBufferCopy(NewFile.data(), 134adea46ed617982ea07fc3266d52717496c0076ceChris Lattner NewFile.data() + NewFile.size(), 135adea46ed617982ea07fc3266d52717496c0076ceChris Lattner MB->getBufferIdentifier()); 136adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 137adea46ed617982ea07fc3266d52717496c0076ceChris Lattner delete MB; 138adea46ed617982ea07fc3266d52717496c0076ceChris Lattner return MB2; 139adea46ed617982ea07fc3266d52717496c0076ceChris Lattner} 140adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 14181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 14281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// ReadCheckFile - Read the check file, which specifies the sequence of 14381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner/// expected strings. The strings are added to the CheckStrings vector. 14481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerstatic bool ReadCheckFile(SourceMgr &SM, 145207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> &CheckStrings) { 14681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the check file, and tell SourceMgr about it. 14781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 14881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 14981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr); 15081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 15181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open check file '" << CheckFilename << "': " 15281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 15381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 15481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 155adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 156adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // If we want to canonicalize whitespace, strip excess whitespace from the 157adea46ed617982ea07fc3266d52717496c0076ceChris Lattner // buffer containing the CHECK lines. 158adea46ed617982ea07fc3266d52717496c0076ceChris Lattner if (!NoCanonicalizeWhiteSpace) 159adea46ed617982ea07fc3266d52717496c0076ceChris Lattner F = CanonicalizeInputFile(F); 160adea46ed617982ea07fc3266d52717496c0076ceChris Lattner 16181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 16281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 163d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Find all instances of CheckPrefix followed by : in the file. 16496077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 16581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 166a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner std::vector<std::pair<SMLoc, Pattern> > NotMatches; 167f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 16881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner while (1) { 16981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // See if Prefix occurs in the memory buffer. 17096077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find(CheckPrefix)); 17181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 17281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // If we didn't find a match, we're done. 17396077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) 17481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner break; 17581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 17696077036f06478d96c123283a50cfba49858fd40Chris Lattner const char *CheckPrefixStart = Buffer.data(); 1775dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 1785dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // When we find a check prefix, keep track of whether we find CHECK: or 1795dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // CHECK-NEXT: 180f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner bool IsCheckNext = false, IsCheckNot = false; 1815dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 182d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner // Verify that the : is present after the prefix. 18396077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer[CheckPrefix.size()] == ':') { 18496077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+1); 18596077036f06478d96c123283a50cfba49858fd40Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+6 && 18696077036f06478d96c123283a50cfba49858fd40Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) { 18796077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+7); 1885dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext = true; 189f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } else if (Buffer.size() > CheckPrefix.size()+5 && 190f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) { 191f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(CheckPrefix.size()+6); 192f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner IsCheckNot = true; 1935dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } else { 19496077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(1); 195d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner continue; 196d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner } 197d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner 19881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, we found the prefix, yay. Remember the rest of the line, but 19981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // ignore leading and trailing whitespace. 200f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 20181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 20281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Scan ahead to the end of line. 20396077036f06478d96c123283a50cfba49858fd40Chris Lattner size_t EOL = Buffer.find_first_of("\n\r"); 204a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 205a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Parse the pattern. 206a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Pattern P; 207a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (P.ParsePattern(Buffer.substr(0, EOL), SM)) 20881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 20981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 210a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner Buffer = Buffer.substr(EOL); 211a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 212f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 2135dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Verify that CHECK-NEXT lines have at least one CHECK line before them. 2145dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (IsCheckNext && CheckStrings.empty()) { 2155dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart), 2165dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "found '"+CheckPrefix+"-NEXT:' without previous '"+ 2175dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ ": line", "error"); 2185dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return true; 2195dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 2205dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 221a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner // Handle CHECK-NOT. 222a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner if (IsCheckNot) { 223a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()), 224a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner P)); 225a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner continue; 226a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner } 227a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner 2289fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner 22981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Okay, add the string we captured to the output vector and move on. 2309fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner CheckStrings.push_back(CheckString(P, 23196077036f06478d96c123283a50cfba49858fd40Chris Lattner SMLoc::getFromPointer(Buffer.data()), 2325dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner IsCheckNext)); 233f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner std::swap(NotMatches, CheckStrings.back().NotStrings); 23481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 23581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 23681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (CheckStrings.empty()) { 237d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner errs() << "error: no check strings found with prefix '" << CheckPrefix 238d7e250527c38297c900db43a9e2f1e56b235b3ccChris Lattner << ":'\n"; 23981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 24081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 24181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 242f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (!NotMatches.empty()) { 243f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner errs() << "error: '" << CheckPrefix 244f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner << "-NOT:' not supported after last check line.\n"; 245f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return true; 246f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 247f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 24881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return false; 24981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 25081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 2515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattnerstatic void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, 25296077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer) { 2535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Otherwise, we have an error, emit an error message. 2545dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(CheckStr.Loc, "expected string not found in input", 2555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 2565dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Print the "scanning from here" line. If the current position is at the 2585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // end of a line, advance to the start of the next line. 25996077036f06478d96c123283a50cfba49858fd40Chris Lattner Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); 2605dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 26196077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here", 2625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "note"); 2635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 2645dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2653711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// CountNumNewlinesBetween - Count the number of newlines in the specified 2663711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner/// range. 2673711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattnerstatic unsigned CountNumNewlinesBetween(StringRef Range) { 2685dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner unsigned NumNewLines = 0; 2693711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner while (1) { 2705dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Scan for newline. 2713711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(Range.find_first_of("\n\r")); 2723711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.empty()) return NumNewLines; 2735dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2745dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner ++NumNewLines; 2755dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 2765dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Handle \n\r and \r\n as a single newline. 2773711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner if (Range.size() > 1 && 2783711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[1] == '\n' || Range[1] == '\r') && 2793711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner (Range[0] != Range[1])) 2803711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 2813711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner Range = Range.substr(1); 2825dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 2835dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner} 2845dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 28581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattnerint main(int argc, char **argv) { 28681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner sys::PrintStackTraceOnErrorSignal(); 28781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner PrettyStackTraceProgram X(argc, argv); 28881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner cl::ParseCommandLineOptions(argc, argv); 28981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 29081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SourceMgr SM; 29181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 29281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Read the expected strings from the check file. 293207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner std::vector<CheckString> CheckStrings; 29481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (ReadCheckFile(SM, CheckStrings)) 29581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 2; 29681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 29781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Open the file to check and add it to SourceMgr. 29881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner std::string ErrorStr; 29981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer *F = 30081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr); 30181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner if (F == 0) { 30281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner errs() << "Could not open input file '" << InputFilename << "': " 30381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner << ErrorStr << '\n'; 30481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return true; 30581cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 30688a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 30788a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner // Remove duplicate spaces in the input file if requested. 30888a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner if (!NoCanonicalizeWhiteSpace) 30988a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner F = CanonicalizeInputFile(F); 31088a7e9ee8dd2f1d2f40cdb9c378f050e45161783Chris Lattner 31181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner SM.AddNewSourceBuffer(F, SMLoc()); 31281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 31381cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Check that we have all of the expected strings, in order, in the input 31481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // file. 31596077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef Buffer = F->getBuffer(); 31681cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 317f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner const char *LastMatch = Buffer.data(); 318f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 31981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) { 320207e1bcf897d1c732f717b9773029651ecc59ab2Chris Lattner const CheckString &CheckStr = CheckStrings[StrNo]; 32181cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 32296077036f06478d96c123283a50cfba49858fd40Chris Lattner StringRef SearchFrom = Buffer; 32396077036f06478d96c123283a50cfba49858fd40Chris Lattner 32481cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner // Find StrNo in the file. 3259fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner size_t MatchLen = 0; 3269fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen)); 32781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 3285dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If we didn't find a match, reject the input. 32996077036f06478d96c123283a50cfba49858fd40Chris Lattner if (Buffer.empty()) { 33096077036f06478d96c123283a50cfba49858fd40Chris Lattner PrintCheckFailed(SM, CheckStr, SearchFrom); 3315dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 33281cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 3333711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 3343711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch); 3353711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner 3365dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // If this check is a "CHECK-NEXT", verify that the previous match was on 3375dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // the previous line (i.e. that there is one newline between them). 3385dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (CheckStr.IsCheckNext) { 3395dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner // Count the number of newlines between the previous match and this one. 340f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner assert(LastMatch != F->getBufferStart() && 341f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner "CHECK-NEXT can't be the first check in a file"); 3425dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3433711b7adccc766fdbafbc6b22c2bb6c45181a3b9Chris Lattner unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion); 3445dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines == 0) { 3450b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 3465dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+"-NEXT: is on the same line as previous match", 3475dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 34896077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 3490b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 3505dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 3515dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 3525dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 3535dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3545dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 3555dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner if (NumNewLines != 1) { 3560b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner SM.PrintMessage(CheckStr.Loc, 3575dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner CheckPrefix+ 3585dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "-NEXT: is not on the line after the previous match", 3595dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "error"); 36096077036f06478d96c123283a50cfba49858fd40Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), 3610b2353f277f7a92b48af20f9804c6c35d96ecb75Chris Lattner "'next' match was here", "note"); 3625dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch), 3635dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner "previous match was here", "note"); 3645dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner return 1; 3655dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 3665dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner } 367f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 368f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // If this match had "not strings", verify that they don't exist in the 369f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner // skipped region. 370f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner for (unsigned i = 0, e = CheckStr.NotStrings.size(); i != e; ++i) { 371a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner size_t MatchLen = 0; 372a29703e8426763fa5232f9a91e6a5fce4d4244d6Chris Lattner size_t Pos = CheckStr.NotStrings[i].second.Match(SkippedRegion, MatchLen); 373f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner if (Pos == StringRef::npos) continue; 374f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 375f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), 376f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: string occurred!", "error"); 377f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner SM.PrintMessage(CheckStr.NotStrings[i].first, 378f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner CheckPrefix+"-NOT: pattern specified here", "note"); 379f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner return 1; 380f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner } 381f15380ba8ae35941dcd56d9a288ad023295dde30Chris Lattner 3825dafafdeb4d89b37c6b7efbeabaa7d818c7023feChris Lattner 38381115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // Otherwise, everything is good. Step over the matched text and remember 38481115765218f1c1505ab6faf843ee4baf292d45fChris Lattner // the position after the match as the end of the last match. 3859fc6678bea11f32acba4e9b6624ae9a0d3a9287bChris Lattner Buffer = Buffer.substr(MatchLen); 38681115765218f1c1505ab6faf843ee4baf292d45fChris Lattner LastMatch = Buffer.data(); 38781cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner } 38881cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner 38981cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner return 0; 39081cb8caa3eb482d45e0fd54f8022384256619178Chris Lattner} 391