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