diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/tools/llvm-objcopy/CommonConfig.h index 49a77e1815a0d..131ce5c591146 100644 --- a/llvm/tools/llvm-objcopy/CommonConfig.h +++ b/llvm/tools/llvm-objcopy/CommonConfig.h @@ -10,6 +10,7 @@ #define LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -113,6 +114,11 @@ class NameOrPattern { llvm::function_ref ErrorCallback); bool isPositiveMatch() const { return IsPositiveMatch; } + Optional getName() const { + if (!R && !G) + return Name; + return None; + } bool operator==(StringRef S) const { return R ? R->match(S) : G ? G->match(S) : Name == S; } @@ -122,23 +128,32 @@ class NameOrPattern { // Matcher that checks symbol or section names against the command line flags // provided for that option. class NameMatcher { - std::vector PosMatchers; + DenseSet PosNames; + std::vector PosPatterns; std::vector NegMatchers; public: Error addMatcher(Expected Matcher) { if (!Matcher) return Matcher.takeError(); - if (Matcher->isPositiveMatch()) - PosMatchers.push_back(std::move(*Matcher)); - else + if (Matcher->isPositiveMatch()) { + if (Optional MaybeName = Matcher->getName()) + PosNames.insert(CachedHashStringRef(*MaybeName)); + else + PosPatterns.push_back(std::move(*Matcher)); + } else { NegMatchers.push_back(std::move(*Matcher)); + } return Error::success(); } bool matches(StringRef S) const { - return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S); + return (PosNames.contains(CachedHashStringRef(S)) || + is_contained(PosPatterns, S)) && + !is_contained(NegMatchers, S); + } + bool empty() const { + return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty(); } - bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); } }; enum class SymbolFlag {