diff options
Diffstat (limited to 'gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp')
-rw-r--r-- | gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp new file mode 100644 index 00000000000..01ac2bc83bb --- /dev/null +++ b/gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -0,0 +1,194 @@ +//===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains special accessors for analyzer configuration options +// with string representations. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstddef> +#include <utility> +#include <vector> + +using namespace clang; +using namespace ento; +using namespace llvm; + +void AnalyzerOptions::printFormattedEntry( + llvm::raw_ostream &Out, + std::pair<StringRef, StringRef> EntryDescPair, + size_t InitialPad, size_t EntryWidth, size_t MinLineWidth) { + + llvm::formatted_raw_ostream FOut(Out); + + const size_t PadForDesc = InitialPad + EntryWidth; + + FOut.PadToColumn(InitialPad) << EntryDescPair.first; + // If the buffer's length is greater then PadForDesc, print a newline. + if (FOut.getColumn() > PadForDesc) + FOut << '\n'; + + FOut.PadToColumn(PadForDesc); + + if (MinLineWidth == 0) { + FOut << EntryDescPair.second; + return; + } + + for (char C : EntryDescPair.second) { + if (FOut.getColumn() > MinLineWidth && C == ' ') { + FOut << '\n'; + FOut.PadToColumn(PadForDesc); + continue; + } + FOut << C; + } +} + +ExplorationStrategyKind +AnalyzerOptions::getExplorationStrategy() const { + auto K = + llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>( + ExplorationStrategy) + .Case("dfs", ExplorationStrategyKind::DFS) + .Case("bfs", ExplorationStrategyKind::BFS) + .Case("unexplored_first", + ExplorationStrategyKind::UnexploredFirst) + .Case("unexplored_first_queue", + ExplorationStrategyKind::UnexploredFirstQueue) + .Case("unexplored_first_location_queue", + ExplorationStrategyKind::UnexploredFirstLocationQueue) + .Case("bfs_block_dfs_contents", + ExplorationStrategyKind::BFSBlockDFSContents) + .Default(None); + assert(K.hasValue() && "User mode is invalid."); + return K.getValue(); +} + +IPAKind AnalyzerOptions::getIPAMode() const { + auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode) + .Case("none", IPAK_None) + .Case("basic-inlining", IPAK_BasicInlining) + .Case("inlining", IPAK_Inlining) + .Case("dynamic", IPAK_DynamicDispatch) + .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate) + .Default(None); + assert(K.hasValue() && "IPA Mode is invalid."); + + return K.getValue(); +} + +bool +AnalyzerOptions::mayInlineCXXMemberFunction( + CXXInlineableMemberKind Param) const { + if (getIPAMode() < IPAK_Inlining) + return false; + + auto K = + llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>( + CXXMemberInliningMode) + .Case("constructors", CIMK_Constructors) + .Case("destructors", CIMK_Destructors) + .Case("methods", CIMK_MemberFunctions) + .Case("none", CIMK_None) + .Default(None); + + assert(K.hasValue() && "Invalid c++ member function inlining mode."); + + return *K >= Param; +} + +StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName, + StringRef OptionName, + bool SearchInParents) const { + assert(!CheckerName.empty() && + "Empty checker name! Make sure the checker object (including it's " + "bases!) if fully initialized before calling this function!"); + + ConfigTable::const_iterator E = Config.end(); + do { + ConfigTable::const_iterator I = + Config.find((Twine(CheckerName) + ":" + OptionName).str()); + if (I != E) + return StringRef(I->getValue()); + size_t Pos = CheckerName.rfind('.'); + if (Pos == StringRef::npos) + break; + + CheckerName = CheckerName.substr(0, Pos); + } while (!CheckerName.empty() && SearchInParents); + + llvm_unreachable("Unknown checker option! Did you call getChecker*Option " + "with incorrect parameters? User input must've been " + "verified by CheckerRegistry."); + + return ""; +} + +StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C, + StringRef OptionName, + bool SearchInParents) const { + return getCheckerStringOption( + C->getTagDescription(), OptionName, SearchInParents); +} + +bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName, + StringRef OptionName, + bool SearchInParents) const { + auto Ret = llvm::StringSwitch<llvm::Optional<bool>>( + getCheckerStringOption(CheckerName, OptionName, + SearchInParents)) + .Case("true", true) + .Case("false", false) + .Default(None); + + assert(Ret && + "This option should be either 'true' or 'false', and should've been " + "validated by CheckerRegistry!"); + + return *Ret; +} + +bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C, + StringRef OptionName, + bool SearchInParents) const { + return getCheckerBooleanOption( + C->getTagDescription(), OptionName, SearchInParents); +} + +int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName, + StringRef OptionName, + bool SearchInParents) const { + int Ret = 0; + bool HasFailed = getCheckerStringOption(CheckerName, OptionName, + SearchInParents) + .getAsInteger(0, Ret); + assert(!HasFailed && + "This option should be numeric, and should've been validated by " + "CheckerRegistry!"); + (void)HasFailed; + return Ret; +} + +int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C, + StringRef OptionName, + bool SearchInParents) const { + return getCheckerIntegerOption( + C->getTagDescription(), OptionName, SearchInParents); +} |