2525
2626namespace llvm {
2727
28- Error SpecialCaseList::Matcher ::insert (StringRef Pattern, unsigned LineNumber ,
29- bool UseGlobs ) {
30- if (Pattern.empty ())
28+ Error SpecialCaseList::RegexMatcher ::insert (StringRef Pattern,
29+ unsigned LineNumber ) {
30+ if (Pattern.empty ()) {
3131 return createStringError (errc::invalid_argument,
32- Twine (" Supplied " ) +
33- (UseGlobs ? " glob" : " regex" ) + " was blank" );
34-
35- if (!UseGlobs) {
36- // Replace * with .*
37- auto Regexp = Pattern.str ();
38- for (size_t pos = 0 ; (pos = Regexp.find (' *' , pos)) != std::string::npos;
39- pos += strlen (" .*" )) {
40- Regexp.replace (pos, strlen (" *" ), " .*" );
41- }
32+ " Supplied regex was blank" );
33+ }
34+
35+ // Replace * with .*
36+ auto Regexp = Pattern.str ();
37+ for (size_t pos = 0 ; (pos = Regexp.find (' *' , pos)) != std::string::npos;
38+ pos += strlen (" .*" )) {
39+ Regexp.replace (pos, strlen (" *" ), " .*" );
40+ }
41+
42+ Regexp = (Twine (" ^(" ) + StringRef (Regexp) + " )$" ).str ();
43+
44+ // Check that the regexp is valid.
45+ Regex CheckRE (Regexp);
46+ std::string REError;
47+ if (!CheckRE.isValid (REError))
48+ return createStringError (errc::invalid_argument, REError);
4249
43- Regexp = (Twine (" ^(" ) + StringRef (Regexp) + " )$" ).str ();
50+ RegExes.emplace_back (
51+ std::make_pair (std::make_unique<Regex>(std::move (CheckRE)), LineNumber));
4452
45- // Check that the regexp is valid.
46- Regex CheckRE (Regexp);
47- std::string REError;
48- if (!CheckRE.isValid (REError))
49- return createStringError (errc::invalid_argument, REError);
53+ return Error::success ();
54+ }
5055
51- RegExes.emplace_back (std::make_pair (
52- std::make_unique<Regex>(std::move (CheckRE)), LineNumber));
56+ unsigned SpecialCaseList::RegexMatcher::match (StringRef Query) const {
57+ for (const auto &[Regex, LineNumber] : reverse (RegExes))
58+ if (Regex->match (Query))
59+ return LineNumber;
60+ return 0 ;
61+ }
5362
54- return Error::success ();
63+ Error SpecialCaseList::GlobMatcher::insert (StringRef Pattern,
64+ unsigned LineNumber) {
65+ if (Pattern.empty ()) {
66+ return createStringError (errc::invalid_argument, " Supplied glob was blank" );
5567 }
5668
57- auto Glob = std::make_unique<Matcher ::Glob>();
69+ auto Glob = std::make_unique<GlobMatcher ::Glob>();
5870 Glob->Name = Pattern.str ();
5971 Glob->LineNo = LineNumber;
6072 // We must be sure to use the string in `Glob` rather than the provided
@@ -66,16 +78,28 @@ Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber,
6678 return Error::success ();
6779}
6880
69- unsigned SpecialCaseList::Matcher ::match (StringRef Query) const {
81+ unsigned SpecialCaseList::GlobMatcher ::match (StringRef Query) const {
7082 for (const auto &Glob : reverse (Globs))
7183 if (Glob->Pattern .match (Query))
7284 return Glob->LineNo ;
73- for (const auto &[Regex, LineNumber] : reverse (RegExes))
74- if (Regex->match (Query))
75- return LineNumber;
7685 return 0 ;
7786}
7887
88+ SpecialCaseList::Matcher::Matcher (bool UseGlobs) {
89+ if (UseGlobs)
90+ M.emplace <GlobMatcher>();
91+ else
92+ M.emplace <RegexMatcher>();
93+ }
94+
95+ unsigned SpecialCaseList::Matcher::match (StringRef Query) const {
96+ return std::visit ([&](auto &V) { return V.match (Query); }, M);
97+ }
98+
99+ Error SpecialCaseList::Matcher::insert (StringRef Pattern, unsigned LineNumber) {
100+ return std::visit ([&](auto &V) { return V.insert (Pattern, LineNumber); }, M);
101+ }
102+
79103// TODO: Refactor this to return Expected<...>
80104std::unique_ptr<SpecialCaseList>
81105SpecialCaseList::create (const std::vector<std::string> &Paths,
@@ -132,10 +156,10 @@ bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
132156Expected<SpecialCaseList::Section *>
133157SpecialCaseList::addSection (StringRef SectionStr, unsigned FileNo,
134158 unsigned LineNo, bool UseGlobs) {
135- Sections.emplace_back (SectionStr, FileNo);
159+ Sections.emplace_back (SectionStr, FileNo, UseGlobs );
136160 auto &Section = Sections.back ();
137161
138- if (auto Err = Section.SectionMatcher -> insert (SectionStr, LineNo, UseGlobs )) {
162+ if (auto Err = Section.SectionMatcher . insert (SectionStr, LineNo)) {
139163 return createStringError (errc::invalid_argument,
140164 " malformed section at line " + Twine (LineNo) +
141165 " : '" + SectionStr +
@@ -148,7 +172,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
148172bool SpecialCaseList::parse (unsigned FileIdx, const MemoryBuffer *MB,
149173 std::string &Error) {
150174 Section *CurrentSection;
151- if (auto Err = addSection (" *" , FileIdx, 1 ).moveInto (CurrentSection)) {
175+ if (auto Err = addSection (" *" , FileIdx, 1 , true ).moveInto (CurrentSection)) {
152176 Error = toString (std::move (Err));
153177 return false ;
154178 }
@@ -194,8 +218,9 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
194218 }
195219
196220 auto [Pattern, Category] = Postfix.split (" =" );
197- auto &Entry = CurrentSection->Entries [Prefix][Category];
198- if (auto Err = Entry.insert (Pattern, LineNo, UseGlobs)) {
221+ auto [It, _] =
222+ CurrentSection->Entries [Prefix].try_emplace (Category, UseGlobs);
223+ if (auto Err = It->second .insert (Pattern, LineNo)) {
199224 Error =
200225 (Twine (" malformed " ) + (UseGlobs ? " glob" : " regex" ) + " in line " +
201226 Twine (LineNo) + " : '" + Pattern + " ': " + toString (std::move (Err)))
@@ -218,7 +243,7 @@ std::pair<unsigned, unsigned>
218243SpecialCaseList::inSectionBlame (StringRef Section, StringRef Prefix,
219244 StringRef Query, StringRef Category) const {
220245 for (const auto &S : reverse (Sections)) {
221- if (S.SectionMatcher -> match (Section)) {
246+ if (S.SectionMatcher . match (Section)) {
222247 unsigned Blame = inSectionBlame (S.Entries , Prefix, Query, Category);
223248 if (Blame)
224249 return {S.FileIdx , Blame};
0 commit comments