llvm.org GIT mirror llvm / ee4f5ea
Allow multiple check prefixes in FileCheck. This is useful if you want to run multiple variations of a single test, and the majority of check lines should be the same. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194343 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 5 years ago
15 changed file(s) with 360 addition(s) and 94 deletion(s). Raw diff Collapse all Expand all
2929
3030 .. option:: --check-prefix prefix
3131
32 FileCheck searches the contents of ``match-filename`` for patterns to match.
33 By default, these patterns are prefixed with "``CHECK:``". If you'd like to
34 use a different prefix (e.g. because the same input file is checking multiple
35 different tool or options), the :option:`--check-prefix` argument allows you
36 to specify a specific prefix to match.
32 FileCheck searches the contents of ``match-filename`` for patterns to
33 match. By default, these patterns are prefixed with "``CHECK:``".
34 If you'd like to use a different prefix (e.g. because the same input
35 file is checking multiple different tool or options), the
36 :option:`--check-prefix` argument allows you to specify one or more
37 prefixes to match. Multiple prefixes are useful for tests which might
38 change for different run options, but most lines remain the same.
3739
3840 .. option:: --input-file filename
3941
0 ; RUN: FileCheck -check-prefix=A -check-prefix=B -input-file %s %s
1
2 this is the string to be matched
3
4 ; B-DAG: this is the string to be {{matched}}
0 ; RUN: FileCheck -check-prefix=B -check-prefix=A -input-file %s %s
1
2 this is the string to be matched
3
4 ; B-DAG: this is the string to be {{matched}}
0 ; RUN: FileCheck -check-prefix=A -input-file %s %s
1
2 this should be matched
3
4 ; B-DAG: foo
5
6 ; A-DAG: {{this}} should be matched
0 ; RUN: FileCheck -check-prefix=A -check-prefix=B -input-file %s %s
1
2 add r10, r1, r2
3 add r11, r3, r4
4 mul r5, r10, r11
5
6 mul r11, r3, r4
7 mul r10, r1, r2
8 add r5, r10, r11
9
10 add r11, r3, r4
11 add r10, r1, r2
12 mul r5, r10, r11
13
14 ; B-DAG: add [[REG1:r[0-9]+]], r1, r2
15 ; B-DAG: add [[REG2:r[0-9]+]], r3, r4
16 ; B: mul r5, [[REG1]], [[REG2]]
17
18 ; A-DAG: mul [[REG1:r[0-9]+]], r1, r2
19 ; A-DAG: mul [[REG2:r[0-9]+]], r3, r4
20 ; A: add r5, [[REG1]], [[REG2]]
21
22 ; B-DAG: add [[REG1:r[0-9]+]], r1, r2
23 ; B-DAG: add [[REG2:r[0-9]+]], r3, r4
24 ; B-NOT: xor
25 ; B-DAG: mul r5, [[REG1]], [[REG2]]
26
0 ; RUN: not FileCheck -check-prefix=A -check-prefix=AA -input-file %s %s
1
2 this is the string to be matched
3 this should also be matched
4
5 ; BAA-DAG: this is the string to be {{matched}}
6 ; BAA-DAG: this should also be {{matched}}
0 // RUN: FileCheck -check-prefix=ONE -check-prefix=TWO -input-file %s %s
1
2 foo
3 bar
4 ; ONE-LABEL: {{f}}oo
5 ; TWO-NEXT: {{b}}ar
0 // RUN: FileCheck -check-prefix=B -check-prefix=BOTH -input-file %s %s
1 // RUN: FileCheck -check-prefix=A -check-prefix=BOTH -input-file %s %s
2
3 ; A: {{a}}aaaaa
4 ; B: {{b}}bbbb
5 ; BOTH: {{q}}qqqqq
6 aaaaaa
7 bbbbb
8 qqqqqq
9 ccccc
0 ; RUN: FileCheck -check-prefix=FOO -check-prefix=FOOBAR -check-prefix=BARFOO -input-file %s %s
1 ; RUN: FileCheck -check-prefix=FOOBAR -check-prefix=FOO -check-prefix=BARFOO -input-file %s %s
2 ; RUN: FileCheck -check-prefix=FOOBAR -check-prefix=BARFOO -check-prefix=FOO -input-file %s %s
3
4 this is the match
5 this is another
6
7 FOO
8 FOOBAR
9 FOOBAR: this is the {{match}}
10 BARFOO: this is {{another}}
0 // RUN: FileCheck -check-prefix=AAAOVERLAP -check-prefix=OVERLAP -input-file %s %s
1
2 foo
3 bar
4 buzz
5
6 OVERLAP: foo
7 AAAOVERLAP: bar
8 OVERLAP: buzz
0 RUN: FileCheck -check-prefix=RUN -input-file %s %s
1 // Prefix is at the first character in the file. The run line then matches itself.
0 // RUN: FileCheck -check-prefix=ANOTHER-PREFIX -input-file %s %s
1 // RUN: not FileCheck -check-prefix=PREFIX1 -check-prefix=PREFIX2 -input-file %s %s 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK-NONEXISTENT-PREFIX -check-prefix=ALSO-NONEXISTENT %s
2
3 foobar
4 ; ANOTHER-PREFIX: foobar
5
6 ; We use regex to match the colon so that FileCheck won't think it is a check
7 ; prefix.
8 ; CHECK-NONEXISTENT-PREFIX: error: no check strings found with prefixes 'PREFIX1{{:}}', 'PREFIX2{{:}}'
0 // RUN: not FileCheck -check-prefix=SOMEPREFIX -input-file %s %s
1 // RUN: FileCheck -check-prefix=ANOTHER -input-file %s %s
2
3 asdf
4 ; SOMEPREFIX: {{t}}his_is_not_asdf
5 ; ANOTHER: {{a}}sdf
6
0 // RUN: not FileCheck -check-prefix=A! -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s
11 // RUN: FileCheck -check-prefix=A1a-B_c -input-file %s %s
2
2 // RUN: not FileCheck -check-prefix=REPEAT -check-prefix=REPEAT -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s
3 // RUN: not FileCheck -check-prefix=VALID -check-prefix=A! -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s
34 foobar
45 ; A1a-B_c: foobar
56
6 ; BAD_PREFIX: Supplied check-prefix is invalid! Prefixes must start with a letter and contain only alphanumeric characters, hyphens and underscores
7 ; BAD_PREFIX: Supplied check-prefix is invalid! Prefixes must be
8 unique and start with a letter and contain only alphanumeric characters, hyphens and underscores
1919 #include "llvm/ADT/SmallString.h"
2020 #include "llvm/ADT/StringExtras.h"
2121 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringSet.h"
2223 #include "llvm/Support/CommandLine.h"
2324 #include "llvm/Support/MemoryBuffer.h"
2425 #include "llvm/Support/PrettyStackTrace.h"
4142 InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
4243 cl::init("-"), cl::value_desc("filename"));
4344
44 static cl::opt
45 CheckPrefix("check-prefix", cl::init("CHECK"),
46 cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
45 static cl::list
46 CheckPrefixes("check-prefix",
47 cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
4748
4849 static cl::opt
4950 NoCanonicalizeWhiteSpace("strict-whitespace",
5051 cl::desc("Do not treat all horizontal whitespace as equivalent"));
52
53 typedef cl::list::const_iterator prefix_iterator;
5154
5255 //===----------------------------------------------------------------------===//
5356 // Pattern Handling Code.
102105 /// getLoc - Return the location in source code.
103106 SMLoc getLoc() const { return PatternLoc; }
104107
105 /// ParsePattern - Parse the given string into the Pattern. SM provides the
106 /// SourceMgr used for error reports, and LineNumber is the line number in
107 /// the input file from which the pattern string was read.
108 /// Returns true in case of an error, false otherwise.
109 bool ParsePattern(StringRef PatternStr, SourceMgr &SM, unsigned LineNumber);
108 /// ParsePattern - Parse the given string into the Pattern. Prefix provides
109 /// which prefix is being matched, SM provides the SourceMgr used for error
110 /// reports, and LineNumber is the line number in the input file from which
111 /// the pattern string was read. Returns true in case of an error, false
112 /// otherwise.
113 bool ParsePattern(StringRef PatternStr,
114 StringRef Prefix,
115 SourceMgr &SM,
116 unsigned LineNumber);
110117
111118 /// Match - Match the pattern string against the input buffer Buffer. This
112119 /// returns the position that is matched or npos if there is no match. If
151158 };
152159
153160
154 bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM,
161 bool Pattern::ParsePattern(StringRef PatternStr,
162 StringRef Prefix,
163 SourceMgr &SM,
155164 unsigned LineNumber) {
156165 this->LineNumber = LineNumber;
157166 PatternLoc = SMLoc::getFromPointer(PatternStr.data());
165174 if (PatternStr.empty()) {
166175 SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
167176 "found empty check string with prefix '" +
168 CheckPrefix+":'");
177 Prefix + ":'");
169178 return true;
170179 }
171180
593602 /// Pat - The pattern to match.
594603 Pattern Pat;
595604
605 /// Prefix - Which prefix name this check matched.
606 StringRef Prefix;
607
596608 /// Loc - The location in the match file that the check string was specified.
597609 SMLoc Loc;
598610
605617 /// file).
606618 std::vector DagNotStrings;
607619
608 CheckString(const Pattern &P, SMLoc L, Check::CheckType Ty)
609 : Pat(P), Loc(L), CheckTy(Ty) {}
620
621 CheckString(const Pattern &P,
622 StringRef S,
623 SMLoc L,
624 Check::CheckType Ty)
625 : Pat(P), Prefix(S), Loc(L), CheckTy(Ty) {}
610626
611627 /// Check - Match check string and its "not strings" and/or "dag strings".
612628 size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
669685 return (isalnum(c) || c == '-' || c == '_');
670686 }
671687
672 static Check::CheckType FindCheckType(StringRef &Buffer, StringRef Prefix) {
688 // Get the size of the prefix extension.
689 static size_t CheckTypeSize(Check::CheckType Ty) {
690 switch (Ty) {
691 case Check::CheckNone:
692 return 0;
693
694 case Check::CheckPlain:
695 return sizeof(":") - 1;
696
697 case Check::CheckNext:
698 return sizeof("-NEXT:") - 1;
699
700 case Check::CheckNot:
701 return sizeof("-NOT:") - 1;
702
703 case Check::CheckDAG:
704 return sizeof("-DAG:") - 1;
705
706 case Check::CheckLabel:
707 return sizeof("-LABEL:") - 1;
708
709 case Check::CheckEOF:
710 llvm_unreachable("Should not be using EOF size");
711 }
712
713 llvm_unreachable("Bad check type");
714 }
715
716 static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
673717 char NextChar = Buffer[Prefix.size()];
674718
675719 // Verify that the : is present after the prefix.
676 if (NextChar == ':') {
677 Buffer = Buffer.substr(Prefix.size() + 1);
720 if (NextChar == ':')
678721 return Check::CheckPlain;
679 }
680
681 if (NextChar != '-') {
682 Buffer = Buffer.drop_front(1);
722
723 if (NextChar != '-')
683724 return Check::CheckNone;
684 }
685725
686726 StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
687 if (Rest.startswith("NEXT:")) {
688 Buffer = Rest.drop_front(sizeof("NEXT:") - 1);
727 if (Rest.startswith("NEXT:"))
689728 return Check::CheckNext;
690 }
691
692 if (Rest.startswith("NOT:")) {
693 Buffer = Rest.drop_front(sizeof("NOT:") - 1);
729
730 if (Rest.startswith("NOT:"))
694731 return Check::CheckNot;
695 }
696
697 if (Rest.startswith("DAG:")) {
698 Buffer = Rest.drop_front(sizeof("DAG:") - 1);
732
733 if (Rest.startswith("DAG:"))
699734 return Check::CheckDAG;
700 }
701
702 if (Rest.startswith("LABEL:")) {
703 Buffer = Rest.drop_front(sizeof("LABEL:") - 1);
735
736 if (Rest.startswith("LABEL:"))
704737 return Check::CheckLabel;
705 }
706
707 Buffer = Buffer.drop_front(1);
738
708739 return Check::CheckNone;
740 }
741
742 // From the given position, find the next character after the word.
743 static size_t SkipWord(StringRef Str, size_t Loc) {
744 while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
745 ++Loc;
746 return Loc;
747 }
748
749 // Try to find the first match in buffer for any prefix. If a valid match is
750 // found, return that prefix and set its type and location. If there are almost
751 // matches (e.g. the actual prefix string is found, but is not an actual check
752 // string), but no valid match, return an empty string and set the position to
753 // resume searching from. If no partial matches are found, return an empty
754 // string and the location will be StringRef::npos. If one prefix is a substring
755 // of another, the maximal match should be found. e.g. if "A" and "AA" are
756 // prefixes then AA-CHECK: should match the second one.
757 static StringRef FindFirstCandidateMatch(StringRef &Buffer,
758 Check::CheckType &CheckTy,
759 size_t &CheckLoc) {
760 StringRef FirstPrefix;
761 size_t FirstLoc = StringRef::npos;
762 size_t SearchLoc = StringRef::npos;
763 Check::CheckType FirstTy = Check::CheckNone;
764
765 CheckTy = Check::CheckNone;
766 CheckLoc = StringRef::npos;
767
768 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
769 I != E; ++I) {
770 StringRef Prefix(*I);
771 size_t PrefixLoc = Buffer.find(Prefix);
772
773 if (PrefixLoc == StringRef::npos)
774 continue;
775
776 // Track where we are searching for invalid prefixes that look almost right.
777 // We need to only advance to the first partial match on the next attempt
778 // since a partial match could be a substring of a later, valid prefix.
779 // Need to skip to the end of the word, otherwise we could end up
780 // matching a prefix in a substring later.
781 if (PrefixLoc < SearchLoc)
782 SearchLoc = SkipWord(Buffer, PrefixLoc);
783
784 // We only want to find the first match to avoid skipping some.
785 if (PrefixLoc > FirstLoc)
786 continue;
787
788 StringRef Rest = Buffer.drop_front(PrefixLoc);
789 // Make sure we have actually found the prefix, and not a word containing
790 // it. This should also prevent matching the wrong prefix when one is a
791 // substring of another.
792 if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
793 continue;
794
795 Check::CheckType Ty = FindCheckType(Rest, Prefix);
796 if (Ty == Check::CheckNone)
797 continue;
798
799 FirstLoc = PrefixLoc;
800 FirstTy = Ty;
801 FirstPrefix = Prefix;
802 }
803
804 if (FirstPrefix.empty()) {
805 CheckLoc = SearchLoc;
806 } else {
807 CheckTy = FirstTy;
808 CheckLoc = FirstLoc;
809 }
810
811 return FirstPrefix;
812 }
813
814 static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
815 unsigned &LineNumber,
816 Check::CheckType &CheckTy,
817 size_t &CheckLoc) {
818 while (!Buffer.empty()) {
819 StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
820 // If we found a real match, we are done.
821 if (!Prefix.empty()) {
822 LineNumber += Buffer.substr(0, CheckLoc).count('\n');
823 return Prefix;
824 }
825
826 // We didn't find any almost matches either, we are also done.
827 if (CheckLoc == StringRef::npos)
828 return StringRef();
829
830 LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
831
832 // Advance to the last possible match we found and try again.
833 Buffer = Buffer.drop_front(CheckLoc + 1);
834 }
835
836 return StringRef();
709837 }
710838
711839 /// ReadCheckFile - Read the check file, which specifies the sequence of
737865 unsigned LineNumber = 1;
738866
739867 while (1) {
740 // See if Prefix occurs in the memory buffer.
741 size_t PrefixLoc = Buffer.find(CheckPrefix);
742 // If we didn't find a match, we're done.
743 if (PrefixLoc == StringRef::npos)
868 Check::CheckType CheckTy;
869 size_t PrefixLoc;
870
871 // See if a prefix occurs in the memory buffer.
872 StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
873 LineNumber,
874 CheckTy,
875 PrefixLoc);
876 if (UsedPrefix.empty())
744877 break;
745878
746 LineNumber += Buffer.substr(0, PrefixLoc).count('\n');
747
748 // Keep the charcter before our prefix so we can validate that we have
749 // found our prefix, and account for cases when PrefixLoc is 0.
750 Buffer = Buffer.substr(std::min(PrefixLoc-1, PrefixLoc));
751
752 const char *CheckPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
753
754 // Make sure we have actually found our prefix, and not a word containing
755 // our prefix.
756 if (PrefixLoc != 0 && IsPartOfWord(Buffer[0])) {
757 Buffer = Buffer.substr(CheckPrefix.size());
758 continue;
759 }
760
761 // When we find a check prefix, keep track of what kind of type of CHECK we
762 // have.
763 Check::CheckType CheckTy = FindCheckType(Buffer, CheckPrefix);
764 if (CheckTy == Check::CheckNone)
765 continue;
879 Buffer = Buffer.drop_front(PrefixLoc);
880
881 // Location to use for error messages.
882 const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
883
884 // PrefixLoc is to the start of the prefix. Skip to the end.
885 Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
766886
767887 // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
768888 // leading and trailing whitespace.
776896
777897 // Parse the pattern.
778898 Pattern P(CheckTy);
779 if (P.ParsePattern(Buffer.substr(0, EOL), SM, LineNumber))
899 if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
780900 return true;
781901
782902 // Verify that CHECK-LABEL lines do not define or use variables
783903 if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
784 SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
904 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
785905 SourceMgr::DK_Error,
786 "found '"+CheckPrefix+"-LABEL:' with variable definition"
787 " or use");
906 "found '" + UsedPrefix + "-LABEL:'"
907 " with variable definition or use");
788908 return true;
789909 }
790910
792912
793913 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
794914 if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
795 SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
915 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
796916 SourceMgr::DK_Error,
797 "found '"+CheckPrefix+"-NEXT:' without previous '"+
798 CheckPrefix+ ": line");
917 "found '" + UsedPrefix + "-NEXT:' without previous '"
918 + UsedPrefix + ": line");
799919 return true;
800920 }
801921
807927
808928 // Okay, add the string we captured to the output vector and move on.
809929 CheckStrings.push_back(CheckString(P,
930 UsedPrefix,
810931 PatternLoc,
811932 CheckTy));
812933 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
813934 }
814935
815 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs.
936 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
937 // prefix as a filler for the error message.
816938 if (!DagNotMatches.empty()) {
817939 CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
940 CheckPrefixes[0],
818941 SMLoc::getFromPointer(Buffer.data()),
819942 Check::CheckEOF));
820943 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
821944 }
822945
823946 if (CheckStrings.empty()) {
824 errs() << "error: no check strings found with prefix '" << CheckPrefix
825 << ":'\n";
947 errs() << "error: no check strings found with prefix"
948 << (CheckPrefixes.size() > 1 ? "es " : " ");
949 for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) {
950 StringRef Prefix(CheckPrefixes[I]);
951 errs() << '\'' << Prefix << ":'";
952 if (I != N - 1)
953 errs() << ", ";
954 }
955
956 errs() << '\n';
826957 return true;
827958 }
828959
9321063 unsigned NumNewLines = CountNumNewlinesBetween(Buffer);
9331064
9341065 if (NumNewLines == 0) {
935 SM.PrintMessage(Loc, SourceMgr::DK_Error, CheckPrefix+
1066 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
9361067 "-NEXT: is on the same line as previous match");
9371068 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
9381069 SourceMgr::DK_Note, "'next' match was here");
9421073 }
9431074
9441075 if (NumNewLines != 1) {
945 SM.PrintMessage(Loc, SourceMgr::DK_Error, CheckPrefix+
1076 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
9461077 "-NEXT: is not on the line after the previous match");
9471078 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
9481079 SourceMgr::DK_Note, "'next' match was here");
9691100
9701101 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
9711102 SourceMgr::DK_Error,
972 CheckPrefix+"-NOT: string occurred!");
1103 Prefix + "-NOT: string occurred!");
9731104 SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
974 CheckPrefix+"-NOT: pattern specified here");
1105 Prefix + "-NOT: pattern specified here");
9751106 return true;
9761107 }
9771108
10211152 // Reordered?
10221153 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
10231154 SourceMgr::DK_Error,
1024 CheckPrefix+"-DAG: found a match of CHECK-DAG"
1155 Prefix + "-DAG: found a match of CHECK-DAG"
10251156 " reordering across a CHECK-NOT");
10261157 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
10271158 SourceMgr::DK_Note,
1028 CheckPrefix+"-DAG: the farthest match of CHECK-DAG"
1159 Prefix + "-DAG: the farthest match of CHECK-DAG"
10291160 " is found here");
10301161 SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
1031 CheckPrefix+"-NOT: the crossed pattern specified"
1162 Prefix + "-NOT: the crossed pattern specified"
10321163 " here");
10331164 SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
1034 CheckPrefix+"-DAG: the reordered pattern specified"
1165 Prefix + "-DAG: the reordered pattern specified"
10351166 " here");
10361167 return StringRef::npos;
10371168 }
10551186 return LastPos;
10561187 }
10571188
1058 bool ValidateCheckPrefix() {
1059 // The check prefix must contain only alphanumeric, hyphens and underscores.
1060 Regex prefixValidator("^[a-zA-Z0-9_-]*$");
1061 return prefixValidator.match(CheckPrefix);
1189 // A check prefix must contain only alphanumeric, hyphens and underscores.
1190 static bool ValidateCheckPrefix(StringRef CheckPrefix) {
1191 Regex Validator("^[a-zA-Z0-9_-]*$");
1192 return Validator.match(CheckPrefix);
1193 }
1194
1195 static bool ValidateCheckPrefixes() {
1196 StringSet<> PrefixSet;
1197
1198 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
1199 I != E; ++I) {
1200 StringRef Prefix(*I);
1201
1202 if (!PrefixSet.insert(Prefix))
1203 return false;
1204
1205 if (!ValidateCheckPrefix(Prefix))
1206 return false;
1207 }
1208
1209 return true;
1210 }
1211
1212 // I don't think there's a way to specify an initial value for cl::list,
1213 // so if nothing was specified, add the default
1214 static void AddCheckPrefixIfNeeded() {
1215 if (CheckPrefixes.empty())
1216 CheckPrefixes.push_back("CHECK");
10621217 }
10631218
10641219 int main(int argc, char **argv) {
10661221 PrettyStackTraceProgram X(argc, argv);
10671222 cl::ParseCommandLineOptions(argc, argv);
10681223
1069 if (!ValidateCheckPrefix()) {
1070 errs() << "Supplied check-prefix is invalid! Prefixes must start with a "
1071 "letter and contain only alphanumeric characters, hyphens and "
1072 "underscores\n";
1224 if (!ValidateCheckPrefixes()) {
1225 errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
1226 "start with a letter and contain only alphanumeric characters, "
1227 "hyphens and underscores\n";
10731228 return 2;
10741229 }
1230
1231 AddCheckPrefixIfNeeded();
10751232
10761233 SourceMgr SM;
10771234