summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp')
-rw-r--r--gnu/llvm/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp194
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);
+}