diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp')
-rw-r--r-- | contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp b/contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp new file mode 100644 index 0000000000..1b3e8b1154 --- /dev/null +++ b/contrib/libs/clang16/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp @@ -0,0 +1,241 @@ +//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "llvm/ADT/Twine.h" +#include <map> + +using namespace clang; +using namespace ento; + +//===----------------------------------------------------------------------===// +// Methods of CmdLineOption, PackageInfo and CheckerInfo. +//===----------------------------------------------------------------------===// + +LLVM_DUMP_METHOD void CmdLineOption::dump() const { + dumpToStream(llvm::errs()); +} + +LLVM_DUMP_METHOD void +CmdLineOption::dumpToStream(llvm::raw_ostream &Out) const { + // The description can be just checked in Checkers.inc, the point here is to + // debug whether we succeeded in parsing it. + Out << OptionName << " (" << OptionType << ", " + << (IsHidden ? "hidden, " : "") << DevelopmentStatus << ") default: \"" + << DefaultValStr; +} + +static StringRef toString(StateFromCmdLine Kind) { + switch (Kind) { + case StateFromCmdLine::State_Disabled: + return "Disabled"; + case StateFromCmdLine::State_Enabled: + return "Enabled"; + case StateFromCmdLine::State_Unspecified: + return "Unspecified"; + } + llvm_unreachable("Unhandled StateFromCmdLine enum"); +} + +LLVM_DUMP_METHOD void CheckerInfo::dump() const { dumpToStream(llvm::errs()); } + +LLVM_DUMP_METHOD void CheckerInfo::dumpToStream(llvm::raw_ostream &Out) const { + // The description can be just checked in Checkers.inc, the point here is to + // debug whether we succeeded in parsing it. Same with documentation uri. + Out << FullName << " (" << toString(State) << (IsHidden ? ", hidden" : "") + << ")\n"; + Out << " Options:\n"; + for (const CmdLineOption &Option : CmdLineOptions) { + Out << " "; + Option.dumpToStream(Out); + Out << '\n'; + } + Out << " Dependencies:\n"; + for (const CheckerInfo *Dependency : Dependencies) { + Out << " " << Dependency->FullName << '\n'; + } + Out << " Weak dependencies:\n"; + for (const CheckerInfo *Dependency : WeakDependencies) { + Out << " " << Dependency->FullName << '\n'; + } +} + +LLVM_DUMP_METHOD void PackageInfo::dump() const { dumpToStream(llvm::errs()); } + +LLVM_DUMP_METHOD void PackageInfo::dumpToStream(llvm::raw_ostream &Out) const { + Out << FullName << "\n"; + Out << " Options:\n"; + for (const CmdLineOption &Option : CmdLineOptions) { + Out << " "; + Option.dumpToStream(Out); + Out << '\n'; + } +} + +static constexpr char PackageSeparator = '.'; + +static bool isInPackage(const CheckerInfo &Checker, StringRef PackageName) { + // Does the checker's full name have the package as a prefix? + if (!Checker.FullName.startswith(PackageName)) + return false; + + // Is the package actually just the name of a specific checker? + if (Checker.FullName.size() == PackageName.size()) + return true; + + // Is the checker in the package (or a subpackage)? + if (Checker.FullName[PackageName.size()] == PackageSeparator) + return true; + + return false; +} + +CheckerInfoListRange +CheckerRegistryData::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) { + auto It = checker_registry::binaryFind(Checkers, CmdLineArg); + + if (!isInPackage(*It, CmdLineArg)) + return {Checkers.end(), Checkers.end()}; + + // See how large the package is. + // If the package doesn't exist, assume the option refers to a single + // checker. + size_t Size = 1; + llvm::StringMap<size_t>::const_iterator PackageSize = + PackageSizes.find(CmdLineArg); + + if (PackageSize != PackageSizes.end()) + Size = PackageSize->getValue(); + + return {It, It + Size}; +} +//===----------------------------------------------------------------------===// +// Printing functions. +//===----------------------------------------------------------------------===// + +void CheckerRegistryData::printCheckerWithDescList( + const AnalyzerOptions &AnOpts, raw_ostream &Out, + size_t MaxNameChars) const { + // FIXME: Print available packages. + + Out << "CHECKERS:\n"; + + // Find the maximum option length. + size_t OptionFieldWidth = 0; + for (const auto &Checker : Checkers) { + // Limit the amount of padding we are willing to give up for alignment. + // Package.Name Description [Hidden] + size_t NameLength = Checker.FullName.size(); + if (NameLength <= MaxNameChars) + OptionFieldWidth = std::max(OptionFieldWidth, NameLength); + } + + const size_t InitialPad = 2; + + auto Print = [=](llvm::raw_ostream &Out, const CheckerInfo &Checker, + StringRef Description) { + AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Description}, + InitialPad, OptionFieldWidth); + Out << '\n'; + }; + + for (const auto &Checker : Checkers) { + // The order of this if branches is significant, we wouldn't like to display + // developer checkers even in the alpha output. For example, + // alpha.cplusplus.IteratorModeling is a modeling checker, hence it's hidden + // by default, and users (even when the user is a developer of an alpha + // checker) shouldn't normally tinker with whether they should be enabled. + + if (Checker.IsHidden) { + if (AnOpts.ShowCheckerHelpDeveloper) + Print(Out, Checker, Checker.Desc); + continue; + } + + if (Checker.FullName.startswith("alpha")) { + if (AnOpts.ShowCheckerHelpAlpha) + Print(Out, Checker, + ("(Enable only for development!) " + Checker.Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerHelp) + Print(Out, Checker, Checker.Desc); + } +} + +void CheckerRegistryData::printEnabledCheckerList(raw_ostream &Out) const { + for (const auto *i : EnabledCheckers) + Out << i->FullName << '\n'; +} + +void CheckerRegistryData::printCheckerOptionList(const AnalyzerOptions &AnOpts, + raw_ostream &Out) const { + Out << "OVERVIEW: Clang Static Analyzer Checker and Package Option List\n\n"; + Out << "USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>\n\n"; + Out << " -analyzer-config OPTION1=VALUE, -analyzer-config " + "OPTION2=VALUE, ...\n\n"; + Out << "OPTIONS:\n\n"; + + // It's usually ill-advised to use multimap, but clang will terminate after + // this function. + std::multimap<StringRef, const CmdLineOption &> OptionMap; + + for (const CheckerInfo &Checker : Checkers) { + for (const CmdLineOption &Option : Checker.CmdLineOptions) { + OptionMap.insert({Checker.FullName, Option}); + } + } + + for (const PackageInfo &Package : Packages) { + for (const CmdLineOption &Option : Package.CmdLineOptions) { + OptionMap.insert({Package.FullName, Option}); + } + } + + auto Print = [](llvm::raw_ostream &Out, StringRef FullOption, + StringRef Desc) { + AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc}, + /*InitialPad*/ 2, + /*EntryWidth*/ 50, + /*MinLineWidth*/ 90); + Out << "\n\n"; + }; + for (const std::pair<const StringRef, const CmdLineOption &> &Entry : + OptionMap) { + const CmdLineOption &Option = Entry.second; + std::string FullOption = (Entry.first + ":" + Option.OptionName).str(); + + std::string Desc = + ("(" + Option.OptionType + ") " + Option.Description + " (default: " + + (Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")") + .str(); + + // The list of these if branches is significant, we wouldn't like to + // display hidden alpha checker options for + // -analyzer-checker-option-help-alpha. + + if (Option.IsHidden) { + if (AnOpts.ShowCheckerOptionDeveloperList) + Print(Out, FullOption, Desc); + continue; + } + + if (Option.DevelopmentStatus == "alpha" || + Entry.first.startswith("alpha")) { + if (AnOpts.ShowCheckerOptionAlphaList) + Print(Out, FullOption, + llvm::Twine("(Enable only for development!) " + Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerOptionList) + Print(Out, FullOption, Desc); + } +} |