1de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
2de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//
3de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//                     The LLVM Compiler Infrastructure
4de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//
5de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose// This file is distributed under the University of Illinois Open Source
6de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose// License. See LICENSE.TXT for details.
7de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//
8de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//===----------------------------------------------------------------------===//
9de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//
10de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose// This file contains special accessors for analyzer configuration options
11de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose// with string representations.
12de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//
13de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose//===----------------------------------------------------------------------===//
14de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
15de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar#include "clang/StaticAnalyzer/Core/Checker.h"
1794bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek#include "llvm/ADT/SmallString.h"
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h"
19ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks#include "llvm/Support/ErrorHandling.h"
2094bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek#include "llvm/Support/raw_ostream.h"
21de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
22de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Roseusing namespace clang;
233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarusing namespace ento;
247229d0011766c174beffe6a846d78f448f845b39Anna Zaksusing namespace llvm;
25de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
26d130140cb7bce73b4350c5d50495443abe38418aAnna ZaksAnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
27d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  if (UserMode == UMK_NotSet) {
28176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StringRef ModeStr =
29176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Config.insert(std::make_pair("mode", "deep")).first->second;
30d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    UserMode = llvm::StringSwitch<UserModeKind>(ModeStr)
31d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks      .Case("shallow", UMK_Shallow)
32d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks      .Case("deep", UMK_Deep)
33d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks      .Default(UMK_NotSet);
34ce32890df08387b50a960f785da79ac5582b7f74Anna Zaks    assert(UserMode != UMK_NotSet && "User mode is invalid.");
35d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  }
36d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  return UserMode;
37d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks}
38d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
39bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna ZaksIPAKind AnalyzerOptions::getIPAMode() {
40bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  if (IPAMode == IPAK_NotSet) {
41bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
42d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    // Use the User Mode to set the default IPA value.
43d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    // Note, we have to add the string to the Config map for the ConfigDumper
44d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    // checker to function properly.
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const char *DefaultIPA = nullptr;
46d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    UserModeKind HighLevelMode = getUserMode();
47d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    if (HighLevelMode == UMK_Shallow)
48ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      DefaultIPA = "inlining";
49d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    else if (HighLevelMode == UMK_Deep)
50d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks      DefaultIPA = "dynamic-bifurcate";
51d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    assert(DefaultIPA);
52d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
53bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    // Lookup the ipa configuration option, use the default from User Mode.
54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StringRef ModeStr =
55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Config.insert(std::make_pair("ipa", DefaultIPA)).first->second;
56bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
57bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Case("none", IPAK_None)
58bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Case("basic-inlining", IPAK_BasicInlining)
59bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Case("inlining", IPAK_Inlining)
60bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Case("dynamic", IPAK_DynamicDispatch)
61bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
62bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks            .Default(IPAK_NotSet);
63ce32890df08387b50a960f785da79ac5582b7f74Anna Zaks    assert(IPAConfig != IPAK_NotSet && "IPA Mode is invalid.");
64bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
65bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    // Set the member variable.
66bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IPAMode = IPAConfig;
67bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  }
68bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
69bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  return IPAMode;
70bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks}
71bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
72de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rosebool
739e28fe60bbfa5de196ce4aa396210bf10fc5c266Ted KremenekAnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) {
74bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  if (getIPAMode() < IPAK_Inlining)
75de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    return false;
76de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
77de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  if (!CXXMemberInliningMode) {
78de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    static const char *ModeKey = "c++-inlining";
79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    StringRef ModeStr =
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Config.insert(std::make_pair(ModeKey, "destructors")).first->second;
82de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
83de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    CXXInlineableMemberKind &MutableMode =
84de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);
85de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
86de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
87de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      .Case("constructors", CIMK_Constructors)
88de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      .Case("destructors", CIMK_Destructors)
89de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      .Case("none", CIMK_None)
90de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      .Case("methods", CIMK_MemberFunctions)
91de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      .Default(CXXInlineableMemberKind());
92de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
93de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    if (!MutableMode) {
94de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      // FIXME: We should emit a warning here about an unknown inlining kind,
95de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      // but the AnalyzerOptions doesn't have access to a diagnostic engine.
96de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      MutableMode = CIMK_None;
97de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    }
98de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  }
99de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
100de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  return CXXMemberInliningMode >= K;
101de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose}
1025a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose
103622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekstatic StringRef toString(bool b) { return b ? "true" : "false"; }
104622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek
1053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarStringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
1063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                            StringRef OptionName,
1073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                            StringRef Default,
1083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                            bool SearchInParents) {
1093ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // Search for a package option if the option for the checker is not specified
1103ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // and search in parents is enabled.
1113ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  ConfigTable::const_iterator E = Config.end();
1123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  do {
1133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    ConfigTable::const_iterator I =
1143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        Config.find((Twine(CheckerName) + ":" + OptionName).str());
1153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    if (I != E)
1163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      return StringRef(I->getValue());
1173ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    size_t Pos = CheckerName.rfind('.');
1183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    if (Pos == StringRef::npos)
1193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      return Default;
1203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    CheckerName = CheckerName.substr(0, Pos);
1213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  } while (!CheckerName.empty() && SearchInParents);
1223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return Default;
1233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
1243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarbool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal,
1263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       const CheckerBase *C,
1273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       bool SearchInParents) {
12881fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose  // FIXME: We should emit a warning here if the value is something other than
12981fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose  // "true", "false", or the empty string (meaning the default value),
13081fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
1313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  StringRef Default = toString(DefaultVal);
132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  StringRef V =
1333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar      C ? getCheckerOption(C->getTagDescription(), Name, Default,
1343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                           SearchInParents)
1353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar        : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
136622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek  return llvm::StringSwitch<bool>(V)
137622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek      .Case("true", true)
138622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek      .Case("false", false)
139622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek      .Default(DefaultVal);
14081fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose}
14181fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose
142dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikiebool AnalyzerOptions::getBooleanOption(Optional<bool> &V, StringRef Name,
1433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       bool DefaultVal, const CheckerBase *C,
1443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                       bool SearchInParents) {
14548d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  if (!V.hasValue())
1463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
14748d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  return V.getValue();
14848d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek}
14948d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek
150622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekbool AnalyzerOptions::includeTemporaryDtorsInCFG() {
15148d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  return getBooleanOption(IncludeTemporaryDtorsInCFG,
15248d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          "cfg-temporary-dtors",
15348d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          /* Default = */ false);
15481fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose}
15581fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose
156622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekbool AnalyzerOptions::mayInlineCXXStandardLibrary() {
15748d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  return getBooleanOption(InlineCXXStandardLibrary,
15848d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          "c++-stdlib-inlining",
15948d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          /*Default=*/true);
16081fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose}
16181fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose
162622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekbool AnalyzerOptions::mayInlineTemplateFunctions() {
16348d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  return getBooleanOption(InlineTemplateFunctions,
16448d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          "c++-template-inlining",
16548d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          /*Default=*/true);
1665a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose}
1677229d0011766c174beffe6a846d78f448f845b39Anna Zaks
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool AnalyzerOptions::mayInlineCXXAllocator() {
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return getBooleanOption(InlineCXXAllocator,
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          "c++-allocator-inlining",
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          /*Default=*/false);
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesbool AnalyzerOptions::mayInlineCXXContainerMethods() {
175c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return getBooleanOption(InlineCXXContainerMethods,
176c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose                          "c++-container-inlining",
177c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose                          /*Default=*/false);
178c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose}
179c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose
18050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rosebool AnalyzerOptions::mayInlineCXXSharedPtrDtor() {
18150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  return getBooleanOption(InlineCXXSharedPtrDtor,
18250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose                          "c++-shared_ptr-inlining",
18350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose                          /*Default=*/false);
18450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose}
18550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
186c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose
187622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekbool AnalyzerOptions::mayInlineObjCMethod() {
18848d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek  return getBooleanOption(ObjCInliningMode,
18948d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          "objc-inlining",
19048d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          /* Default = */ true);
19157330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks}
19257330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks
1937ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rosebool AnalyzerOptions::shouldSuppressNullReturnPaths() {
1947ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rose  return getBooleanOption(SuppressNullReturnPaths,
19548d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          "suppress-null-return-paths",
19648d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek                          /* Default = */ true);
197b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
198b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
1996a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosebool AnalyzerOptions::shouldAvoidSuppressingNullArgumentPaths() {
2006a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return getBooleanOption(AvoidSuppressingNullArgumentPaths,
2016a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                          "avoid-suppressing-null-argument-paths",
2026a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                          /* Default = */ false);
2036a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
2046a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
205713e07591995d761f65c7132289dce003a29870fAnna Zaksbool AnalyzerOptions::shouldSuppressInlinedDefensiveChecks() {
206713e07591995d761f65c7132289dce003a29870fAnna Zaks  return getBooleanOption(SuppressInlinedDefensiveChecks,
207713e07591995d761f65c7132289dce003a29870fAnna Zaks                          "suppress-inlined-defensive-checks",
208713e07591995d761f65c7132289dce003a29870fAnna Zaks                          /* Default = */ true);
209713e07591995d761f65c7132289dce003a29870fAnna Zaks}
210713e07591995d761f65c7132289dce003a29870fAnna Zaks
211a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rosebool AnalyzerOptions::shouldSuppressFromCXXStandardLibrary() {
212a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  return getBooleanOption(SuppressFromCXXStandardLibrary,
213a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose                          "suppress-c++-stdlib",
214a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose                          /* Default = */ false);
215a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose}
216a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
217d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaksbool AnalyzerOptions::shouldReportIssuesInMainSourceFile() {
218d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks  return getBooleanOption(ReportIssuesInMainSourceFile,
219d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks                          "report-in-main-source-file",
220d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks                          /* Default = */ false);
221d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks}
222d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks
223c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
224c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesbool AnalyzerOptions::shouldWriteStableReportFilename() {
225c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return getBooleanOption(StableReportFilename,
226c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                          "stable-report-filename",
227c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                          /* Default = */ false);
228c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
229c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
2303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainarint AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal,
2313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                        const CheckerBase *C,
2323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                        bool SearchInParents) {
233cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallString<10> StrBuf;
23494bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek  llvm::raw_svector_ostream OS(StrBuf);
23594bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek  OS << DefaultVal;
236176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(),
2383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                     SearchInParents)
2393ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                  : StringRef(Config.insert(std::make_pair(Name, OS.str()))
2403ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                  .first->second);
2413ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
2427229d0011766c174beffe6a846d78f448f845b39Anna Zaks  int Res = DefaultVal;
24394bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek  bool b = V.getAsInteger(10, Res);
24494bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek  assert(!b && "analyzer-config option should be numeric");
2453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  (void)b;
2467229d0011766c174beffe6a846d78f448f845b39Anna Zaks  return Res;
2477229d0011766c174beffe6a846d78f448f845b39Anna Zaks}
2487229d0011766c174beffe6a846d78f448f845b39Anna Zaks
2493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga NainarStringRef AnalyzerOptions::getOptionAsString(StringRef Name,
2503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                             StringRef DefaultVal,
2513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                             const CheckerBase *C,
2523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                             bool SearchInParents) {
2533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return C ? getCheckerOption(C->getTagDescription(), Name, DefaultVal,
2543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                              SearchInParents)
2553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar           : StringRef(
2563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                 Config.insert(std::make_pair(Name, DefaultVal)).first->second);
2573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
2583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
25994bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenekunsigned AnalyzerOptions::getAlwaysInlineSize() {
26094bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek  if (!AlwaysInlineSize.hasValue())
26194bb74cef72a33d77c5d6739abfc0840c781eb8eTed Kremenek    AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
2627229d0011766c174beffe6a846d78f448f845b39Anna Zaks  return AlwaysInlineSize.getValue();
2637229d0011766c174beffe6a846d78f448f845b39Anna Zaks}
264a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
2656bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaksunsigned AnalyzerOptions::getMaxInlinableSize() {
266ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks  if (!MaxInlinableSize.hasValue()) {
267ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks
268ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    int DefaultValue = 0;
269ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    UserModeKind HighLevelMode = getUserMode();
270ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    switch (HighLevelMode) {
271ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      default:
272ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        llvm_unreachable("Invalid mode.");
273ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      case UMK_Shallow:
274ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        DefaultValue = 4;
275ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        break;
276ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      case UMK_Deep:
277ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        DefaultValue = 50;
278ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        break;
279ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    }
280ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks
281ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    MaxInlinableSize = getOptionAsInteger("max-inlinable-size", DefaultValue);
282ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks  }
2836bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaks  return MaxInlinableSize.getValue();
2846bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaks}
2856bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaks
2864d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Roseunsigned AnalyzerOptions::getGraphTrimInterval() {
2874d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  if (!GraphTrimInterval.hasValue())
2884d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose    GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000);
2894d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  return GraphTrimInterval.getValue();
2904d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose}
2914d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose
2927959671d456c916706a5f61af609d8f1fc95decfAnna Zaksunsigned AnalyzerOptions::getMaxTimesInlineLarge() {
2937959671d456c916706a5f61af609d8f1fc95decfAnna Zaks  if (!MaxTimesInlineLarge.hasValue())
2947959671d456c916706a5f61af609d8f1fc95decfAnna Zaks    MaxTimesInlineLarge = getOptionAsInteger("max-times-inline-large", 32);
2957959671d456c916706a5f61af609d8f1fc95decfAnna Zaks  return MaxTimesInlineLarge.getValue();
2967959671d456c916706a5f61af609d8f1fc95decfAnna Zaks}
2977959671d456c916706a5f61af609d8f1fc95decfAnna Zaks
298ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaksunsigned AnalyzerOptions::getMaxNodesPerTopLevelFunction() {
299ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks  if (!MaxNodesPerTopLevelFunction.hasValue()) {
300ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    int DefaultValue = 0;
301ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    UserModeKind HighLevelMode = getUserMode();
302ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    switch (HighLevelMode) {
303ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      default:
304ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        llvm_unreachable("Invalid mode.");
305ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      case UMK_Shallow:
306ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        DefaultValue = 75000;
307ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        break;
308ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks      case UMK_Deep:
309ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        DefaultValue = 150000;
310ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks        break;
311ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    }
312ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    MaxNodesPerTopLevelFunction = getOptionAsInteger("max-nodes", DefaultValue);
313ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks  }
314ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks  return MaxNodesPerTopLevelFunction.getValue();
315ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks}
316ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks
317622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenekbool AnalyzerOptions::shouldSynthesizeBodies() {
318938869941e5a01049fb301fbf82f3caa4c7efa09Ted Kremenek  return getBooleanOption("faux-bodies", true);
319a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek}
320aeca2cc3a6f486abff3fdfb4e82903cd3ca4267eJordan Rose
321aeca2cc3a6f486abff3fdfb4e82903cd3ca4267eJordan Rosebool AnalyzerOptions::shouldPrunePaths() {
322aeca2cc3a6f486abff3fdfb4e82903cd3ca4267eJordan Rose  return getBooleanOption("prune-paths", true);
323aeca2cc3a6f486abff3fdfb4e82903cd3ca4267eJordan Rose}
32402a88c3edf1aeb9580e0b6e444b30c52846a673cTed Kremenek
32502a88c3edf1aeb9580e0b6e444b30c52846a673cTed Kremenekbool AnalyzerOptions::shouldConditionalizeStaticInitializers() {
3260f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek  return getBooleanOption("cfg-conditional-static-initializers", true);
32702a88c3edf1aeb9580e0b6e444b30c52846a673cTed Kremenek}
328