File indexing completed on 2026-05-10 08:37:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
0015 #define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
0016
0017 #include "clang/Analysis/PathDiagnostic.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0020 #include "llvm/ADT/StringMap.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include <string>
0023 #include <utility>
0024 #include <vector>
0025
0026 namespace clang {
0027
0028 namespace ento {
0029
0030 class CheckerBase;
0031
0032 }
0033
0034
0035 enum AnalysisConstraints {
0036 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
0037 #include "clang/StaticAnalyzer/Core/Analyses.def"
0038 NumConstraints
0039 };
0040
0041
0042
0043 enum AnalysisDiagClients {
0044 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
0045 #include "clang/StaticAnalyzer/Core/Analyses.def"
0046 PD_NONE,
0047 NUM_ANALYSIS_DIAG_CLIENTS
0048 };
0049
0050
0051 enum AnalysisPurgeMode {
0052 #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
0053 #include "clang/StaticAnalyzer/Core/Analyses.def"
0054 NumPurgeModes
0055 };
0056
0057
0058 enum AnalysisInliningMode {
0059 #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
0060 #include "clang/StaticAnalyzer/Core/Analyses.def"
0061 NumInliningModes
0062 };
0063
0064
0065
0066
0067
0068
0069 enum CXXInlineableMemberKind {
0070
0071
0072
0073 CIMK_None,
0074
0075
0076 CIMK_MemberFunctions,
0077
0078
0079
0080
0081
0082 CIMK_Constructors,
0083
0084
0085 CIMK_Destructors
0086 };
0087
0088
0089 enum IPAKind {
0090
0091 IPAK_None = 1,
0092
0093
0094 IPAK_BasicInlining = 2,
0095
0096
0097 IPAK_Inlining = 3,
0098
0099
0100 IPAK_DynamicDispatch = 4,
0101
0102
0103
0104 IPAK_DynamicDispatchBifurcate = 5
0105 };
0106
0107 enum class ExplorationStrategyKind {
0108 DFS,
0109 BFS,
0110 UnexploredFirst,
0111 UnexploredFirstQueue,
0112 UnexploredFirstLocationQueue,
0113 BFSBlockDFSContents,
0114 };
0115
0116
0117 enum UserModeKind {
0118
0119 UMK_Shallow = 1,
0120
0121
0122 UMK_Deep = 2
0123 };
0124
0125 enum class CTUPhase1InliningKind { None, Small, All };
0126
0127 class PositiveAnalyzerOption {
0128 public:
0129 constexpr PositiveAnalyzerOption() = default;
0130 constexpr PositiveAnalyzerOption(unsigned Value) : Value(Value) {
0131 assert(Value > 0 && "only positive values are accepted");
0132 }
0133 constexpr PositiveAnalyzerOption(const PositiveAnalyzerOption &) = default;
0134 constexpr PositiveAnalyzerOption &
0135 operator=(const PositiveAnalyzerOption &Other) {
0136 Value = Other.Value;
0137 return *this;
0138 }
0139
0140 static constexpr std::optional<PositiveAnalyzerOption> create(unsigned Val) {
0141 if (Val == 0)
0142 return std::nullopt;
0143 return PositiveAnalyzerOption{Val};
0144 }
0145 static std::optional<PositiveAnalyzerOption> create(StringRef Str) {
0146 unsigned Parsed = 0;
0147 if (Str.getAsInteger(0, Parsed))
0148 return std::nullopt;
0149 return PositiveAnalyzerOption::create(Parsed);
0150 }
0151 constexpr operator unsigned() const { return Value; }
0152
0153 private:
0154 unsigned Value = 1;
0155 };
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
0180 public:
0181 using ConfigTable = llvm::StringMap<std::string>;
0182
0183
0184
0185 static std::vector<StringRef>
0186 getRegisteredCheckers(bool IncludeExperimental = false);
0187
0188
0189
0190 static std::vector<StringRef>
0191 getRegisteredPackages(bool IncludeExperimental = false);
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 static void printFormattedEntry(llvm::raw_ostream &Out,
0211 std::pair<StringRef, StringRef> EntryDescPair,
0212 size_t InitialPad, size_t EntryWidth,
0213 size_t MinLineWidth = 0);
0214
0215
0216 std::vector<std::pair<std::string, bool>> CheckersAndPackages;
0217
0218
0219 std::vector<std::string> SilencedCheckersAndPackages;
0220
0221
0222
0223 ConfigTable Config;
0224 AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
0225 AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
0226 AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
0227
0228 std::string AnalyzeSpecificFunction;
0229
0230
0231 std::string DumpExplodedGraphTo;
0232
0233
0234
0235 std::string FullCompilerInvocation;
0236
0237
0238 unsigned maxBlockVisitOnPath;
0239
0240
0241
0242
0243
0244
0245 unsigned DisableAllCheckers : 1;
0246
0247 unsigned ShowCheckerHelp : 1;
0248 unsigned ShowCheckerHelpAlpha : 1;
0249 unsigned ShowCheckerHelpDeveloper : 1;
0250
0251 unsigned ShowCheckerOptionList : 1;
0252 unsigned ShowCheckerOptionAlphaList : 1;
0253 unsigned ShowCheckerOptionDeveloperList : 1;
0254
0255 unsigned ShowEnabledCheckerList : 1;
0256 unsigned ShowConfigOptionsList : 1;
0257 unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
0258 unsigned AnalyzeAll : 1;
0259 unsigned AnalyzerDisplayProgress : 1;
0260 unsigned AnalyzerNoteAnalysisEntryPoints : 1;
0261
0262 unsigned TrimGraph : 1;
0263 unsigned visualizeExplodedGraphWithGraphViz : 1;
0264 unsigned UnoptimizedCFG : 1;
0265 unsigned PrintStats : 1;
0266
0267
0268
0269 unsigned NoRetryExhausted : 1;
0270
0271
0272 bool AnalyzerWerror : 1;
0273
0274
0275 unsigned InlineMaxStackDepth;
0276
0277
0278 AnalysisInliningMode InliningMode = NoRedundancy;
0279
0280
0281 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
0282 SHALLOW_VAL, DEEP_VAL) \
0283 ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
0284
0285 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
0286 TYPE NAME;
0287
0288 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
0289 #undef ANALYZER_OPTION
0290 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
0291
0292 bool isUnknownAnalyzerConfig(llvm::StringRef Name) {
0293 static std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = []() {
0294
0295 std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
0296 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
0297 SHALLOW_VAL, DEEP_VAL) \
0298 ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
0299
0300 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
0301 llvm::StringLiteral(CMDFLAG),
0302
0303 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
0304 #undef ANALYZER_OPTION
0305 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
0306 };
0307
0308 llvm::sort(AnalyzerConfigCmdFlags);
0309 return AnalyzerConfigCmdFlags;
0310 }();
0311
0312 return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
0313 AnalyzerConfigCmdFlags.end(), Name);
0314 }
0315
0316 AnalyzerOptions()
0317 : DisableAllCheckers(false), ShowCheckerHelp(false),
0318 ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
0319 ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
0320 ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
0321 ShowConfigOptionsList(false),
0322 ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
0323 AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
0324 TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
0325 UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
0326 AnalyzerWerror(false) {}
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
0344 bool SearchInParents = false) const;
0345
0346 bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
0347 bool SearchInParents = false) const;
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363 int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
0364 bool SearchInParents = false) const;
0365
0366 int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
0367 bool SearchInParents = false) const;
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
0384 bool SearchInParents = false) const;
0385
0386 StringRef getCheckerStringOption(const ento::CheckerBase *C,
0387 StringRef OptionName,
0388 bool SearchInParents = false) const;
0389
0390 ExplorationStrategyKind getExplorationStrategy() const;
0391 CTUPhase1InliningKind getCTUPhase1Inlining() const;
0392
0393
0394 IPAKind getIPAMode() const;
0395
0396
0397
0398
0399
0400
0401
0402 bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
0403
0404 ento::PathDiagnosticConsumerOptions getDiagOpts() const {
0405 return {FullCompilerInvocation,
0406 ShouldDisplayMacroExpansions,
0407 ShouldSerializeStats,
0408
0409
0410
0411
0412 ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename,
0413 AnalyzerWerror,
0414 ShouldApplyFixIts,
0415 ShouldDisplayCheckerNameForText};
0416 }
0417 };
0418
0419 using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 inline std::vector<StringRef>
0430 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
0431 static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
0432 #define GET_CHECKERS
0433 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
0434 llvm::StringLiteral(FULLNAME),
0435 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
0436 #undef CHECKER
0437 #undef GET_CHECKERS
0438 };
0439 std::vector<StringRef> Checkers;
0440 for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
0441 if (!CheckerName.starts_with("debug.") &&
0442 (IncludeExperimental || !CheckerName.starts_with("alpha.")))
0443 Checkers.push_back(CheckerName);
0444 }
0445 return Checkers;
0446 }
0447
0448 inline std::vector<StringRef>
0449 AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
0450 static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
0451 #define GET_PACKAGES
0452 #define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
0453 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
0454 #undef PACKAGE
0455 #undef GET_PACKAGES
0456 };
0457 std::vector<StringRef> Packages;
0458 for (StringRef PackageName : StaticAnalyzerPackageNames) {
0459 if (PackageName != "debug" &&
0460 (IncludeExperimental || PackageName != "alpha"))
0461 Packages.push_back(PackageName);
0462 }
0463 return Packages;
0464 }
0465
0466 }
0467
0468 #endif