From ac75baaad844e932a6d83e966ff7450661fae8a1 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 22 Mar 2015 15:56:12 +0000 Subject: [PATCH] [multilib] Turn virtual functor into functin_ref And update code to use lambdas where possible, plus random cleanup. NFCI. llvm-svn: 232916 --- clang/include/clang/Driver/Multilib.h | 22 +++--- clang/lib/Driver/Multilib.cpp | 123 ++++++++++++---------------------- clang/lib/Driver/ToolChains.cpp | 11 +-- 3 files changed, 57 insertions(+), 99 deletions(-) diff --git a/clang/include/clang/Driver/Multilib.h b/clang/include/clang/Driver/Multilib.h index dcf609a..20bb80d 100644 --- a/clang/include/clang/Driver/Multilib.h +++ b/clang/include/clang/Driver/Multilib.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_DRIVER_MULTILIB_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" #include @@ -102,11 +103,7 @@ public: StringRef InstallDir, StringRef Triple, const Multilib &M)> IncludeDirsFunc; - struct FilterCallback { - virtual ~FilterCallback() {}; - /// \return true iff the filter should remove the Multilib from the set - virtual bool operator()(const Multilib &M) const = 0; - }; + typedef llvm::function_ref FilterCallback; private: multilib_list Multilibs; @@ -127,12 +124,12 @@ public: MultilibSet &Either(const Multilib &M1, const Multilib &M2, const Multilib &M3, const Multilib &M4, const Multilib &M5); - MultilibSet &Either(const std::vector &Ms); + MultilibSet &Either(ArrayRef Ms); /// Filter out some subset of the Multilibs using a user defined callback - MultilibSet &FilterOut(const FilterCallback &F); + MultilibSet &FilterOut(FilterCallback F); /// Filter out those Multilibs whose gccSuffix matches the given expression - MultilibSet &FilterOut(std::string Regex); + MultilibSet &FilterOut(const char *Regex); /// Add a completed Multilib to the set void push_back(const Multilib &M); @@ -157,18 +154,17 @@ public: void print(raw_ostream &OS) const; MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) { - IncludeCallback = F; + IncludeCallback = std::move(F); return *this; } - IncludeDirsFunc includeDirsCallback() const { return IncludeCallback; } + const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; } private: /// Apply the filter to Multilibs and return the subset that remains - static multilib_list filterCopy(const FilterCallback &F, - const multilib_list &Ms); + static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms); /// Apply the filter to the multilib_list, removing those that don't match - static void filterInPlace(const FilterCallback &F, multilib_list &Ms); + static void filterInPlace(FilterCallback F, multilib_list &Ms); }; raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS); diff --git a/clang/lib/Driver/Multilib.cpp b/clang/lib/Driver/Multilib.cpp index b503acc..8acda67 100644 --- a/clang/lib/Driver/Multilib.cpp +++ b/clang/lib/Driver/Multilib.cpp @@ -151,41 +151,23 @@ MultilibSet &MultilibSet::Maybe(const Multilib &M) { } MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2) { - std::vector Ms; - Ms.push_back(M1); - Ms.push_back(M2); - return Either(Ms); + return Either({M1, M2}); } MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2, const Multilib &M3) { - std::vector Ms; - Ms.push_back(M1); - Ms.push_back(M2); - Ms.push_back(M3); - return Either(Ms); + return Either({M1, M2, M3}); } MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2, const Multilib &M3, const Multilib &M4) { - std::vector Ms; - Ms.push_back(M1); - Ms.push_back(M2); - Ms.push_back(M3); - Ms.push_back(M4); - return Either(Ms); + return Either({M1, M2, M3, M4}); } MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2, const Multilib &M3, const Multilib &M4, const Multilib &M5) { - std::vector Ms; - Ms.push_back(M1); - Ms.push_back(M2); - Ms.push_back(M3); - Ms.push_back(M4); - Ms.push_back(M5); - return Either(Ms); + return Either({M1, M2, M3, M4, M5}); } static Multilib compose(const Multilib &Base, const Multilib &New) { @@ -207,8 +189,7 @@ static Multilib compose(const Multilib &Base, const Multilib &New) { return Composed; } -MultilibSet & -MultilibSet::Either(const std::vector &MultilibSegments) { +MultilibSet &MultilibSet::Either(ArrayRef MultilibSegments) { multilib_list Composed; if (Multilibs.empty()) @@ -229,30 +210,23 @@ MultilibSet::Either(const std::vector &MultilibSegments) { return *this; } -MultilibSet &MultilibSet::FilterOut(const MultilibSet::FilterCallback &F) { +MultilibSet &MultilibSet::FilterOut(FilterCallback F) { filterInPlace(F, Multilibs); return *this; } -MultilibSet &MultilibSet::FilterOut(std::string Regex) { - class REFilter : public MultilibSet::FilterCallback { - mutable llvm::Regex R; - - public: - REFilter(std::string Regex) : R(Regex) {} - bool operator()(const Multilib &M) const override { - std::string Error; - if (!R.isValid(Error)) { - llvm::errs() << Error; - assert(false); - return false; - } - return R.match(M.gccSuffix()); - } - }; +MultilibSet &MultilibSet::FilterOut(const char *Regex) { + llvm::Regex R(Regex); +#ifndef NDEBUG + std::string Error; + if (!R.isValid(Error)) { + llvm::errs() << Error; + llvm_unreachable("Invalid regex!"); + } +#endif - REFilter REF(Regex); - filterInPlace(REF, Multilibs); + filterInPlace([&R](const Multilib &M) { return R.match(M.gccSuffix()); }, + Multilibs); return *this; } @@ -262,38 +236,29 @@ void MultilibSet::combineWith(const MultilibSet &Other) { Multilibs.insert(Multilibs.end(), Other.begin(), Other.end()); } +static bool isFlagEnabled(StringRef Flag) { + char Indicator = Flag.front(); + assert(Indicator == '+' || Indicator == '-'); + return Indicator == '+'; +} + bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const { - class FilterFlagsMismatch : public MultilibSet::FilterCallback { - llvm::StringMap FlagSet; - - public: - FilterFlagsMismatch(const std::vector &Flags) { - // Stuff all of the flags into the FlagSet such that a true mappend - // indicates the flag was enabled, and a false mappend indicates the - // flag was disabled - for (StringRef Flag : Flags) - FlagSet[Flag.substr(1)] = isFlagEnabled(Flag); - } - bool operator()(const Multilib &M) const override { - for (StringRef Flag : M.flags()) { - llvm::StringMap::const_iterator SI = FlagSet.find(Flag.substr(1)); - if (SI != FlagSet.end()) - if (SI->getValue() != isFlagEnabled(Flag)) - return true; - } - return false; - } - private: - bool isFlagEnabled(StringRef Flag) const { - char Indicator = Flag.front(); - assert(Indicator == '+' || Indicator == '-'); - return Indicator == '+'; + llvm::StringMap FlagSet; + + // Stuff all of the flags into the FlagSet such that a true mappend indicates + // the flag was enabled, and a false mappend indicates the flag was disabled. + for (StringRef Flag : Flags) + FlagSet[Flag.substr(1)] = isFlagEnabled(Flag); + + multilib_list Filtered = filterCopy([&FlagSet](const Multilib &M) { + for (StringRef Flag : M.flags()) { + llvm::StringMap::const_iterator SI = FlagSet.find(Flag.substr(1)); + if (SI != FlagSet.end()) + if (SI->getValue() != isFlagEnabled(Flag)) + return true; } - }; - - FilterFlagsMismatch FlagsMismatch(Flags); - - multilib_list Filtered = filterCopy(FlagsMismatch, Multilibs); + return false; + }, Multilibs); if (Filtered.size() == 0) { return false; @@ -313,19 +278,15 @@ void MultilibSet::print(raw_ostream &OS) const { OS << M << "\n"; } -MultilibSet::multilib_list -MultilibSet::filterCopy(const MultilibSet::FilterCallback &F, - const multilib_list &Ms) { +MultilibSet::multilib_list MultilibSet::filterCopy(FilterCallback F, + const multilib_list &Ms) { multilib_list Copy(Ms); filterInPlace(F, Copy); return Copy; } -void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F, - multilib_list &Ms) { - Ms.erase(std::remove_if(Ms.begin(), Ms.end(), - [&F](const Multilib &M) { return F(M); }), - Ms.end()); +void MultilibSet::filterInPlace(FilterCallback F, multilib_list &Ms) { + Ms.erase(std::remove_if(Ms.begin(), Ms.end(), F), Ms.end()); } raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) { diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index e358c4e..15a461e 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -1498,11 +1498,12 @@ bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { namespace { // Filter to remove Multilibs that don't exist as a suffix to Path -class FilterNonExistent : public MultilibSet::FilterCallback { - std::string Base; +class FilterNonExistent { + StringRef Base; + public: - FilterNonExistent(std::string Base) : Base(Base) {} - bool operator()(const Multilib &M) const override { + FilterNonExistent(StringRef Base) : Base(Base) {} + bool operator()(const Multilib &M) { return !llvm::sys::fs::exists(Base + M.gccSuffix() + "/crtbegin.o"); } }; @@ -3171,7 +3172,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Add include directories specific to the selected multilib set and multilib. if (GCCInstallation.isValid()) { - auto Callback = Multilibs.includeDirsCallback(); + const auto &Callback = Multilibs.includeDirsCallback(); if (Callback) { const auto IncludePaths = Callback(GCCInstallation.getInstallPath(), GCCInstallation.getTriple().str(), -- 2.7.4