clang  3.7.0
AnalyzerOptions.cpp
Go to the documentation of this file.
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 
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 
22 using namespace clang;
23 using namespace ento;
24 using namespace llvm;
25 
26 AnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
27  if (UserMode == UMK_NotSet) {
28  StringRef ModeStr =
29  Config.insert(std::make_pair("mode", "deep")).first->second;
30  UserMode = llvm::StringSwitch<UserModeKind>(ModeStr)
31  .Case("shallow", UMK_Shallow)
32  .Case("deep", UMK_Deep)
33  .Default(UMK_NotSet);
34  assert(UserMode != UMK_NotSet && "User mode is invalid.");
35  }
36  return UserMode;
37 }
38 
40  if (IPAMode == IPAK_NotSet) {
41 
42  // Use the User Mode to set the default IPA value.
43  // Note, we have to add the string to the Config map for the ConfigDumper
44  // checker to function properly.
45  const char *DefaultIPA = nullptr;
46  UserModeKind HighLevelMode = getUserMode();
47  if (HighLevelMode == UMK_Shallow)
48  DefaultIPA = "inlining";
49  else if (HighLevelMode == UMK_Deep)
50  DefaultIPA = "dynamic-bifurcate";
51  assert(DefaultIPA);
52 
53  // Lookup the ipa configuration option, use the default from User Mode.
54  StringRef ModeStr =
55  Config.insert(std::make_pair("ipa", DefaultIPA)).first->second;
56  IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
57  .Case("none", IPAK_None)
58  .Case("basic-inlining", IPAK_BasicInlining)
59  .Case("inlining", IPAK_Inlining)
60  .Case("dynamic", IPAK_DynamicDispatch)
61  .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
62  .Default(IPAK_NotSet);
63  assert(IPAConfig != IPAK_NotSet && "IPA Mode is invalid.");
64 
65  // Set the member variable.
66  IPAMode = IPAConfig;
67  }
68 
69  return IPAMode;
70 }
71 
72 bool
74  if (getIPAMode() < IPAK_Inlining)
75  return false;
76 
77  if (!CXXMemberInliningMode) {
78  static const char *ModeKey = "c++-inlining";
79 
80  StringRef ModeStr =
81  Config.insert(std::make_pair(ModeKey, "destructors")).first->second;
82 
83  CXXInlineableMemberKind &MutableMode =
84  const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);
85 
86  MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
87  .Case("constructors", CIMK_Constructors)
88  .Case("destructors", CIMK_Destructors)
89  .Case("none", CIMK_None)
90  .Case("methods", CIMK_MemberFunctions)
91  .Default(CXXInlineableMemberKind());
92 
93  if (!MutableMode) {
94  // FIXME: We should emit a warning here about an unknown inlining kind,
95  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
96  MutableMode = CIMK_None;
97  }
98  }
99 
100  return CXXMemberInliningMode >= K;
101 }
102 
103 static StringRef toString(bool b) { return b ? "true" : "false"; }
104 
105 StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
106  StringRef OptionName,
107  StringRef Default,
108  bool SearchInParents) {
109  // Search for a package option if the option for the checker is not specified
110  // and search in parents is enabled.
111  ConfigTable::const_iterator E = Config.end();
112  do {
113  ConfigTable::const_iterator I =
114  Config.find((Twine(CheckerName) + ":" + OptionName).str());
115  if (I != E)
116  return StringRef(I->getValue());
117  size_t Pos = CheckerName.rfind('.');
118  if (Pos == StringRef::npos)
119  return Default;
120  CheckerName = CheckerName.substr(0, Pos);
121  } while (!CheckerName.empty() && SearchInParents);
122  return Default;
123 }
124 
125 bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal,
126  const CheckerBase *C,
127  bool SearchInParents) {
128  // FIXME: We should emit a warning here if the value is something other than
129  // "true", "false", or the empty string (meaning the default value),
130  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
131  StringRef Default = toString(DefaultVal);
132  StringRef V =
133  C ? getCheckerOption(C->getTagDescription(), Name, Default,
134  SearchInParents)
135  : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
136  return llvm::StringSwitch<bool>(V)
137  .Case("true", true)
138  .Case("false", false)
139  .Default(DefaultVal);
140 }
141 
143  bool DefaultVal, const CheckerBase *C,
144  bool SearchInParents) {
145  if (!V.hasValue())
146  V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
147  return V.getValue();
148 }
149 
151  return getBooleanOption(IncludeTemporaryDtorsInCFG,
152  "cfg-temporary-dtors",
153  /* Default = */ false);
154 }
155 
157  return getBooleanOption(InlineCXXStandardLibrary,
158  "c++-stdlib-inlining",
159  /*Default=*/true);
160 }
161 
163  return getBooleanOption(InlineTemplateFunctions,
164  "c++-template-inlining",
165  /*Default=*/true);
166 }
167 
169  return getBooleanOption(InlineCXXAllocator,
170  "c++-allocator-inlining",
171  /*Default=*/false);
172 }
173 
175  return getBooleanOption(InlineCXXContainerMethods,
176  "c++-container-inlining",
177  /*Default=*/false);
178 }
179 
181  return getBooleanOption(InlineCXXSharedPtrDtor,
182  "c++-shared_ptr-inlining",
183  /*Default=*/false);
184 }
185 
186 
188  return getBooleanOption(ObjCInliningMode,
189  "objc-inlining",
190  /* Default = */ true);
191 }
192 
194  return getBooleanOption(SuppressNullReturnPaths,
195  "suppress-null-return-paths",
196  /* Default = */ true);
197 }
198 
200  return getBooleanOption(AvoidSuppressingNullArgumentPaths,
201  "avoid-suppressing-null-argument-paths",
202  /* Default = */ false);
203 }
204 
206  return getBooleanOption(SuppressInlinedDefensiveChecks,
207  "suppress-inlined-defensive-checks",
208  /* Default = */ true);
209 }
210 
212  return getBooleanOption(SuppressFromCXXStandardLibrary,
213  "suppress-c++-stdlib",
214  /* Default = */ false);
215 }
216 
218  return getBooleanOption(ReportIssuesInMainSourceFile,
219  "report-in-main-source-file",
220  /* Default = */ false);
221 }
222 
223 
225  return getBooleanOption(StableReportFilename,
226  "stable-report-filename",
227  /* Default = */ false);
228 }
229 
230 int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal,
231  const CheckerBase *C,
232  bool SearchInParents) {
233  SmallString<10> StrBuf;
234  llvm::raw_svector_ostream OS(StrBuf);
235  OS << DefaultVal;
236 
237  StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(),
238  SearchInParents)
239  : StringRef(Config.insert(std::make_pair(Name, OS.str()))
240  .first->second);
241 
242  int Res = DefaultVal;
243  bool b = V.getAsInteger(10, Res);
244  assert(!b && "analyzer-config option should be numeric");
245  (void)b;
246  return Res;
247 }
248 
249 StringRef AnalyzerOptions::getOptionAsString(StringRef Name,
250  StringRef DefaultVal,
251  const CheckerBase *C,
252  bool SearchInParents) {
253  return C ? getCheckerOption(C->getTagDescription(), Name, DefaultVal,
254  SearchInParents)
255  : StringRef(
256  Config.insert(std::make_pair(Name, DefaultVal)).first->second);
257 }
258 
260  if (!AlwaysInlineSize.hasValue())
261  AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
262  return AlwaysInlineSize.getValue();
263 }
264 
266  if (!MaxInlinableSize.hasValue()) {
267 
268  int DefaultValue = 0;
269  UserModeKind HighLevelMode = getUserMode();
270  switch (HighLevelMode) {
271  default:
272  llvm_unreachable("Invalid mode.");
273  case UMK_Shallow:
274  DefaultValue = 4;
275  break;
276  case UMK_Deep:
277  DefaultValue = 50;
278  break;
279  }
280 
281  MaxInlinableSize = getOptionAsInteger("max-inlinable-size", DefaultValue);
282  }
283  return MaxInlinableSize.getValue();
284 }
285 
287  if (!GraphTrimInterval.hasValue())
288  GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000);
289  return GraphTrimInterval.getValue();
290 }
291 
293  if (!MaxTimesInlineLarge.hasValue())
294  MaxTimesInlineLarge = getOptionAsInteger("max-times-inline-large", 32);
295  return MaxTimesInlineLarge.getValue();
296 }
297 
299  if (!MaxNodesPerTopLevelFunction.hasValue()) {
300  int DefaultValue = 0;
301  UserModeKind HighLevelMode = getUserMode();
302  switch (HighLevelMode) {
303  default:
304  llvm_unreachable("Invalid mode.");
305  case UMK_Shallow:
306  DefaultValue = 75000;
307  break;
308  case UMK_Deep:
309  DefaultValue = 150000;
310  break;
311  }
312  MaxNodesPerTopLevelFunction = getOptionAsInteger("max-nodes", DefaultValue);
313  }
314  return MaxNodesPerTopLevelFunction.getValue();
315 }
316 
318  return getBooleanOption("faux-bodies", true);
319 }
320 
322  return getBooleanOption("prune-paths", true);
323 }
324 
326  return getBooleanOption("cfg-conditional-static-initializers", true);
327 }
Inline C functions and blocks when their definitions are available.
IPAKind
Describes the different modes of inter-procedural analysis.
bool shouldAvoidSuppressingNullArgumentPaths()
Perform only intra-procedural analysis.
A dummy mode in which no C++ inlining is enabled.
Inline callees(C, C++, ObjC) when their definitions are available.
StringRef getOptionAsString(StringRef Name, StringRef DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
StringRef getTagDescription() const override
Definition: Checker.cpp:20
UserModeKind getUserMode()
Retrieves and sets the UserMode. This is a high-level option, which is used to set other low-level op...
IPAKind getIPAMode()
Returns the inter-procedural analysis mode.
Refers to regular member function and operator calls.
bool mayInlineObjCMethod()
Returns true if ObjectiveC inlining is enabled, false otherwise.
bool shouldConditionalizeStaticInitializers()
Enable inlining of dynamically dispatched methods.
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
unsigned getMaxNodesPerTopLevelFunction()
Refers to destructors (implicit or explicit).
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K)
CXXInlineableMemberKind
Describes the different kinds of C++ member functions which can be considered for inlining by the ana...
int getOptionAsInteger(StringRef Name, int DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
static StringRef toString(bool b)