- //===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This header defines various options for the static analyzer that are set 
- // by the frontend and are consulted throughout the analyzer. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H 
- #define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H 
-   
- #include "clang/Analysis/PathDiagnostic.h" 
- #include "clang/Basic/LLVM.h" 
- #include "llvm/ADT/IntrusiveRefCntPtr.h" 
- #include "llvm/ADT/StringMap.h" 
- #include "llvm/ADT/StringRef.h" 
- #include <string> 
- #include <utility> 
- #include <vector> 
-   
- namespace clang { 
-   
- namespace ento { 
-   
- class CheckerBase; 
-   
- } // namespace ento 
-   
- /// AnalysisConstraints - Set of available constraint models. 
- enum AnalysisConstraints { 
- #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, 
- #include "clang/StaticAnalyzer/Core/Analyses.def" 
- NumConstraints 
- }; 
-   
- /// AnalysisDiagClients - Set of available diagnostic clients for rendering 
- ///  analysis results. 
- enum AnalysisDiagClients { 
- #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, 
- #include "clang/StaticAnalyzer/Core/Analyses.def" 
- PD_NONE, 
- NUM_ANALYSIS_DIAG_CLIENTS 
- }; 
-   
- /// AnalysisPurgeModes - Set of available strategies for dead symbol removal. 
- enum AnalysisPurgeMode { 
- #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME, 
- #include "clang/StaticAnalyzer/Core/Analyses.def" 
- NumPurgeModes 
- }; 
-   
- /// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics. 
- enum AnalysisInliningMode { 
- #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME, 
- #include "clang/StaticAnalyzer/Core/Analyses.def" 
- NumInliningModes 
- }; 
-   
- /// Describes the different kinds of C++ member functions which can be 
- /// considered for inlining by the analyzer. 
- /// 
- /// These options are cumulative; enabling one kind of member function will 
- /// enable all kinds with lower enum values. 
- enum CXXInlineableMemberKind { 
-   // Uninitialized = 0, 
-   
-   /// A dummy mode in which no C++ inlining is enabled. 
-   CIMK_None, 
-   
-   /// Refers to regular member function and operator calls. 
-   CIMK_MemberFunctions, 
-   
-   /// Refers to constructors (implicit or explicit). 
-   /// 
-   /// Note that a constructor will not be inlined if the corresponding 
-   /// destructor is non-trivial. 
-   CIMK_Constructors, 
-   
-   /// Refers to destructors (implicit or explicit). 
-   CIMK_Destructors 
- }; 
-   
- /// Describes the different modes of inter-procedural analysis. 
- enum IPAKind { 
-   /// Perform only intra-procedural analysis. 
-   IPAK_None = 1, 
-   
-   /// Inline C functions and blocks when their definitions are available. 
-   IPAK_BasicInlining = 2, 
-   
-   /// Inline callees(C, C++, ObjC) when their definitions are available. 
-   IPAK_Inlining = 3, 
-   
-   /// Enable inlining of dynamically dispatched methods. 
-   IPAK_DynamicDispatch = 4, 
-   
-   /// Enable inlining of dynamically dispatched methods, bifurcate paths when 
-   /// exact type info is unavailable. 
-   IPAK_DynamicDispatchBifurcate = 5 
- }; 
-   
- enum class ExplorationStrategyKind { 
-   DFS, 
-   BFS, 
-   UnexploredFirst, 
-   UnexploredFirstQueue, 
-   UnexploredFirstLocationQueue, 
-   BFSBlockDFSContents, 
- }; 
-   
- /// Describes the kinds for high-level analyzer mode. 
- enum UserModeKind { 
-   /// Perform shallow but fast analyzes. 
-   UMK_Shallow = 1, 
-   
-   /// Perform deep analyzes. 
-   UMK_Deep = 2 
- }; 
-   
- enum class CTUPhase1InliningKind { None, Small, All }; 
-   
- /// Stores options for the analyzer from the command line. 
- /// 
- /// Some options are frontend flags (e.g.: -analyzer-output), but some are 
- /// analyzer configuration options, which are preceded by -analyzer-config 
- /// (e.g.: -analyzer-config notes-as-events=true). 
- /// 
- /// If you'd like to add a new frontend flag, add it to 
- /// include/clang/Driver/CC1Options.td, add a new field to store the value of 
- /// that flag in this class, and initialize it in 
- /// lib/Frontend/CompilerInvocation.cpp. 
- /// 
- /// If you'd like to add a new non-checker configuration, register it in 
- /// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the 
- /// top of the file for documentation. 
- /// 
- /// If you'd like to add a new checker option, call getChecker*Option() 
- /// whenever. 
- /// 
- /// Some of the options are controlled by raw frontend flags for no good reason, 
- /// and should be eventually converted into -analyzer-config flags. New analyzer 
- /// options should not be implemented as frontend flags. Frontend flags still 
- /// make sense for things that do not affect the actual analysis. 
- class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> { 
- public: 
-   using ConfigTable = llvm::StringMap<std::string>; 
-   
-   /// Retrieves the list of checkers generated from Checkers.td. This doesn't 
-   /// contain statically linked but non-generated checkers and plugin checkers! 
-   static std::vector<StringRef> 
-   getRegisteredCheckers(bool IncludeExperimental = false); 
-   
-   /// Retrieves the list of packages generated from Checkers.td. This doesn't 
-   /// contain statically linked but non-generated packages and plugin packages! 
-   static std::vector<StringRef> 
-   getRegisteredPackages(bool IncludeExperimental = false); 
-   
-   /// Convenience function for printing options or checkers and their 
-   /// description in a formatted manner. If \p MinLineWidth is set to 0, no line 
-   /// breaks are introduced for the description. 
-   /// 
-   /// Format, depending whether the option name's length is less than 
-   /// \p EntryWidth: 
-   /// 
-   ///   <padding>EntryName<padding>Description 
-   ///   <---------padding--------->Description 
-   ///   <---------padding--------->Description 
-   /// 
-   ///   <padding>VeryVeryLongEntryName 
-   ///   <---------padding--------->Description 
-   ///   <---------padding--------->Description 
-   ///   ^~~~~~~~~InitialPad 
-   ///            ^~~~~~~~~~~~~~~~~~EntryWidth 
-   ///   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth 
-   static void printFormattedEntry(llvm::raw_ostream &Out, 
-                                   std::pair<StringRef, StringRef> EntryDescPair, 
-                                   size_t InitialPad, size_t EntryWidth, 
-                                   size_t MinLineWidth = 0); 
-   
-   /// Pairs of checker/package name and enable/disable. 
-   std::vector<std::pair<std::string, bool>> CheckersAndPackages; 
-   
-   /// Vector of checker/package names which will not emit warnings. 
-   std::vector<std::string> SilencedCheckersAndPackages; 
-   
-   /// A key-value table of use-specified configuration values. 
-   // TODO: This shouldn't be public. 
-   ConfigTable Config; 
-   AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel; 
-   AnalysisDiagClients AnalysisDiagOpt = PD_HTML; 
-   AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt; 
-   
-   std::string AnalyzeSpecificFunction; 
-   
-   /// File path to which the exploded graph should be dumped. 
-   std::string DumpExplodedGraphTo; 
-   
-   /// Store full compiler invocation for reproducible instructions in the 
-   /// generated report. 
-   std::string FullCompilerInvocation; 
-   
-   /// The maximum number of times the analyzer visits a block. 
-   unsigned maxBlockVisitOnPath; 
-   
-   /// Disable all analyzer checkers. 
-   /// 
-   /// This flag allows one to disable analyzer checkers on the code processed by 
-   /// the given analysis consumer. Note, the code will get parsed and the 
-   /// command-line options will get checked. 
-   unsigned DisableAllCheckers : 1; 
-   
-   unsigned ShowCheckerHelp : 1; 
-   unsigned ShowCheckerHelpAlpha : 1; 
-   unsigned ShowCheckerHelpDeveloper : 1; 
-   
-   unsigned ShowCheckerOptionList : 1; 
-   unsigned ShowCheckerOptionAlphaList : 1; 
-   unsigned ShowCheckerOptionDeveloperList : 1; 
-   
-   unsigned ShowEnabledCheckerList : 1; 
-   unsigned ShowConfigOptionsList : 1; 
-   unsigned ShouldEmitErrorsOnInvalidConfigValue : 1; 
-   unsigned AnalyzeAll : 1; 
-   unsigned AnalyzerDisplayProgress : 1; 
-   
-   unsigned eagerlyAssumeBinOpBifurcation : 1; 
-   
-   unsigned TrimGraph : 1; 
-   unsigned visualizeExplodedGraphWithGraphViz : 1; 
-   unsigned UnoptimizedCFG : 1; 
-   unsigned PrintStats : 1; 
-   
-   /// Do not re-analyze paths leading to exhausted nodes with a different 
-   /// strategy. We get better code coverage when retry is enabled. 
-   unsigned NoRetryExhausted : 1; 
-   
-   /// Emit analyzer warnings as errors. 
-   bool AnalyzerWerror : 1; 
-   
-   /// The inlining stack depth limit. 
-   unsigned InlineMaxStackDepth; 
-   
-   /// The mode of function selection used during inlining. 
-   AnalysisInliningMode InliningMode = NoRedundancy; 
-   
-   // Create a field for each -analyzer-config option. 
- #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \ 
-                                              SHALLOW_VAL, DEEP_VAL)            \ 
-   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL) 
-   
- #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \ 
-   TYPE NAME; 
-   
- #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" 
- #undef ANALYZER_OPTION 
- #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE 
-   
-   // Create an array of all -analyzer-config command line options. Sort it in 
-   // the constructor. 
-   std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = { 
- #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \ 
-                                              SHALLOW_VAL, DEEP_VAL)            \ 
-   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL) 
-   
- #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \ 
-   llvm::StringLiteral(CMDFLAG), 
-   
- #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" 
- #undef ANALYZER_OPTION 
- #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE 
-   }; 
-   
-   bool isUnknownAnalyzerConfig(StringRef Name) const { 
-     assert(llvm::is_sorted(AnalyzerConfigCmdFlags)); 
-   
-     return !std::binary_search(AnalyzerConfigCmdFlags.begin(), 
-                                AnalyzerConfigCmdFlags.end(), Name); 
-   } 
-   
-   AnalyzerOptions() 
-       : DisableAllCheckers(false), ShowCheckerHelp(false), 
-         ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), 
-         ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false), 
-         ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false), 
-         ShowConfigOptionsList(false), 
-         ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false), 
-         AnalyzerDisplayProgress(false), eagerlyAssumeBinOpBifurcation(false), 
-         TrimGraph(false), visualizeExplodedGraphWithGraphViz(false), 
-         UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false), 
-         AnalyzerWerror(false) { 
-     llvm::sort(AnalyzerConfigCmdFlags); 
-   } 
-   
-   /// Interprets an option's string value as a boolean. The "true" string is 
-   /// interpreted as true and the "false" string is interpreted as false. 
-   /// 
-   /// If an option value is not provided, returns the given \p DefaultVal. 
-   /// @param [in] CheckerName The *full name* of the checker. One may retrieve 
-   /// this from the checker object's field \c Name, or through \c 
-   /// CheckerManager::getCurrentCheckerName within the checker's registry 
-   /// function. 
-   /// Checker options are retrieved in the following format: 
-   /// `-analyzer-config CheckerName:OptionName=Value. 
-   /// @param [in] OptionName Name for option to retrieve. 
-   /// @param [in] SearchInParents If set to true and the searched option was not 
-   /// specified for the given checker the options for the parent packages will 
-   /// be searched as well. The inner packages take precedence over the outer 
-   /// ones. 
-   bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, 
-                                bool SearchInParents = false) const; 
-   
-   bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName, 
-                                bool SearchInParents = false) const; 
-   
-   /// Interprets an option's string value as an integer value. 
-   /// 
-   /// If an option value is not provided, returns the given \p DefaultVal. 
-   /// @param [in] CheckerName The *full name* of the checker. One may retrieve 
-   /// this from the checker object's field \c Name, or through \c 
-   /// CheckerManager::getCurrentCheckerName within the checker's registry 
-   /// function. 
-   /// Checker options are retrieved in the following format: 
-   /// `-analyzer-config CheckerName:OptionName=Value. 
-   /// @param [in] OptionName Name for option to retrieve. 
-   /// @param [in] SearchInParents If set to true and the searched option was not 
-   /// specified for the given checker the options for the parent packages will 
-   /// be searched as well. The inner packages take precedence over the outer 
-   /// ones. 
-   int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName, 
-                               bool SearchInParents = false) const; 
-   
-   int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName, 
-                               bool SearchInParents = false) const; 
-   
-   /// Query an option's string value. 
-   /// 
-   /// If an option value is not provided, returns the given \p DefaultVal. 
-   /// @param [in] CheckerName The *full name* of the checker. One may retrieve 
-   /// this from the checker object's field \c Name, or through \c 
-   /// CheckerManager::getCurrentCheckerName within the checker's registry 
-   /// function. 
-   /// Checker options are retrieved in the following format: 
-   /// `-analyzer-config CheckerName:OptionName=Value. 
-   /// @param [in] OptionName Name for option to retrieve. 
-   /// @param [in] SearchInParents If set to true and the searched option was not 
-   /// specified for the given checker the options for the parent packages will 
-   /// be searched as well. The inner packages take precedence over the outer 
-   /// ones. 
-   StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName, 
-                                    bool SearchInParents = false) const; 
-   
-   StringRef getCheckerStringOption(const ento::CheckerBase *C, 
-                                    StringRef OptionName, 
-                                    bool SearchInParents = false) const; 
-   
-   ExplorationStrategyKind getExplorationStrategy() const; 
-   CTUPhase1InliningKind getCTUPhase1Inlining() const; 
-   
-   /// Returns the inter-procedural analysis mode. 
-   IPAKind getIPAMode() const; 
-   
-   /// Returns the option controlling which C++ member functions will be 
-   /// considered for inlining. 
-   /// 
-   /// This is controlled by the 'c++-inlining' config option. 
-   /// 
-   /// \sa CXXMemberInliningMode 
-   bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const; 
-   
-   ento::PathDiagnosticConsumerOptions getDiagOpts() const { 
-     return {FullCompilerInvocation, 
-             ShouldDisplayMacroExpansions, 
-             ShouldSerializeStats, 
-             // The stable report filename option is deprecated because 
-             // file names are now always stable. Now the old option acts as 
-             // an alias to the new verbose filename option because this 
-             // closely mimics the behavior under the old option. 
-             ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename, 
-             AnalyzerWerror, 
-             ShouldApplyFixIts, 
-             ShouldDisplayCheckerNameForText}; 
-   } 
- }; 
-   
- using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>; 
-   
- //===----------------------------------------------------------------------===// 
- // We'll use AnalyzerOptions in the frontend, but we can't link the frontend 
- // with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on 
- // clangFrontend. 
- // 
- // For this reason, implement some methods in this header file. 
- //===----------------------------------------------------------------------===// 
-   
- inline std::vector<StringRef> 
- AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) { 
-   static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = { 
- #define GET_CHECKERS 
- #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \ 
-   llvm::StringLiteral(FULLNAME), 
- #include "clang/StaticAnalyzer/Checkers/Checkers.inc" 
- #undef CHECKER 
- #undef GET_CHECKERS 
-   }; 
-   std::vector<StringRef> Checkers; 
-   for (StringRef CheckerName : StaticAnalyzerCheckerNames) { 
-     if (!CheckerName.startswith("debug.") && 
-         (IncludeExperimental || !CheckerName.startswith("alpha."))) 
-       Checkers.push_back(CheckerName); 
-   } 
-   return Checkers; 
- } 
-   
- inline std::vector<StringRef> 
- AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) { 
-   static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = { 
- #define GET_PACKAGES 
- #define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME), 
- #include "clang/StaticAnalyzer/Checkers/Checkers.inc" 
- #undef PACKAGE 
- #undef GET_PACKAGES 
-   }; 
-   std::vector<StringRef> Packages; 
-   for (StringRef PackageName : StaticAnalyzerPackageNames) { 
-     if (PackageName != "debug" && 
-         (IncludeExperimental || PackageName != "alpha")) 
-       Packages.push_back(PackageName); 
-   } 
-   return Packages; 
- } 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H 
-