llvm.org GIT mirror llvm / 4f67afc
FileCheck refactor: use enum instead of bunch of bools git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190893 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 6 years ago
1 changed file(s) with 89 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
5252 // Pattern Handling Code.
5353 //===----------------------------------------------------------------------===//
5454
55 namespace Check {
56 enum CheckType {
57 CheckNone = 0,
58 CheckPlain,
59 CheckNext,
60 CheckNot,
61 CheckDAG,
62 CheckLabel,
63
64 /// MatchEOF - When set, this pattern only matches the end of file. This is
65 /// used for trailing CHECK-NOTs.
66 CheckEOF
67 };
68 }
69
5570 class Pattern {
5671 SMLoc PatternLoc;
5772
58 /// MatchEOF - When set, this pattern only matches the end of file. This is
59 /// used for trailing CHECK-NOTs.
60 bool MatchEOF;
61
62 /// MatchNot
63 bool MatchNot;
64
65 /// MatchDag
66 bool MatchDag;
73 Check::CheckType CheckTy;
6774
6875 /// FixedStr - If non-empty, this pattern is a fixed string match with the
6976 /// specified fixed string.
8895
8996 public:
9097
91 Pattern(bool matchEOF = false)
92 : MatchEOF(matchEOF), MatchNot(false), MatchDag(false) { }
98 Pattern(Check::CheckType Ty)
99 : CheckTy(Ty) { }
93100
94101 /// getLoc - Return the location in source code.
95102 SMLoc getLoc() const { return PatternLoc; }
117124 bool hasVariable() const { return !(VariableUses.empty() &&
118125 VariableDefs.empty()); }
119126
120 void setMatchNot(bool Not) { MatchNot = Not; }
121 bool getMatchNot() const { return MatchNot; }
122
123 void setMatchDag(bool Dag) { MatchDag = Dag; }
124 bool getMatchDag() const { return MatchDag; }
127 Check::CheckType getCheckTy() const { return CheckTy; }
125128
126129 private:
127130 static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
380383 size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
381384 StringMap &VariableTable) const {
382385 // If this is the EOF pattern, match it immediately.
383 if (MatchEOF) {
386 if (CheckTy == Check::CheckEOF) {
384387 MatchLen = 0;
385388 return Buffer.size();
386389 }
592595 /// Loc - The location in the match file that the check string was specified.
593596 SMLoc Loc;
594597
595 /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
596 /// to a CHECK: directive.
597 bool IsCheckNext;
598
599 /// IsCheckLabel - This is true if this is a CHECK-LABEL: directive (as
600 /// opposed to a CHECK: directive.
601 bool IsCheckLabel;
598 /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
599 /// as opposed to a CHECK: directive.
600 Check::CheckType CheckTy;
602601
603602 /// DagNotStrings - These are all of the strings that are disallowed from
604603 /// occurring between this match string and the previous one (or start of
605604 /// file).
606605 std::vector DagNotStrings;
607606
608 CheckString(const Pattern &P, SMLoc L, bool isCheckNext, bool isCheckLabel)
609 : Pat(P), Loc(L), IsCheckNext(isCheckNext), IsCheckLabel(isCheckLabel) {}
607 CheckString(const Pattern &P, SMLoc L, Check::CheckType Ty)
608 : Pat(P), Loc(L), CheckTy(Ty) {}
610609
611610 /// Check - Match check string and its "not strings" and/or "dag strings".
612611 size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabel,
665664 return MB2;
666665 }
667666
667 static bool IsPartOfWord(char c) {
668 return (isalnum(c) || c == '-' || c == '_');
669 }
670
671 static Check::CheckType FindCheckType(StringRef &Buffer, StringRef Prefix) {
672 char NextChar = Buffer[CheckPrefix.size()];
673
674 // Verify that the : is present after the prefix.
675 if (NextChar == ':') {
676 Buffer = Buffer.substr(CheckPrefix.size() + 1);
677 return Check::CheckPlain;
678 }
679
680 if (NextChar != '-') {
681 Buffer = Buffer.drop_front(1);
682 return Check::CheckNone;
683 }
684
685 StringRef Rest = Buffer.drop_front(CheckPrefix.size() + 1);
686 if (Rest.startswith("NEXT:")) {
687 Buffer = Rest.drop_front(sizeof("NEXT:") - 1);
688 return Check::CheckNext;
689 }
690
691 if (Rest.startswith("NOT:")) {
692 Buffer = Rest.drop_front(sizeof("NOT:") - 1);
693 return Check::CheckNot;
694 }
695
696 if (Rest.startswith("DAG:")) {
697 Buffer = Rest.drop_front(sizeof("DAG:") - 1);
698 return Check::CheckDAG;
699 }
700
701 if (Rest.startswith("LABEL:")) {
702 Buffer = Rest.drop_front(sizeof("LABEL:") - 1);
703 return Check::CheckLabel;
704 }
705
706 Buffer = Buffer.drop_front(1);
707 return Check::CheckNone;
708 }
668709
669710 /// ReadCheckFile - Read the check file, which specifies the sequence of
670711 /// expected strings. The strings are added to the CheckStrings vector.
709750
710751 const char *CheckPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
711752
712 // When we find a check prefix, keep track of whether we find CHECK: or
713 // CHECK-NEXT:
714 bool IsCheckNext = false, IsCheckNot = false, IsCheckDag = false,
715 IsCheckLabel = false;
716
717753 // Make sure we have actually found our prefix, and not a word containing
718754 // our prefix.
719 if (PrefixLoc != 0 && (isalnum(Buffer[0]) ||
720 Buffer[0] == '-' ||
721 Buffer[0] == '_')) {
755 if (PrefixLoc != 0 && IsPartOfWord(Buffer[0])) {
722756 Buffer = Buffer.substr(CheckPrefix.size());
723757 continue;
724758 }
725759
726 // Verify that the : is present after the prefix.
727 if (Buffer[CheckPrefix.size()] == ':') {
728 Buffer = Buffer.substr(CheckPrefix.size()+1);
729 } else if (Buffer.size() > CheckPrefix.size()+6 &&
730 memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
731 Buffer = Buffer.substr(CheckPrefix.size()+6);
732 IsCheckNext = true;
733 } else if (Buffer.size() > CheckPrefix.size()+5 &&
734 memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
735 Buffer = Buffer.substr(CheckPrefix.size()+5);
736 IsCheckNot = true;
737 } else if (Buffer.size() > CheckPrefix.size()+5 &&
738 memcmp(Buffer.data()+CheckPrefix.size(), "-DAG:", 5) == 0) {
739 Buffer = Buffer.substr(CheckPrefix.size()+5);
740 IsCheckDag = true;
741 } else if (Buffer.size() > CheckPrefix.size()+7 &&
742 memcmp(Buffer.data()+CheckPrefix.size(), "-LABEL:", 7) == 0) {
743 Buffer = Buffer.substr(CheckPrefix.size()+7);
744 IsCheckLabel = true;
745 } else {
746 Buffer = Buffer.substr(1);
760 // When we find a check prefix, keep track of what kind of type of CHECK we
761 // have.
762 Check::CheckType CheckTy = FindCheckType(Buffer, CheckPrefix);
763 if (CheckTy == Check::CheckNone)
747764 continue;
748 }
749
750 // Okay, we found the prefix, yay. Remember the rest of the line, but
751 // ignore leading and trailing whitespace.
765
766 // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
767 // leading and trailing whitespace.
752768 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
753769
754770 // Scan ahead to the end of line.
758774 SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
759775
760776 // Parse the pattern.
761 Pattern P;
777 Pattern P(CheckTy);
762778 if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
763779 return true;
764780
765781 // Verify that CHECK-LABEL lines do not define or use variables
766 if (IsCheckLabel && P.hasVariable()) {
782 if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
767783 SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
768784 SourceMgr::DK_Error,
769785 "found '"+CheckPrefix+"-LABEL:' with variable definition"
771787 return true;
772788 }
773789
774 P.setMatchNot(IsCheckNot);
775 P.setMatchDag(IsCheckDag);
776
777790 Buffer = Buffer.substr(EOL);
778791
779792 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
780 if (IsCheckNext && CheckStrings.empty()) {
793 if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
781794 SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
782795 SourceMgr::DK_Error,
783796 "found '"+CheckPrefix+"-NEXT:' without previous '"+
786799 }
787800
788801 // Handle CHECK-DAG/-NOT.
789 if (IsCheckDag || IsCheckNot) {
802 if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
790803 DagNotMatches.push_back(P);
791804 continue;
792805 }
794807 // Okay, add the string we captured to the output vector and move on.
795808 CheckStrings.push_back(CheckString(P,
796809 PatternLoc,
797 IsCheckNext,
798 IsCheckLabel));
810 CheckTy));
799811 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
800812 }
801813
802814 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs.
803815 if (!DagNotMatches.empty()) {
804 CheckStrings.push_back(CheckString(Pattern(true),
816 CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
805817 SMLoc::getFromPointer(Buffer.data()),
806 false,
807 false));
818 Check::CheckEOF));
808819 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
809820 }
810821
901912 }
902913
903914 bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
904 if (!IsCheckNext)
915 if (CheckTy != Check::CheckNext)
905916 return false;
906917
907918 // Count the number of newlines between the previous match and this one.
942953 for (unsigned ChunkNo = 0, e = NotStrings.size();
943954 ChunkNo != e; ++ChunkNo) {
944955 const Pattern *Pat = NotStrings[ChunkNo];
945 assert(Pat->getMatchNot() && "Expect CHECK-NOT!");
956 assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
946957
947958 size_t MatchLen = 0;
948959 size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
973984 ChunkNo != e; ++ChunkNo) {
974985 const Pattern &Pat = DagNotStrings[ChunkNo];
975986
976 assert((Pat.getMatchDag() ^ Pat.getMatchNot()) &&
987 assert((Pat.getCheckTy() == Check::CheckDAG ||
988 Pat.getCheckTy() == Check::CheckNot) &&
977989 "Invalid CHECK-DAG or CHECK-NOT!");
978990
979 if (Pat.getMatchNot()) {
991 if (Pat.getCheckTy() == Check::CheckNot) {
980992 NotStrings.push_back(&Pat);
981993 continue;
982994 }
983995
984 assert(Pat.getMatchDag() && "Expect CHECK-DAG!");
996 assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
985997
986998 size_t MatchLen = 0, MatchPos;
987999
10991111 CheckRegion = Buffer;
11001112 } else {
11011113 const CheckString &CheckLabelStr = CheckStrings[j];
1102 if (!CheckLabelStr.IsCheckLabel) {
1114 if (CheckLabelStr.CheckTy != Check::CheckLabel) {
11031115 ++j;
11041116 continue;
11051117 }