FileCheck refactor: use enum instead of bunch of bools

llvm-svn: 190893
This commit is contained in:
Matt Arsenault 2013-09-17 22:30:02 +00:00
parent 1ebb145bdf
commit 38820972e9
1 changed files with 88 additions and 76 deletions

View File

@ -53,18 +53,25 @@ NoCanonicalizeWhiteSpace("strict-whitespace",
// Pattern Handling Code.
//===----------------------------------------------------------------------===//
namespace Check {
enum CheckType {
CheckNone = 0,
CheckPlain,
CheckNext,
CheckNot,
CheckDAG,
CheckLabel,
/// MatchEOF - When set, this pattern only matches the end of file. This is
/// used for trailing CHECK-NOTs.
CheckEOF
};
}
class Pattern {
SMLoc PatternLoc;
/// MatchEOF - When set, this pattern only matches the end of file. This is
/// used for trailing CHECK-NOTs.
bool MatchEOF;
/// MatchNot
bool MatchNot;
/// MatchDag
bool MatchDag;
Check::CheckType CheckTy;
/// FixedStr - If non-empty, this pattern is a fixed string match with the
/// specified fixed string.
@ -89,8 +96,8 @@ class Pattern {
public:
Pattern(bool matchEOF = false)
: MatchEOF(matchEOF), MatchNot(false), MatchDag(false) { }
Pattern(Check::CheckType Ty)
: CheckTy(Ty) { }
/// getLoc - Return the location in source code.
SMLoc getLoc() const { return PatternLoc; }
@ -118,11 +125,7 @@ public:
bool hasVariable() const { return !(VariableUses.empty() &&
VariableDefs.empty()); }
void setMatchNot(bool Not) { MatchNot = Not; }
bool getMatchNot() const { return MatchNot; }
void setMatchDag(bool Dag) { MatchDag = Dag; }
bool getMatchDag() const { return MatchDag; }
Check::CheckType getCheckTy() const { return CheckTy; }
private:
static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
@ -381,7 +384,7 @@ bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
StringMap<StringRef> &VariableTable) const {
// If this is the EOF pattern, match it immediately.
if (MatchEOF) {
if (CheckTy == Check::CheckEOF) {
MatchLen = 0;
return Buffer.size();
}
@ -593,21 +596,17 @@ struct CheckString {
/// Loc - The location in the match file that the check string was specified.
SMLoc Loc;
/// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
/// to a CHECK: directive.
bool IsCheckNext;
/// IsCheckLabel - This is true if this is a CHECK-LABEL: directive (as
/// opposed to a CHECK: directive.
bool IsCheckLabel;
/// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
/// as opposed to a CHECK: directive.
Check::CheckType CheckTy;
/// DagNotStrings - These are all of the strings that are disallowed from
/// occurring between this match string and the previous one (or start of
/// file).
std::vector<Pattern> DagNotStrings;
CheckString(const Pattern &P, SMLoc L, bool isCheckNext, bool isCheckLabel)
: Pat(P), Loc(L), IsCheckNext(isCheckNext), IsCheckLabel(isCheckLabel) {}
CheckString(const Pattern &P, SMLoc L, Check::CheckType Ty)
: Pat(P), Loc(L), CheckTy(Ty) {}
/// Check - Match check string and its "not strings" and/or "dag strings".
size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabel,
@ -666,6 +665,48 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB,
return MB2;
}
static bool IsPartOfWord(char c) {
return (isalnum(c) || c == '-' || c == '_');
}
static Check::CheckType FindCheckType(StringRef &Buffer, StringRef Prefix) {
char NextChar = Buffer[CheckPrefix.size()];
// Verify that the : is present after the prefix.
if (NextChar == ':') {
Buffer = Buffer.substr(CheckPrefix.size() + 1);
return Check::CheckPlain;
}
if (NextChar != '-') {
Buffer = Buffer.drop_front(1);
return Check::CheckNone;
}
StringRef Rest = Buffer.drop_front(CheckPrefix.size() + 1);
if (Rest.startswith("NEXT:")) {
Buffer = Rest.drop_front(sizeof("NEXT:") - 1);
return Check::CheckNext;
}
if (Rest.startswith("NOT:")) {
Buffer = Rest.drop_front(sizeof("NOT:") - 1);
return Check::CheckNot;
}
if (Rest.startswith("DAG:")) {
Buffer = Rest.drop_front(sizeof("DAG:") - 1);
return Check::CheckDAG;
}
if (Rest.startswith("LABEL:")) {
Buffer = Rest.drop_front(sizeof("LABEL:") - 1);
return Check::CheckLabel;
}
Buffer = Buffer.drop_front(1);
return Check::CheckNone;
}
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings. The strings are added to the CheckStrings vector.
@ -710,46 +751,21 @@ static bool ReadCheckFile(SourceMgr &SM,
const char *CheckPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
// When we find a check prefix, keep track of whether we find CHECK: or
// CHECK-NEXT:
bool IsCheckNext = false, IsCheckNot = false, IsCheckDag = false,
IsCheckLabel = false;
// Make sure we have actually found our prefix, and not a word containing
// our prefix.
if (PrefixLoc != 0 && (isalnum(Buffer[0]) ||
Buffer[0] == '-' ||
Buffer[0] == '_')) {
if (PrefixLoc != 0 && IsPartOfWord(Buffer[0])) {
Buffer = Buffer.substr(CheckPrefix.size());
continue;
}
// Verify that the : is present after the prefix.
if (Buffer[CheckPrefix.size()] == ':') {
Buffer = Buffer.substr(CheckPrefix.size()+1);
} else if (Buffer.size() > CheckPrefix.size()+6 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+6);
IsCheckNext = true;
} else if (Buffer.size() > CheckPrefix.size()+5 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+5);
IsCheckNot = true;
} else if (Buffer.size() > CheckPrefix.size()+5 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-DAG:", 5) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+5);
IsCheckDag = true;
} else if (Buffer.size() > CheckPrefix.size()+7 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-LABEL:", 7) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+7);
IsCheckLabel = true;
} else {
Buffer = Buffer.substr(1);
// When we find a check prefix, keep track of what kind of type of CHECK we
// have.
Check::CheckType CheckTy = FindCheckType(Buffer, CheckPrefix);
if (CheckTy == Check::CheckNone)
continue;
}
// Okay, we found the prefix, yay. Remember the rest of the line, but
// ignore leading and trailing whitespace.
// Okay, we found the prefix, yay. Remember the rest of the line, but ignore
// leading and trailing whitespace.
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
// Scan ahead to the end of line.
@ -759,12 +775,12 @@ static bool ReadCheckFile(SourceMgr &SM,
SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
// Parse the pattern.
Pattern P;
Pattern P(CheckTy);
if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
return true;
// Verify that CHECK-LABEL lines do not define or use variables
if (IsCheckLabel && P.hasVariable()) {
if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
SourceMgr::DK_Error,
"found '"+CheckPrefix+"-LABEL:' with variable definition"
@ -772,13 +788,10 @@ static bool ReadCheckFile(SourceMgr &SM,
return true;
}
P.setMatchNot(IsCheckNot);
P.setMatchDag(IsCheckDag);
Buffer = Buffer.substr(EOL);
// Verify that CHECK-NEXT lines have at least one CHECK line before them.
if (IsCheckNext && CheckStrings.empty()) {
if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
SourceMgr::DK_Error,
"found '"+CheckPrefix+"-NEXT:' without previous '"+
@ -787,7 +800,7 @@ static bool ReadCheckFile(SourceMgr &SM,
}
// Handle CHECK-DAG/-NOT.
if (IsCheckDag || IsCheckNot) {
if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
DagNotMatches.push_back(P);
continue;
}
@ -795,17 +808,15 @@ static bool ReadCheckFile(SourceMgr &SM,
// Okay, add the string we captured to the output vector and move on.
CheckStrings.push_back(CheckString(P,
PatternLoc,
IsCheckNext,
IsCheckLabel));
CheckTy));
std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
}
// Add an EOF pattern for any trailing CHECK-DAG/-NOTs.
if (!DagNotMatches.empty()) {
CheckStrings.push_back(CheckString(Pattern(true),
CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
SMLoc::getFromPointer(Buffer.data()),
false,
false));
Check::CheckEOF));
std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
}
@ -902,7 +913,7 @@ size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
}
bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
if (!IsCheckNext)
if (CheckTy != Check::CheckNext)
return false;
// Count the number of newlines between the previous match and this one.
@ -943,7 +954,7 @@ bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
for (unsigned ChunkNo = 0, e = NotStrings.size();
ChunkNo != e; ++ChunkNo) {
const Pattern *Pat = NotStrings[ChunkNo];
assert(Pat->getMatchNot() && "Expect CHECK-NOT!");
assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
size_t MatchLen = 0;
size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
@ -974,15 +985,16 @@ size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
ChunkNo != e; ++ChunkNo) {
const Pattern &Pat = DagNotStrings[ChunkNo];
assert((Pat.getMatchDag() ^ Pat.getMatchNot()) &&
assert((Pat.getCheckTy() == Check::CheckDAG ||
Pat.getCheckTy() == Check::CheckNot) &&
"Invalid CHECK-DAG or CHECK-NOT!");
if (Pat.getMatchNot()) {
if (Pat.getCheckTy() == Check::CheckNot) {
NotStrings.push_back(&Pat);
continue;
}
assert(Pat.getMatchDag() && "Expect CHECK-DAG!");
assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
size_t MatchLen = 0, MatchPos;
@ -1100,7 +1112,7 @@ int main(int argc, char **argv) {
CheckRegion = Buffer;
} else {
const CheckString &CheckLabelStr = CheckStrings[j];
if (!CheckLabelStr.IsCheckLabel) {
if (CheckLabelStr.CheckTy != Check::CheckLabel) {
++j;
continue;
}