AnalyzerOptions.cpp revision ce32890df08387b50a960f785da79ac5582b7f74
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 23AnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() { 24 if (UserMode == UMK_NotSet) { 25 StringRef ModeStr(Config.GetOrCreateValue("mode", "deep").getValue()); 26 UserMode = llvm::StringSwitch<UserModeKind>(ModeStr) 27 .Case("shallow", UMK_Shallow) 28 .Case("deep", UMK_Deep) 29 .Default(UMK_NotSet); 30 assert(UserMode != UMK_NotSet && "User mode is invalid."); 31 } 32 return UserMode; 33} 34 35IPAKind AnalyzerOptions::getIPAMode() { 36 if (IPAMode == IPAK_NotSet) { 37 38 // Use the User Mode to set the default IPA value. 39 // Note, we have to add the string to the Config map for the ConfigDumper 40 // checker to function properly. 41 const char *DefaultIPA = 0; 42 UserModeKind HighLevelMode = getUserMode(); 43 if (HighLevelMode == UMK_Shallow) 44 DefaultIPA = "basic-inlining"; 45 else if (HighLevelMode == UMK_Deep) 46 DefaultIPA = "dynamic-bifurcate"; 47 assert(DefaultIPA); 48 49 // Lookup the ipa configuration option, use the default from User Mode. 50 StringRef ModeStr(Config.GetOrCreateValue("ipa", DefaultIPA).getValue()); 51 IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr) 52 .Case("none", IPAK_None) 53 .Case("basic-inlining", IPAK_BasicInlining) 54 .Case("inlining", IPAK_Inlining) 55 .Case("dynamic", IPAK_DynamicDispatch) 56 .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate) 57 .Default(IPAK_NotSet); 58 assert(IPAConfig != IPAK_NotSet && "IPA Mode is invalid."); 59 60 // Set the member variable. 61 IPAMode = IPAConfig; 62 } 63 64 return IPAMode; 65} 66 67bool 68AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) { 69 if (getIPAMode() < IPAK_Inlining) 70 return false; 71 72 if (!CXXMemberInliningMode) { 73 static const char *ModeKey = "c++-inlining"; 74 75 StringRef ModeStr(Config.GetOrCreateValue(ModeKey, 76 "methods").getValue()); 77 78 CXXInlineableMemberKind &MutableMode = 79 const_cast<CXXInlineableMemberKind &>(CXXMemberInliningMode); 80 81 MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr) 82 .Case("constructors", CIMK_Constructors) 83 .Case("destructors", CIMK_Destructors) 84 .Case("none", CIMK_None) 85 .Case("methods", CIMK_MemberFunctions) 86 .Default(CXXInlineableMemberKind()); 87 88 if (!MutableMode) { 89 // FIXME: We should emit a warning here about an unknown inlining kind, 90 // but the AnalyzerOptions doesn't have access to a diagnostic engine. 91 MutableMode = CIMK_None; 92 } 93 } 94 95 return CXXMemberInliningMode >= K; 96} 97 98static StringRef toString(bool b) { return b ? "true" : "false"; } 99 100bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) { 101 // FIXME: We should emit a warning here if the value is something other than 102 // "true", "false", or the empty string (meaning the default value), 103 // but the AnalyzerOptions doesn't have access to a diagnostic engine. 104 StringRef V(Config.GetOrCreateValue(Name, toString(DefaultVal)).getValue()); 105 return llvm::StringSwitch<bool>(V) 106 .Case("true", true) 107 .Case("false", false) 108 .Default(DefaultVal); 109} 110 111bool AnalyzerOptions::getBooleanOption(llvm::Optional<bool> &V, 112 StringRef Name, 113 bool DefaultVal) { 114 if (!V.hasValue()) 115 V = getBooleanOption(Name, DefaultVal); 116 return V.getValue(); 117} 118 119bool AnalyzerOptions::includeTemporaryDtorsInCFG() { 120 return getBooleanOption(IncludeTemporaryDtorsInCFG, 121 "cfg-temporary-dtors", 122 /* Default = */ false); 123} 124 125bool AnalyzerOptions::mayInlineCXXStandardLibrary() { 126 return getBooleanOption(InlineCXXStandardLibrary, 127 "c++-stdlib-inlining", 128 /*Default=*/true); 129} 130 131bool AnalyzerOptions::mayInlineTemplateFunctions() { 132 return getBooleanOption(InlineTemplateFunctions, 133 "c++-template-inlining", 134 /*Default=*/true); 135} 136 137bool AnalyzerOptions::mayInlineObjCMethod() { 138 return getBooleanOption(ObjCInliningMode, 139 "objc-inlining", 140 /* Default = */ true); 141} 142 143bool AnalyzerOptions::shouldSuppressNullReturnPaths() { 144 return getBooleanOption(SuppressNullReturnPaths, 145 "suppress-null-return-paths", 146 /* Default = */ true); 147} 148 149bool AnalyzerOptions::shouldAvoidSuppressingNullArgumentPaths() { 150 return getBooleanOption(AvoidSuppressingNullArgumentPaths, 151 "avoid-suppressing-null-argument-paths", 152 /* Default = */ false); 153} 154 155int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) { 156 SmallString<10> StrBuf; 157 llvm::raw_svector_ostream OS(StrBuf); 158 OS << DefaultVal; 159 160 StringRef V(Config.GetOrCreateValue(Name, OS.str()).getValue()); 161 int Res = DefaultVal; 162 bool b = V.getAsInteger(10, Res); 163 assert(!b && "analyzer-config option should be numeric"); 164 (void) b; 165 return Res; 166} 167 168unsigned AnalyzerOptions::getAlwaysInlineSize() { 169 if (!AlwaysInlineSize.hasValue()) 170 AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3); 171 return AlwaysInlineSize.getValue(); 172} 173 174unsigned AnalyzerOptions::getGraphTrimInterval() { 175 if (!GraphTrimInterval.hasValue()) 176 GraphTrimInterval = getOptionAsInteger("graph-trim-interval", 1000); 177 return GraphTrimInterval.getValue(); 178} 179 180unsigned AnalyzerOptions::getMaxTimesInlineLarge() { 181 if (!MaxTimesInlineLarge.hasValue()) 182 MaxTimesInlineLarge = getOptionAsInteger("max-times-inline-large", 32); 183 return MaxTimesInlineLarge.getValue(); 184} 185 186bool AnalyzerOptions::shouldSynthesizeBodies() { 187 return getBooleanOption("faux-bodies", true); 188} 189 190bool AnalyzerOptions::shouldPrunePaths() { 191 return getBooleanOption("prune-paths", true); 192} 193