Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -19,7 +19,6 @@ #include "llvm/ADT/MapVector.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Regex.h" #include namespace lld { @@ -115,9 +114,9 @@ // It can optionally have negative match pattern for EXCLUDED_FILE command. // Also it may be surrounded with SORT() command, so contains sorting rules. struct SectionPattern { - SectionPattern(llvm::Regex &&Re1, llvm::Regex &&Re2) - : ExcludedFileRe(std::forward(Re1)), - SectionRe(std::forward(Re2)) {} + SectionPattern(StringMatcher &&Re1, StringMatcher &&Re2) + : ExcludedFileRe(std::forward(Re1)), + SectionRe(std::forward(Re2)) {} SectionPattern(SectionPattern &&Other) { std::swap(ExcludedFileRe, Other.ExcludedFileRe); @@ -126,18 +125,17 @@ std::swap(SortInner, Other.SortInner); } - llvm::Regex ExcludedFileRe; - llvm::Regex SectionRe; + StringMatcher ExcludedFileRe; + StringMatcher SectionRe; SortSectionPolicy SortOuter; SortSectionPolicy SortInner; }; struct InputSectionDescription : BaseCommand { InputSectionDescription(StringRef FilePattern) - : BaseCommand(InputSectionKind), - FileRe(compileGlobPatterns({FilePattern})) {} + : BaseCommand(InputSectionKind), FileRe(FilePattern) {} static bool classof(const BaseCommand *C); - llvm::Regex FileRe; + StringMatcher FileRe; // Input sections that matches at least one of SectionPatterns // will be associated with this InputSectionDescription. Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -936,7 +936,7 @@ std::vector readOutputSectionFiller(StringRef Tok); std::vector readOutputSectionPhdrs(); InputSectionDescription *readInputSectionDescription(StringRef Tok); - Regex readFilePatterns(); + StringMatcher readFilePatterns(); std::vector readInputSectionsList(); InputSectionDescription *readInputSectionRules(StringRef FilePattern); unsigned readPhdrType(); @@ -1207,11 +1207,11 @@ .Default(-1); } -Regex ScriptParser::readFilePatterns() { +StringMatcher ScriptParser::readFilePatterns() { std::vector V; while (!Error && !consume(")")) V.push_back(next()); - return compileGlobPatterns(V); + return StringMatcher(std::move(V)); } SortSectionPolicy ScriptParser::readSortKind() { @@ -1236,7 +1236,7 @@ std::vector ScriptParser::readInputSectionsList() { std::vector Ret; while (!Error && peek() != ")") { - Regex ExcludeFileRe; + StringMatcher ExcludeFileRe; if (consume("EXCLUDE_FILE")) { expect("("); ExcludeFileRe = readFilePatterns(); @@ -1247,7 +1247,7 @@ V.push_back(next()); if (!V.empty()) - Ret.push_back({std::move(ExcludeFileRe), compileGlobPatterns(V)}); + Ret.push_back({std::move(ExcludeFileRe), StringMatcher(std::move(V))}); else setError("section pattern is expected"); } Index: ELF/Strings.h =================================================================== --- ELF/Strings.h +++ ELF/Strings.h @@ -18,6 +18,7 @@ namespace lld { namespace elf { +bool globMatch(StringRef S, StringRef T); llvm::Regex compileGlobPatterns(ArrayRef V); int getPriority(StringRef S); bool hasWildcard(StringRef S); @@ -25,6 +26,22 @@ bool isValidCIdentifier(StringRef S); StringRef unquote(StringRef S); +class StringMatcher { +public: + StringMatcher() = default; + StringMatcher(StringRef P) : Patterns({P}) {} + StringMatcher(std::vector &&Pat) + : Patterns(std::forward>(Pat)) {} + + bool match(StringRef S) { + for (StringRef P : Patterns) + if (globMatch(P, S)) + return true; + return false; + } + std::vector Patterns; +}; + // Returns a demangled C++ symbol name. If Name is not a mangled // name or the system does not provide __cxa_demangle function, // it returns an unmodified string. Index: ELF/Strings.cpp =================================================================== --- ELF/Strings.cpp +++ ELF/Strings.cpp @@ -21,6 +21,30 @@ using namespace lld; using namespace lld::elf; +// Returns true if S matches T. S can contain glob meta-characters. +// The asterisk ('*') matches zero or more characters, and the question +// mark ('?') matches one character. +bool elf::globMatch(StringRef S, StringRef T) { + for (;;) { + if (S.empty()) + return T.empty(); + if (S[0] == '*') { + S = S.substr(1); + if (S.empty()) + // Fast path. If a pattern is '*', it matches anything. + return true; + for (size_t I = 0, E = T.size(); I < E; ++I) + if (globMatch(S, T.substr(I))) + return true; + return false; + } + if (T.empty() || (S[0] != T[0] && S[0] != '?')) + return false; + S = S.substr(1); + T = T.substr(1); + } +} + // If an input string is in the form of "foo.N" where N is a number, // return N. Otherwise, returns 65536, which is one greater than the // lowest priority.