AnalyzerOptions.h revision 360784
1238384Sjkim//===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===//
2238384Sjkim//
3238384Sjkim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4238384Sjkim// See https://llvm.org/LICENSE.txt for license information.
5238384Sjkim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6238384Sjkim//
7238384Sjkim//===----------------------------------------------------------------------===//
8238384Sjkim//
9238384Sjkim// This header defines various options for the static analyzer that are set
10238384Sjkim// by the frontend and are consulted throughout the analyzer.
11238384Sjkim//
12238384Sjkim//===----------------------------------------------------------------------===//
13238384Sjkim
14238384Sjkim#ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
15238384Sjkim#define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
16238384Sjkim
17238384Sjkim#include "clang/Basic/LLVM.h"
18238384Sjkim#include "llvm/ADT/IntrusiveRefCntPtr.h"
19238384Sjkim#include "llvm/ADT/Optional.h"
20238384Sjkim#include "llvm/ADT/StringMap.h"
21238384Sjkim#include "llvm/ADT/StringRef.h"
22238384Sjkim#include "llvm/ADT/StringSwitch.h"
23238384Sjkim#include <string>
24238384Sjkim#include <utility>
25238384Sjkim#include <vector>
26238384Sjkim
27238384Sjkimnamespace clang {
28238384Sjkim
29238384Sjkimnamespace ento {
30238384Sjkim
31246772Sjkimclass CheckerBase;
32246772Sjkim
33238384Sjkim} // namespace ento
34238384Sjkim
35238384Sjkim/// Analysis - Set of available source code analyses.
36238384Sjkimenum Analyses {
37238384Sjkim#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
38238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
39238384SjkimNumAnalyses
40238384Sjkim};
41238384Sjkim
42238384Sjkim/// AnalysisStores - Set of available analysis store models.
43238384Sjkimenum AnalysisStores {
44238384Sjkim#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
45238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
46238384SjkimNumStores
47238384Sjkim};
48238384Sjkim
49238384Sjkim/// AnalysisConstraints - Set of available constraint models.
50238384Sjkimenum AnalysisConstraints {
51238384Sjkim#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
52238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
53238384SjkimNumConstraints
54238384Sjkim};
55238384Sjkim
56238384Sjkim/// AnalysisDiagClients - Set of available diagnostic clients for rendering
57238384Sjkim///  analysis results.
58238384Sjkimenum AnalysisDiagClients {
59238384Sjkim#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
60238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
61238384SjkimPD_NONE,
62238384SjkimNUM_ANALYSIS_DIAG_CLIENTS
63238384Sjkim};
64238384Sjkim
65238384Sjkim/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
66238384Sjkimenum AnalysisPurgeMode {
67238384Sjkim#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
68238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
69238384SjkimNumPurgeModes
70238384Sjkim};
71238384Sjkim
72238384Sjkim/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
73238384Sjkimenum AnalysisInliningMode {
74238384Sjkim#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
75238384Sjkim#include "clang/StaticAnalyzer/Core/Analyses.def"
76238384SjkimNumInliningModes
77238384Sjkim};
78238384Sjkim
79238384Sjkim/// Describes the different kinds of C++ member functions which can be
80238384Sjkim/// considered for inlining by the analyzer.
81238384Sjkim///
82238384Sjkim/// These options are cumulative; enabling one kind of member function will
83238384Sjkim/// enable all kinds with lower enum values.
84238384Sjkimenum CXXInlineableMemberKind {
85238384Sjkim  // Uninitialized = 0,
86238384Sjkim
87238384Sjkim  /// A dummy mode in which no C++ inlining is enabled.
88238384Sjkim  CIMK_None,
89238384Sjkim
90238384Sjkim  /// Refers to regular member function and operator calls.
91238384Sjkim  CIMK_MemberFunctions,
92238384Sjkim
93238384Sjkim  /// Refers to constructors (implicit or explicit).
94238384Sjkim  ///
95238384Sjkim  /// Note that a constructor will not be inlined if the corresponding
96238384Sjkim  /// destructor is non-trivial.
97238384Sjkim  CIMK_Constructors,
98238384Sjkim
99238384Sjkim  /// Refers to destructors (implicit or explicit).
100238384Sjkim  CIMK_Destructors
101238384Sjkim};
102238384Sjkim
103238384Sjkim/// Describes the different modes of inter-procedural analysis.
104238384Sjkimenum IPAKind {
105238384Sjkim  /// Perform only intra-procedural analysis.
106238384Sjkim  IPAK_None = 1,
107238384Sjkim
108238384Sjkim  /// Inline C functions and blocks when their definitions are available.
109238384Sjkim  IPAK_BasicInlining = 2,
110238384Sjkim
111238384Sjkim  /// Inline callees(C, C++, ObjC) when their definitions are available.
112238384Sjkim  IPAK_Inlining = 3,
113238384Sjkim
114238384Sjkim  /// Enable inlining of dynamically dispatched methods.
115238384Sjkim  IPAK_DynamicDispatch = 4,
116238384Sjkim
117238384Sjkim  /// Enable inlining of dynamically dispatched methods, bifurcate paths when
118238384Sjkim  /// exact type info is unavailable.
119238384Sjkim  IPAK_DynamicDispatchBifurcate = 5
120238384Sjkim};
121238384Sjkim
122238384Sjkimenum class ExplorationStrategyKind {
123238384Sjkim  DFS,
124238384Sjkim  BFS,
125238384Sjkim  UnexploredFirst,
126238384Sjkim  UnexploredFirstQueue,
127238384Sjkim  UnexploredFirstLocationQueue,
128238384Sjkim  BFSBlockDFSContents,
129238384Sjkim};
130238384Sjkim
131238384Sjkim/// Describes the kinds for high-level analyzer mode.
132238384Sjkimenum UserModeKind {
133238384Sjkim  /// Perform shallow but fast analyzes.
134238384Sjkim  UMK_Shallow = 1,
135238384Sjkim
136238384Sjkim  /// Perform deep analyzes.
137238384Sjkim  UMK_Deep = 2
138238384Sjkim};
139238384Sjkim
140238384Sjkim/// Stores options for the analyzer from the command line.
141238384Sjkim///
142238384Sjkim/// Some options are frontend flags (e.g.: -analyzer-output), but some are
143238384Sjkim/// analyzer configuration options, which are preceded by -analyzer-config
144238384Sjkim/// (e.g.: -analyzer-config notes-as-events=true).
145238384Sjkim///
146238384Sjkim/// If you'd like to add a new frontend flag, add it to
147238384Sjkim/// include/clang/Driver/CC1Options.td, add a new field to store the value of
148238384Sjkim/// that flag in this class, and initialize it in
149238384Sjkim/// lib/Frontend/CompilerInvocation.cpp.
150238384Sjkim///
151238384Sjkim/// If you'd like to add a new non-checker configuration, register it in
152238384Sjkim/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
153238384Sjkim/// top of the file for documentation.
154238384Sjkim///
155238384Sjkim/// If you'd like to add a new checker option, call getChecker*Option()
156238384Sjkim/// whenever.
157238384Sjkim///
158238384Sjkim/// Some of the options are controlled by raw frontend flags for no good reason,
159238384Sjkim/// and should be eventually converted into -analyzer-config flags. New analyzer
160238384Sjkim/// options should not be implemented as frontend flags. Frontend flags still
161238384Sjkim/// make sense for things that do not affect the actual analysis.
162238384Sjkimclass AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
163238384Sjkimpublic:
164238384Sjkim  using ConfigTable = llvm::StringMap<std::string>;
165238384Sjkim
166238384Sjkim  /// Retrieves the list of checkers generated from Checkers.td. This doesn't
167238384Sjkim  /// contain statically linked but non-generated checkers and plugin checkers!
168238384Sjkim  static std::vector<StringRef>
169238384Sjkim  getRegisteredCheckers(bool IncludeExperimental = false);
170238384Sjkim
171238384Sjkim  /// Retrieves the list of packages generated from Checkers.td. This doesn't
172238384Sjkim  /// contain statically linked but non-generated packages and plugin packages!
173238384Sjkim  static std::vector<StringRef>
174238384Sjkim  getRegisteredPackages(bool IncludeExperimental = false);
175238384Sjkim
176238384Sjkim  /// Convenience function for printing options or checkers and their
177238384Sjkim  /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
178238384Sjkim  /// breaks are introduced for the description.
179238384Sjkim  ///
180238384Sjkim  /// Format, depending whether the option name's length is less then
181238384Sjkim  /// \p OptionWidth:
182238384Sjkim  ///
183238384Sjkim  ///   <padding>EntryName<padding>Description
184238384Sjkim  ///   <---------padding--------->Description
185238384Sjkim  ///   <---------padding--------->Description
186238384Sjkim  ///
187238384Sjkim  ///   <padding>VeryVeryLongOptionName
188238384Sjkim  ///   <---------padding--------->Description
189238384Sjkim  ///   <---------padding--------->Description
190238384Sjkim  ///   ^~~~~~~~ InitialPad
191238384Sjkim  ///   ^~~~~~~~~~~~~~~~~~~~~~~~~~ EntryWidth
192238384Sjkim  ///   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth
193238384Sjkim  static void printFormattedEntry(
194238384Sjkim      llvm::raw_ostream &Out,
195238384Sjkim      std::pair<StringRef, StringRef> EntryDescPair,
196238384Sjkim      size_t EntryWidth, size_t InitialPad, size_t MinLineWidth = 0);
197238384Sjkim
198238384Sjkim  /// Pairs of checker/package name and enable/disable.
199238384Sjkim  std::vector<std::pair<std::string, bool>> CheckersAndPackages;
200238384Sjkim
201238384Sjkim  /// Vector of checker/package names which will not emit warnings.
202238384Sjkim  std::vector<std::string> SilencedCheckersAndPackages;
203238384Sjkim
204238384Sjkim  /// A key-value table of use-specified configuration values.
205238384Sjkim  // TODO: This shouldn't be public.
206238384Sjkim  ConfigTable Config;
207238384Sjkim  AnalysisStores AnalysisStoreOpt = RegionStoreModel;
208238384Sjkim  AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
209238384Sjkim  AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
210238384Sjkim  AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
211238384Sjkim
212238384Sjkim  std::string AnalyzeSpecificFunction;
213238384Sjkim
214238384Sjkim  /// File path to which the exploded graph should be dumped.
215238384Sjkim  std::string DumpExplodedGraphTo;
216238384Sjkim
217238384Sjkim  /// Store full compiler invocation for reproducible instructions in the
218238384Sjkim  /// generated report.
219238384Sjkim  std::string FullCompilerInvocation;
220238384Sjkim
221238384Sjkim  /// The maximum number of times the analyzer visits a block.
222238384Sjkim  unsigned maxBlockVisitOnPath;
223238384Sjkim
224238384Sjkim  /// Disable all analyzer checkers.
225238384Sjkim  ///
226238384Sjkim  /// This flag allows one to disable analyzer checkers on the code processed by
227238384Sjkim  /// the given analysis consumer. Note, the code will get parsed and the
228238384Sjkim  /// command-line options will get checked.
229238384Sjkim  unsigned DisableAllCheckers : 1;
230238384Sjkim
231238384Sjkim  unsigned ShowCheckerHelp : 1;
232238384Sjkim  unsigned ShowCheckerHelpAlpha : 1;
233238384Sjkim  unsigned ShowCheckerHelpDeveloper : 1;
234238384Sjkim
235238384Sjkim  unsigned ShowCheckerOptionList : 1;
236238384Sjkim  unsigned ShowCheckerOptionAlphaList : 1;
237238384Sjkim  unsigned ShowCheckerOptionDeveloperList : 1;
238238384Sjkim
239238384Sjkim  unsigned ShowEnabledCheckerList : 1;
240238384Sjkim  unsigned ShowConfigOptionsList : 1;
241238384Sjkim  unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
242238384Sjkim  unsigned AnalyzeAll : 1;
243238384Sjkim  unsigned AnalyzerDisplayProgress : 1;
244238384Sjkim  unsigned AnalyzeNestedBlocks : 1;
245238384Sjkim
246238384Sjkim  unsigned eagerlyAssumeBinOpBifurcation : 1;
247238384Sjkim
248238384Sjkim  unsigned TrimGraph : 1;
249238384Sjkim  unsigned visualizeExplodedGraphWithGraphViz : 1;
250238384Sjkim  unsigned UnoptimizedCFG : 1;
251238384Sjkim  unsigned PrintStats : 1;
252238384Sjkim
253238384Sjkim  /// Do not re-analyze paths leading to exhausted nodes with a different
254238384Sjkim  /// strategy. We get better code coverage when retry is enabled.
255238384Sjkim  unsigned NoRetryExhausted : 1;
256238384Sjkim
257238384Sjkim  /// Emit analyzer warnings as errors.
258238384Sjkim  unsigned AnalyzerWerror : 1;
259238384Sjkim
260238384Sjkim  /// The inlining stack depth limit.
261238384Sjkim  // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
262238384Sjkim  unsigned InlineMaxStackDepth = 5;
263238384Sjkim
264238384Sjkim  /// The mode of function selection used during inlining.
265238384Sjkim  AnalysisInliningMode InliningMode = NoRedundancy;
266238384Sjkim
267238384Sjkim  // Create a field for each -analyzer-config option.
268238384Sjkim#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
269238384Sjkim                                             SHALLOW_VAL, DEEP_VAL)            \
270238384Sjkim  ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
271238384Sjkim
272238384Sjkim#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
273238384Sjkim  TYPE NAME;
274238384Sjkim
275238384Sjkim#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
276238384Sjkim#undef ANALYZER_OPTION
277238384Sjkim#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
278238384Sjkim
279238384Sjkim  // Create an array of all -analyzer-config command line options. Sort it in
280238384Sjkim  // the constructor.
281238384Sjkim  std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
282238384Sjkim#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
283238384Sjkim                                             SHALLOW_VAL, DEEP_VAL)            \
284238384Sjkim  ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
285238384Sjkim
286238384Sjkim#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
287238384Sjkim  llvm::StringLiteral(CMDFLAG),
288238384Sjkim
289238384Sjkim#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
290238384Sjkim#undef ANALYZER_OPTION
291238384Sjkim#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
292238384Sjkim  };
293238384Sjkim
294238384Sjkim  bool isUnknownAnalyzerConfig(StringRef Name) const {
295238384Sjkim
296238384Sjkim    assert(std::is_sorted(AnalyzerConfigCmdFlags.begin(),
297238384Sjkim                          AnalyzerConfigCmdFlags.end()));
298238384Sjkim
299238384Sjkim    return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
300238384Sjkim                               AnalyzerConfigCmdFlags.end(), Name);
301238384Sjkim  }
302238384Sjkim
303238384Sjkim  AnalyzerOptions()
304238384Sjkim      : DisableAllCheckers(false), ShowCheckerHelp(false),
305238384Sjkim        ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
306238384Sjkim        ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
307238384Sjkim        ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
308238384Sjkim        ShowConfigOptionsList(false), AnalyzeAll(false),
309238384Sjkim        AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
310238384Sjkim        eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
311238384Sjkim        visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
312238384Sjkim        PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
313238384Sjkim    llvm::sort(AnalyzerConfigCmdFlags);
314238384Sjkim  }
315238384Sjkim
316238384Sjkim  /// Interprets an option's string value as a boolean. The "true" string is
317238384Sjkim  /// interpreted as true and the "false" string is interpreted as false.
318238384Sjkim  ///
319238384Sjkim  /// If an option value is not provided, returns the given \p DefaultVal.
320238384Sjkim  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
321238384Sjkim  /// this from the checker object's field \c Name, or through \c
322238384Sjkim  /// CheckerManager::getCurrentCheckerName within the checker's registry
323238384Sjkim  /// function.
324238384Sjkim  /// Checker options are retrieved in the following format:
325238384Sjkim  /// `-analyzer-config CheckerName:OptionName=Value.
326238384Sjkim  /// @param [in] OptionName Name for option to retrieve.
327238384Sjkim  /// @param [in] SearchInParents If set to true and the searched option was not
328238384Sjkim  /// specified for the given checker the options for the parent packages will
329238384Sjkim  /// be searched as well. The inner packages take precedence over the outer
330238384Sjkim  /// ones.
331238384Sjkim  bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
332238384Sjkim                               bool SearchInParents = false) const;
333238384Sjkim
334238384Sjkim  bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
335238384Sjkim                               bool SearchInParents = false) const;
336238384Sjkim
337238384Sjkim  /// Interprets an option's string value as an integer value.
338238384Sjkim  ///
339238384Sjkim  /// If an option value is not provided, returns the given \p DefaultVal.
340238384Sjkim  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
341238384Sjkim  /// this from the checker object's field \c Name, or through \c
342238384Sjkim  /// CheckerManager::getCurrentCheckerName within the checker's registry
343238384Sjkim  /// function.
344238384Sjkim  /// Checker options are retrieved in the following format:
345238384Sjkim  /// `-analyzer-config CheckerName:OptionName=Value.
346238384Sjkim  /// @param [in] OptionName Name for option to retrieve.
347238384Sjkim  /// @param [in] SearchInParents If set to true and the searched option was not
348238384Sjkim  /// specified for the given checker the options for the parent packages will
349238384Sjkim  /// be searched as well. The inner packages take precedence over the outer
350238384Sjkim  /// ones.
351238384Sjkim  int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
352238384Sjkim                              bool SearchInParents = false) const;
353238384Sjkim
354238384Sjkim  int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
355238384Sjkim                              bool SearchInParents = false) const;
356238384Sjkim
357238384Sjkim  /// Query an option's string value.
358238384Sjkim  ///
359238384Sjkim  /// If an option value is not provided, returns the given \p DefaultVal.
360238384Sjkim  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
361238384Sjkim  /// this from the checker object's field \c Name, or through \c
362238384Sjkim  /// CheckerManager::getCurrentCheckerName within the checker's registry
363238384Sjkim  /// function.
364238384Sjkim  /// Checker options are retrieved in the following format:
365238384Sjkim  /// `-analyzer-config CheckerName:OptionName=Value.
366238384Sjkim  /// @param [in] OptionName Name for option to retrieve.
367238384Sjkim  /// @param [in] SearchInParents If set to true and the searched option was not
368238384Sjkim  /// specified for the given checker the options for the parent packages will
369238384Sjkim  /// be searched as well. The inner packages take precedence over the outer
370238384Sjkim  /// ones.
371238384Sjkim  StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
372238384Sjkim                                   bool SearchInParents = false) const;
373238384Sjkim
374238384Sjkim  StringRef getCheckerStringOption(const ento::CheckerBase *C,
375238384Sjkim                                   StringRef OptionName,
376238384Sjkim                                   bool SearchInParents = false) const;
377238384Sjkim
378238384Sjkim  /// Retrieves and sets the UserMode. This is a high-level option,
379238384Sjkim  /// which is used to set other low-level options. It is not accessible
380238384Sjkim  /// outside of AnalyzerOptions.
381238384Sjkim  UserModeKind getUserMode() const;
382238384Sjkim
383238384Sjkim  ExplorationStrategyKind getExplorationStrategy() const;
384238384Sjkim
385238384Sjkim  /// Returns the inter-procedural analysis mode.
386238384Sjkim  IPAKind getIPAMode() const;
387238384Sjkim
388238384Sjkim  /// Returns the option controlling which C++ member functions will be
389238384Sjkim  /// considered for inlining.
390238384Sjkim  ///
391238384Sjkim  /// This is controlled by the 'c++-inlining' config option.
392238384Sjkim  ///
393238384Sjkim  /// \sa CXXMemberInliningMode
394238384Sjkim  bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
395238384Sjkim};
396238384Sjkim
397238384Sjkimusing AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
398238384Sjkim
399238384Sjkim//===----------------------------------------------------------------------===//
400238384Sjkim// We'll use AnalyzerOptions in the frontend, but we can't link the frontend
401238384Sjkim// with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on
402238384Sjkim// clangFrontend.
403238384Sjkim//
404238384Sjkim// For this reason, implement some methods in this header file.
405238384Sjkim//===----------------------------------------------------------------------===//
406238384Sjkim
407238384Sjkiminline UserModeKind AnalyzerOptions::getUserMode() const {
408238384Sjkim  auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
409238384Sjkim    .Case("shallow", UMK_Shallow)
410238384Sjkim    .Case("deep", UMK_Deep)
411238384Sjkim    .Default(None);
412238384Sjkim  assert(K.hasValue() && "User mode is invalid.");
413238384Sjkim  return K.getValue();
414238384Sjkim}
415238384Sjkim
416238384Sjkiminline std::vector<StringRef>
417238384SjkimAnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
418238384Sjkim  static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
419238384Sjkim#define GET_CHECKERS
420238384Sjkim#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \
421238384Sjkim  llvm::StringLiteral(FULLNAME),
422238384Sjkim#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
423238384Sjkim#undef CHECKER
424238384Sjkim#undef GET_CHECKERS
425238384Sjkim  };
426238384Sjkim  std::vector<StringRef> Checkers;
427238384Sjkim  for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
428238384Sjkim    if (!CheckerName.startswith("debug.") &&
429238384Sjkim        (IncludeExperimental || !CheckerName.startswith("alpha.")))
430238384Sjkim      Checkers.push_back(CheckerName);
431238384Sjkim  }
432238384Sjkim  return Checkers;
433238384Sjkim}
434238384Sjkim
435238384Sjkiminline std::vector<StringRef>
436238384SjkimAnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
437238384Sjkim  static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
438238384Sjkim#define GET_PACKAGES
439238384Sjkim#define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
440238384Sjkim#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
441238384Sjkim#undef PACKAGE
442238384Sjkim#undef GET_PACKAGES
443238384Sjkim  };
444238384Sjkim  std::vector<StringRef> Packages;
445238384Sjkim  for (StringRef PackageName : StaticAnalyzerPackageNames) {
446238384Sjkim    if (PackageName != "debug" &&
447238384Sjkim        (IncludeExperimental || PackageName != "alpha"))
448238384Sjkim      Packages.push_back(PackageName);
449238384Sjkim  }
450238384Sjkim  return Packages;
451238384Sjkim}
452238384Sjkim
453238384Sjkim} // namespace clang
454238384Sjkim
455238384Sjkim#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
456238384Sjkim