From: Kristof Umann Date: Thu, 18 Apr 2019 17:34:45 +0000 (+0000) Subject: [analyzer][NFC] Prefer binary searches in CheckerRegistry X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a587cf65682501489f4db724b959c8c9315bc04b;p=clang [analyzer][NFC] Prefer binary searches in CheckerRegistry Differential Revision: https://reviews.llvm.org/D59459 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@358695 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 96e32635ec..ab8fff0ce7 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -108,8 +108,8 @@ public: State_Enabled }; - InitializationFunction Initialize; - ShouldRegisterFunction ShouldRegister; + InitializationFunction Initialize = nullptr; + ShouldRegisterFunction ShouldRegister = nullptr; StringRef FullName; StringRef Desc; StringRef DocumentationUri; @@ -129,6 +129,9 @@ public: StringRef Name, StringRef Desc, StringRef DocsUri) : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), DocumentationUri(DocsUri) {} + + // Used for lower_bound. + explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} }; using StateFromCmdLine = CheckerInfo::StateFromCmdLine; diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index b164d41438..c0d5d1bdc3 100644 --- a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -48,6 +48,28 @@ template struct FullNameLT { using CheckerNameLT = FullNameLT; } // end of anonymous namespace +template +static + typename std::conditional::value, + typename CheckerOrPackageInfoList::const_iterator, + typename CheckerOrPackageInfoList::iterator>::type + binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) { + + using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type; + using CheckerOrPackageFullNameLT = FullNameLT; + + assert(std::is_sorted(Collection.begin(), Collection.end(), + CheckerOrPackageFullNameLT{}) && + "In order to efficiently gather checkers/packages, this function " + "expects them to be already sorted!"); + + typename CheckerOrPackageInfoList::value_type Info(FullName); + + return llvm::lower_bound( + Collection, Info, + FullNameLT{}); +} + static constexpr char PackageSeparator = '.'; static bool isInPackage(const CheckerRegistry::CheckerInfo &Checker, @@ -69,16 +91,7 @@ static bool isInPackage(const CheckerRegistry::CheckerInfo &Checker, CheckerRegistry::CheckerInfoListRange CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) { - - assert(std::is_sorted(Checkers.begin(), Checkers.end(), CheckerNameLT{}) && - "In order to efficiently gather checkers, this function expects them " - "to be already sorted!"); - - // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo PackageInfo(nullptr, nullptr, CmdLineArg, "", - ""); - auto It = std::lower_bound(Checkers.begin(), Checkers.end(), PackageInfo, - CheckerNameLT{}); + auto It = binaryFind(Checkers, CmdLineArg); if (!isInPackage(*It, CmdLineArg)) return {Checkers.end(), Checkers.end()}; @@ -268,24 +281,18 @@ void CheckerRegistry::addChecker(InitializationFunction Rfn, } } -void CheckerRegistry::addDependency(StringRef FullName, StringRef dependency) { - auto CheckerThatNeedsDeps = [&FullName](const CheckerInfo &Chk) { - return Chk.FullName == FullName; - }; - auto Dependency = [&dependency](const CheckerInfo &Chk) { - return Chk.FullName == dependency; - }; - - auto CheckerIt = llvm::find_if(Checkers, CheckerThatNeedsDeps); - assert(CheckerIt != Checkers.end() && +void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) { + auto CheckerIt = binaryFind(Checkers, FullName); + assert(CheckerIt != Checkers.end() && CheckerIt->FullName == FullName && "Failed to find the checker while attempting to set up its " "dependencies!"); - auto DependencyIt = llvm::find_if(Checkers, Dependency); + auto DependencyIt = binaryFind(Checkers, Dependency); assert(DependencyIt != Checkers.end() && + DependencyIt->FullName == Dependency && "Failed to find the dependency of a checker!"); - CheckerIt->Dependencies.push_back(&*DependencyIt); + CheckerIt->Dependencies.emplace_back(&*DependencyIt); } void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {