Copy some AVX support from MCJIT to JIT. Maybe will fix PR12748.
[oota-llvm.git] / utils / FileCheck / FileCheck.cpp
index cd76d44043086016320ea674070c65da099df4bd..33f04ce647794bf7e94a18b18695d74156b5bbdb 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include <algorithm>
@@ -50,6 +52,10 @@ NoCanonicalizeWhiteSpace("strict-whitespace",
 class Pattern {
   SMLoc PatternLoc;
 
+  /// MatchEOF - When set, this pattern only matches the end of file. This is
+  /// used for trailing CHECK-NOTs.
+  bool MatchEOF;
+
   /// FixedStr - If non-empty, this pattern is a fixed string match with the
   /// specified fixed string.
   StringRef FixedStr;
@@ -71,7 +77,7 @@ class Pattern {
 
 public:
 
-  Pattern() { }
+  Pattern(bool matchEOF = false) : MatchEOF(matchEOF) { }
 
   bool ParsePattern(StringRef PatternStr, SourceMgr &SM);
 
@@ -111,8 +117,9 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
 
   // Check that there is something on the line.
   if (PatternStr.empty()) {
-    SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
-                    CheckPrefix+":'", "error");
+    SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
+                    "found empty check string with prefix '" +
+                    CheckPrefix+":'");
     return true;
   }
 
@@ -125,26 +132,35 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
   }
 
   // Paren value #0 is for the fully matched string.  Any new parenthesized
-  // values add from their.
+  // values add from there.
   unsigned CurParen = 1;
 
   // Otherwise, there is at least one regex piece.  Build up the regex pattern
   // by escaping scary characters in fixed strings, building up one big regex.
   while (!PatternStr.empty()) {
     // RegEx matches.
-    if (PatternStr.size() >= 2 &&
-        PatternStr[0] == '{' && PatternStr[1] == '{') {
+    if (PatternStr.startswith("{{")) {
 
       // Otherwise, this is the start of a regex match.  Scan for the }}.
       size_t End = PatternStr.find("}}");
       if (End == StringRef::npos) {
         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
-                        "found start of regex string with no end '}}'", "error");
+                        SourceMgr::DK_Error,
+                        "found start of regex string with no end '}}'");
         return true;
       }
 
+      // Enclose {{}} patterns in parens just like [[]] even though we're not
+      // capturing the result for any purpose.  This is required in case the
+      // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
+      // want this to turn into: "abc(x|z)def" not "abcx|zdef".
+      RegExStr += '(';
+      ++CurParen;
+
       if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
         return true;
+      RegExStr += ')';
+
       PatternStr = PatternStr.substr(End+2);
       continue;
     }
@@ -154,13 +170,13 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
     // second form is [[foo]] which is a reference to foo.  The variable name
     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
     // it.  This is to catch some common errors.
-    if (PatternStr.size() >= 2 &&
-        PatternStr[0] == '[' && PatternStr[1] == '[') {
+    if (PatternStr.startswith("[[")) {
       // Verify that it is terminated properly.
       size_t End = PatternStr.find("]]");
       if (End == StringRef::npos) {
         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
-                        "invalid named regex reference, no ]] found", "error");
+                        SourceMgr::DK_Error,
+                        "invalid named regex reference, no ]] found");
         return true;
       }
 
@@ -172,26 +188,23 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
       StringRef Name = MatchStr.substr(0, NameEnd);
 
       if (Name.empty()) {
-        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
-                        "invalid name in named regex: empty name", "error");
+        SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
+                        "invalid name in named regex: empty name");
         return true;
       }
 
       // Verify that the name is well formed.
       for (unsigned i = 0, e = Name.size(); i != e; ++i)
-        if (Name[i] != '_' &&
-            (Name[i] < 'a' || Name[i] > 'z') &&
-            (Name[i] < 'A' || Name[i] > 'Z') &&
-            (Name[i] < '0' || Name[i] > '9')) {
+        if (Name[i] != '_' && !isalnum(Name[i])) {
           SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
-                          "invalid name in named regex", "error");
+                          SourceMgr::DK_Error, "invalid name in named regex");
           return true;
         }
 
       // Name can't start with a digit.
       if (isdigit(Name[0])) {
-        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
-                        "invalid name in named regex", "error");
+        SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
+                        "invalid name in named regex");
         return true;
       }
 
@@ -256,8 +269,8 @@ bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
   Regex R(RegexStr);
   std::string Error;
   if (!R.isValid(Error)) {
-    SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()),
-                    "invalid regex: " + Error, "error");
+    SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), SourceMgr::DK_Error,
+                    "invalid regex: " + Error);
     return true;
   }
 
@@ -271,6 +284,12 @@ bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
 /// there is a match, the size of the matched string is returned in MatchLen.
 size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
                       StringMap<StringRef> &VariableTable) const {
+  // If this is the EOF pattern, match it immediately.
+  if (MatchEOF) {
+    MatchLen = 0;
+    return Buffer.size();
+  }
+
   // If this is a fixed string pattern, just match it now.
   if (!FixedStr.empty()) {
     MatchLen = FixedStr.size();
@@ -367,8 +386,8 @@ void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
         OS.write_escaped(it->second) << "\"";
       }
 
-      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
-                      /*ShowLine=*/false);
+      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
+                      OS.str());
     }
   }
 
@@ -406,7 +425,7 @@ void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
   // line.
   if (Best && Best != StringRef::npos && BestQuality < 50) {
       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
-                      "possible intended match here", "note");
+                      SourceMgr::DK_Note, "possible intended match here");
 
     // FIXME: If we wanted to be really friendly we would show why the match
     // failed, as it can be hard to spot simple one character differences.
@@ -446,6 +465,11 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
 
   for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
        Ptr != End; ++Ptr) {
+    // Eliminate trailing dosish \r.
+    if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
+      continue;
+    }
+
     // If C is not a horizontal whitespace, skip it.
     if (*Ptr != ' ' && *Ptr != '\t') {
       NewFile.push_back(*Ptr);
@@ -473,14 +497,14 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
 static bool ReadCheckFile(SourceMgr &SM,
                           std::vector<CheckString> &CheckStrings) {
   // Open the check file, and tell SourceMgr about it.
-  std::string ErrorStr;
-  MemoryBuffer *F =
-    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
-  if (F == 0) {
+  OwningPtr<MemoryBuffer> File;
+  if (error_code ec =
+        MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), File)) {
     errs() << "Could not open check file '" << CheckFilename << "': "
-           << ErrorStr << '\n';
+           << ec.message() << '\n';
     return true;
   }
+  MemoryBuffer *F = File.take();
 
   // If we want to canonicalize whitespace, strip excess whitespace from the
   // buffer containing the CHECK lines.
@@ -545,8 +569,9 @@ static bool ReadCheckFile(SourceMgr &SM,
     // Verify that CHECK-NEXT lines have at least one CHECK line before them.
     if (IsCheckNext && CheckStrings.empty()) {
       SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
+                      SourceMgr::DK_Error,
                       "found '"+CheckPrefix+"-NEXT:' without previous '"+
-                      CheckPrefix+ ": line", "error");
+                      CheckPrefix+ ": line");
       return true;
     }
 
@@ -565,18 +590,20 @@ static bool ReadCheckFile(SourceMgr &SM,
     std::swap(NotMatches, CheckStrings.back().NotStrings);
   }
 
+  // Add an EOF pattern for any trailing CHECK-NOTs.
+  if (!NotMatches.empty()) {
+    CheckStrings.push_back(CheckString(Pattern(true),
+                                       SMLoc::getFromPointer(Buffer.data()),
+                                       false));
+    std::swap(NotMatches, CheckStrings.back().NotStrings);
+  }
+
   if (CheckStrings.empty()) {
     errs() << "error: no check strings found with prefix '" << CheckPrefix
            << ":'\n";
     return true;
   }
 
-  if (!NotMatches.empty()) {
-    errs() << "error: '" << CheckPrefix
-           << "-NOT:' not supported after last check line.\n";
-    return true;
-  }
-
   return false;
 }
 
@@ -584,15 +611,15 @@ static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
                              StringRef Buffer,
                              StringMap<StringRef> &VariableTable) {
   // Otherwise, we have an error, emit an error message.
-  SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
-                  "error");
+  SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
+                  "expected string not found in input");
 
   // Print the "scanning from here" line.  If the current position is at the
   // end of a line, advance to the start of the next line.
   Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
 
-  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
-                  "note");
+  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
+                  "scanning from here");
 
   // Allow the pattern to print additional information if desired.
   CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
@@ -631,15 +658,20 @@ int main(int argc, char **argv) {
     return 2;
 
   // Open the file to check and add it to SourceMgr.
-  std::string ErrorStr;
-  MemoryBuffer *F =
-    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
-  if (F == 0) {
+  OwningPtr<MemoryBuffer> File;
+  if (error_code ec =
+        MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
     errs() << "Could not open input file '" << InputFilename << "': "
-           << ErrorStr << '\n';
+           << ec.message() << '\n';
     return true;
   }
+  MemoryBuffer *F = File.take();
 
+  if (F->getBufferSize() == 0) {
+    errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
+    return 1;
+  }
+  
   // Remove duplicate spaces in the input file if requested.
   if (!NoCanonicalizeWhiteSpace)
     F = CanonicalizeInputFile(F);
@@ -662,10 +694,11 @@ int main(int argc, char **argv) {
 
     // Find StrNo in the file.
     size_t MatchLen = 0;
-    Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));
+    size_t MatchPos = CheckStr.Pat.Match(Buffer, MatchLen, VariableTable);
+    Buffer = Buffer.substr(MatchPos);
 
     // If we didn't find a match, reject the input.
-    if (Buffer.empty()) {
+    if (MatchPos == StringRef::npos) {
       PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
       return 1;
     }
@@ -681,25 +714,22 @@ int main(int argc, char **argv) {
 
       unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
       if (NumNewLines == 0) {
-        SM.PrintMessage(CheckStr.Loc,
-                    CheckPrefix+"-NEXT: is on the same line as previous match",
-                        "error");
+        SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
+                    CheckPrefix+"-NEXT: is on the same line as previous match");
         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
-                        "'next' match was here", "note");
-        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
-                        "previous match was here", "note");
+                        SourceMgr::DK_Note, "'next' match was here");
+        SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
+                        "previous match was here");
         return 1;
       }
 
       if (NumNewLines != 1) {
-        SM.PrintMessage(CheckStr.Loc,
-                        CheckPrefix+
-                        "-NEXT: is not on the line after the previous match",
-                        "error");
+        SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error, CheckPrefix+
+                        "-NEXT: is not on the line after the previous match");
         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
-                        "'next' match was here", "note");
-        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
-                        "previous match was here", "note");
+                        SourceMgr::DK_Note, "'next' match was here");
+        SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
+                        "previous match was here");
         return 1;
       }
     }
@@ -714,10 +744,10 @@ int main(int argc, char **argv) {
                                                              VariableTable);
       if (Pos == StringRef::npos) continue;
 
-      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
-                      CheckPrefix+"-NOT: string occurred!", "error");
-      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
-                      CheckPrefix+"-NOT: pattern specified here", "note");
+      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), SourceMgr::DK_Error,
+                      CheckPrefix+"-NOT: string occurred!");
+      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, SourceMgr::DK_Note,
+                      CheckPrefix+"-NOT: pattern specified here");
       return 1;
     }