aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/AnalyzerOptions.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp59
1 files changed, 51 insertions, 8 deletions
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index d717e3fe86d2..1696bcfac9c1 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -13,12 +13,14 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
+using namespace ento;
using namespace llvm;
AnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
@@ -100,12 +102,37 @@ AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) {
static StringRef toString(bool b) { return b ? "true" : "false"; }
-bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) {
+StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
+ StringRef OptionName,
+ StringRef Default,
+ bool SearchInParents) {
+ // Search for a package option if the option for the checker is not specified
+ // and search in parents is enabled.
+ 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)
+ return Default;
+ CheckerName = CheckerName.substr(0, Pos);
+ } while (!CheckerName.empty() && SearchInParents);
+ return Default;
+}
+
+bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal,
+ const CheckerBase *C,
+ bool SearchInParents) {
// FIXME: We should emit a warning here if the value is something other than
// "true", "false", or the empty string (meaning the default value),
// but the AnalyzerOptions doesn't have access to a diagnostic engine.
+ StringRef Default = toString(DefaultVal);
StringRef V =
- Config.insert(std::make_pair(Name, toString(DefaultVal))).first->second;
+ C ? getCheckerOption(C->getTagDescription(), Name, Default,
+ SearchInParents)
+ : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
return llvm::StringSwitch<bool>(V)
.Case("true", true)
.Case("false", false)
@@ -113,9 +140,10 @@ bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) {
}
bool AnalyzerOptions::getBooleanOption(Optional<bool> &V, StringRef Name,
- bool DefaultVal) {
+ bool DefaultVal, const CheckerBase *C,
+ bool SearchInParents) {
if (!V.hasValue())
- V = getBooleanOption(Name, DefaultVal);
+ V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
return V.getValue();
}
@@ -199,19 +227,35 @@ bool AnalyzerOptions::shouldWriteStableReportFilename() {
/* Default = */ false);
}
-int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
+int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal,
+ const CheckerBase *C,
+ bool SearchInParents) {
SmallString<10> StrBuf;
llvm::raw_svector_ostream OS(StrBuf);
OS << DefaultVal;
- StringRef V = Config.insert(std::make_pair(Name, OS.str())).first->second;
+ StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(),
+ SearchInParents)
+ : StringRef(Config.insert(std::make_pair(Name, OS.str()))
+ .first->second);
+
int Res = DefaultVal;
bool b = V.getAsInteger(10, Res);
assert(!b && "analyzer-config option should be numeric");
- (void) b;
+ (void)b;
return Res;
}
+StringRef AnalyzerOptions::getOptionAsString(StringRef Name,
+ StringRef DefaultVal,
+ const CheckerBase *C,
+ bool SearchInParents) {
+ return C ? getCheckerOption(C->getTagDescription(), Name, DefaultVal,
+ SearchInParents)
+ : StringRef(
+ Config.insert(std::make_pair(Name, DefaultVal)).first->second);
+}
+
unsigned AnalyzerOptions::getAlwaysInlineSize() {
if (!AlwaysInlineSize.hasValue())
AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
@@ -281,4 +325,3 @@ bool AnalyzerOptions::shouldPrunePaths() {
bool AnalyzerOptions::shouldConditionalizeStaticInitializers() {
return getBooleanOption("cfg-conditional-static-initializers", true);
}
-