AnalyzerOptions.cpp revision bfa9ab8183e2fdc74f8633d758cb0c6201314320
1//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains special accessors for analyzer configuration options
11// with string representations.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/raw_ostream.h"
19
20using namespace clang;
21using namespace llvm;
22
23IPAKind AnalyzerOptions::getIPAMode() {
24  if (IPAMode == IPAK_NotSet) {
25
26    // Lookup the ipa configuration option, use the default from User Mode.
27    StringRef ModeStr(Config.GetOrCreateValue("ipa",
28                                              "dynamic-bifurcate").getValue());
29    IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
30            .Case("none", IPAK_None)
31            .Case("basic-inlining", IPAK_BasicInlining)
32            .Case("inlining", IPAK_Inlining)
33            .Case("dynamic", IPAK_DynamicDispatch)
34            .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
35            .Default(IPAK_NotSet);
36    assert(IPAConfig != IPAK_NotSet && "IPA Mode is not set or invalid.");
37
38    // Set the member variable.
39    IPAMode = IPAConfig;
40  }
41
42  return IPAMode;
43}
44
45bool
46AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) {
47  if (getIPAMode() < IPAK_Inlining)
48    return false;
49
50  if (!CXXMemberInliningMode) {
51    static const char *ModeKey = "c++-inlining";
52
53    StringRef ModeStr(Config.GetOrCreateValue(ModeKey,
54                                              "methods").getValue());
55
56    CXXInlineableMemberKind &MutableMode =
57      const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);
58
59    MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
60      .Case("constructors", CIMK_Constructors)
61      .Case("destructors", CIMK_Destructors)
62      .Case("none", CIMK_None)
63      .Case("methods", CIMK_MemberFunctions)
64      .Default(CXXInlineableMemberKind());
65
66    if (!MutableMode) {
67      // FIXME: We should emit a warning here about an unknown inlining kind,
68      // but the AnalyzerOptions doesn't have access to a diagnostic engine.
69      MutableMode = CIMK_None;
70    }
71  }
72
73  return CXXMemberInliningMode >= K;
74}
75
76static StringRef toString(bool b) { return b ? "true" : "false"; }
77
78bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) {
79  // FIXME: We should emit a warning here if the value is something other than
80  // "true", "false", or the empty string (meaning the default value),
81  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
82  StringRef V(Config.GetOrCreateValue(Name, toString(DefaultVal)).getValue());
83  return llvm::StringSwitch<bool>(V)
84      .Case("true", true)
85      .Case("false", false)
86      .Default(DefaultVal);
87}
88
89bool AnalyzerOptions::getBooleanOption(llvm::Optional<bool> &V,
90                                       StringRef Name,
91                                       bool DefaultVal) {
92  if (!V.hasValue())
93    V = getBooleanOption(Name, DefaultVal);
94  return V.getValue();
95}
96
97bool AnalyzerOptions::includeTemporaryDtorsInCFG() {
98  return getBooleanOption(IncludeTemporaryDtorsInCFG,
99                          "cfg-temporary-dtors",
100                          /* Default = */ false);
101}
102
103bool AnalyzerOptions::mayInlineCXXStandardLibrary() {
104  return getBooleanOption(InlineCXXStandardLibrary,
105                          "c++-stdlib-inlining",
106                          /*Default=*/true);
107}
108
109bool AnalyzerOptions::mayInlineTemplateFunctions() {
110  return getBooleanOption(InlineTemplateFunctions,
111                          "c++-template-inlining",
112                          /*Default=*/true);
113}
114
115bool AnalyzerOptions::mayInlineObjCMethod() {
116  return getBooleanOption(ObjCInliningMode,
117                          "objc-inlining",
118                          /* Default = */ true);
119}
120
121bool AnalyzerOptions::shouldPruneNullReturnPaths() {
122  return getBooleanOption(PruneNullReturnPaths,
123                          "suppress-null-return-paths",
124                          /* Default = */ true);
125}
126
127bool AnalyzerOptions::shouldAvoidSuppressingNullArgumentPaths() {
128  return getBooleanOption(AvoidSuppressingNullArgumentPaths,
129                          "avoid-suppressing-null-argument-paths",
130                          /* Default = */ false);
131}
132
133int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
134  SmallString<10> StrBuf;
135  llvm::raw_svector_ostream OS(StrBuf);
136  OS << DefaultVal;
137
138  StringRef V(Config.GetOrCreateValue(Name, OS.str()).getValue());
139  int Res = DefaultVal;
140  bool b = V.getAsInteger(10, Res);
141  assert(!b && "analyzer-config option should be numeric");
142  (void) b;
143  return Res;
144}
145
146unsigned AnalyzerOptions::getAlwaysInlineSize() {
147  if (!AlwaysInlineSize.hasValue())
148    AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
149  return AlwaysInlineSize.getValue();
150}
151
152unsigned AnalyzerOptions::getGraphTrimInterval() {
153  if (!GraphTrimInterval.hasValue())
154    GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000);
155  return GraphTrimInterval.getValue();
156}
157
158unsigned AnalyzerOptions::getMaxTimesInlineLarge() {
159  if (!MaxTimesInlineLarge.hasValue())
160    MaxTimesInlineLarge = getOptionAsInteger("max-times-inline-large", 32);
161  return MaxTimesInlineLarge.getValue();
162}
163
164bool AnalyzerOptions::shouldSynthesizeBodies() {
165  return getBooleanOption("faux-bodies", true);
166}
167