AnalyzerOptions.cpp revision 6bbe1442a5f3f5f761582a9005e9edf1d49c4da2
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//===-- AnalyzerOptions.cpp - Analysis Engine Options -----------*- C++ -*-===//
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//                     The LLVM Compiler Infrastructure
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This file is distributed under the University of Illinois Open Source
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner// License. See LICENSE.TXT for details.
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//===----------------------------------------------------------------------===//
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner// This file contains special accessors for analyzer configuration options
115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner// with string representations.
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//===----------------------------------------------------------------------===//
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "llvm/ADT/SmallString.h"
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "llvm/ADT/StringSwitch.h"
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "llvm/Support/raw_ostream.h"
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerusing namespace clang;
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectusing namespace llvm;
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (UserMode == UMK_NotSet) {
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    StringRef ModeStr(Config.GetOrCreateValue("mode", "deep").getValue());
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    UserMode = llvm::StringSwitch<UserModeKind>(ModeStr)
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("shallow", UMK_Shallow)
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("deep", UMK_Deep)
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Default(UMK_NotSet);
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(UserMode != UMK_NotSet && "User mode is invalid.");
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return UserMode;
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectIPAKind AnalyzerOptions::getIPAMode() {
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (IPAMode == IPAK_NotSet) {
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    // Use the User Mode to set the default IPA value.
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    // Note, we have to add the string to the Config map for the ConfigDumper
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    // checker to function properly.
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *DefaultIPA = 0;
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    UserModeKind HighLevelMode = getUserMode();
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (HighLevelMode == UMK_Shallow)
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      DefaultIPA = "basic-inlining";
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (HighLevelMode == UMK_Deep)
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner      DefaultIPA = "dynamic-bifurcate";
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(DefaultIPA);
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Lookup the ipa configuration option, use the default from User Mode.
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    StringRef ModeStr(Config.GetOrCreateValue("ipa", DefaultIPA).getValue());
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Case("none", IPAK_None)
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Case("basic-inlining", IPAK_BasicInlining)
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Case("inlining", IPAK_Inlining)
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Case("dynamic", IPAK_DynamicDispatch)
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            .Default(IPAK_NotSet);
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(IPAConfig != IPAK_NotSet && "IPA Mode is invalid.");
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Set the member variable.
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IPAMode = IPAConfig;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return IPAMode;
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) {
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (getIPAMode() < IPAK_Inlining)
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return false;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (!CXXMemberInliningMode) {
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const char *ModeKey = "c++-inlining";
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    StringRef ModeStr(Config.GetOrCreateValue(ModeKey,
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                              "methods").getValue());
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CXXInlineableMemberKind &MutableMode =
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("constructors", CIMK_Constructors)
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("destructors", CIMK_Destructors)
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("none", CIMK_None)
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("methods", CIMK_MemberFunctions)
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Default(CXXInlineableMemberKind());
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!MutableMode) {
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      // FIXME: We should emit a warning here about an unknown inlining kind,
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      // but the AnalyzerOptions doesn't have access to a diagnostic engine.
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      MutableMode = CIMK_None;
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return CXXMemberInliningMode >= K;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic StringRef toString(bool b) { return b ? "true" : "false"; }
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) {
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  // FIXME: We should emit a warning here if the value is something other than
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  // "true", "false", or the empty string (meaning the default value),
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  // but the AnalyzerOptions doesn't have access to a diagnostic engine.
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  StringRef V(Config.GetOrCreateValue(Name, toString(DefaultVal)).getValue());
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return llvm::StringSwitch<bool>(V)
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("true", true)
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Case("false", false)
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      .Default(DefaultVal);
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::getBooleanOption(llvm::Optional<bool> &V,
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                       StringRef Name,
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                       bool DefaultVal) {
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (!V.hasValue())
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    V = getBooleanOption(Name, DefaultVal);
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return V.getValue();
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::includeTemporaryDtorsInCFG() {
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption(IncludeTemporaryDtorsInCFG,
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          "cfg-temporary-dtors",
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                          /* Default = */ false);
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::mayInlineCXXStandardLibrary() {
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption(InlineCXXStandardLibrary,
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          "c++-stdlib-inlining",
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          /*Default=*/true);
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::mayInlineTemplateFunctions() {
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption(InlineTemplateFunctions,
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          "c++-template-inlining",
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          /*Default=*/true);
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::mayInlineObjCMethod() {
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption(ObjCInliningMode,
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          "objc-inlining",
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          /* Default = */ true);
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::shouldSuppressNullReturnPaths() {
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption(SuppressNullReturnPaths,
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          "suppress-null-return-paths",
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          /* Default = */ true);
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerbool AnalyzerOptions::shouldAvoidSuppressingNullArgumentPaths() {
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return getBooleanOption(AvoidSuppressingNullArgumentPaths,
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                          "avoid-suppressing-null-argument-paths",
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                          /* Default = */ false);
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  SmallString<10> StrBuf;
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  llvm::raw_svector_ostream OS(StrBuf);
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  OS << DefaultVal;
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  StringRef V(Config.GetOrCreateValue(Name, OS.str()).getValue());
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  int Res = DefaultVal;
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  bool b = V.getAsInteger(10, Res);
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  assert(!b && "analyzer-config option should be numeric");
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  (void) b;
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return Res;
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned AnalyzerOptions::getAlwaysInlineSize() {
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!AlwaysInlineSize.hasValue())
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return AlwaysInlineSize.getValue();
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned AnalyzerOptions::getMaxInlinableSize() {
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!MaxInlinableSize.hasValue())
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    MaxInlinableSize = getOptionAsInteger("max-inlinable-size", 50);
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return MaxInlinableSize.getValue();
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned AnalyzerOptions::getGraphTrimInterval() {
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!GraphTrimInterval.hasValue())
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000);
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return GraphTrimInterval.getValue();
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned AnalyzerOptions::getMaxTimesInlineLarge() {
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (!MaxTimesInlineLarge.hasValue())
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    MaxTimesInlineLarge = getOptionAsInteger("max-times-inline-large", 32);
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return MaxTimesInlineLarge.getValue();
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerbool AnalyzerOptions::shouldSynthesizeBodies() {
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption("faux-bodies", true);
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbool AnalyzerOptions::shouldPrunePaths() {
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return getBooleanOption("prune-paths", true);
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project