Szelethus created this revision. Szelethus added reviewers: NoQ, george.karpenkov, xazax.hun, MTC, rnkovacs. Herald added subscribers: cfe-commits, donat.nagy, mikhail.ramalho, dmgreen, a.sidorin, mgrang, szepet, whisperity.
Title says it all, here's how it look like locally: OVERVIEW: Clang Static Analyzer -analyzer-config Option List USAGE: clang [CLANG_OPTIONS] -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...> clang [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ... OPTIONS: aggressive-binary-operation-simplification (bool) Whether SValBuilder should rearrange comparisons and additive operations of symbolic expressions which consist of a sum of a symbol and a concrete integer into the format where symbols are on the left-hand side and the integer is on the right. This is only done if both symbols and both concrete integers are signed, greater than or equal to the quarter of the minimum value of the type and less than or equal to the quarter of the maximum value of that type. A + n <OP> B + m becomes A - B <OP> m - n, where A and B symbolic, n and m are integers. <OP> is any of '==', '!=', '<', '<=', '>', '>=', '+' or '-'. The rearrangement also happens with '-' instead of '+' on either or both side and also if any or both integers are missing. (default: false) avoid-suppressing-null-argument-paths (bool) Whether a bug report should not be suppressed if its path includes a call with a null argument, even if that call has a null return. This option has no effect when #shouldSuppressNullReturnPaths() is false. This is a counter-heuristic to avoid false negatives. (default: false) c++-allocator-inlining (bool) Whether or not allocator call may be considered for inlining. (default: true) c++-container-inlining (bool) Whether or not methods of C++ container objects may be considered for inlining. (default: false) c++-inlining (string) Controls which C++ member functions will be considered for inlining. Value: "constructors", "destructors" (default), "methods". c++-shared_ptr-inlining (bool) Whether or not the destructor of C++ 'shared_ptr' may be considered for inlining. This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr, and indeed any destructor named '~shared_ptr'. (default: false) c++-stdlib-inlining (bool) Whether or not C++ standard library functions may be considered for inlining. (default: true) c++-temp-dtor-inlining (bool) Whether C++ temporary destructors should be inlined during analysis. If temporary destructors are disabled in the CFG via the 'cfg-temporary-dtors' option, temporary destructors would not be inlined anyway. (default: true) c++-template-inlining (bool) Whether or not templated functions may be considered for inlining. cfg-conditional-static-initializers (bool) Whether 'static' initializers should be in conditional logic in the CFG. (default: true) cfg-implicit-dtors (bool) Whether or not implicit destructors for C++ objects should be included in the CFG. (default: true) cfg-lifetime (bool) Whether or not end-of-lifetime information should be included in the CFG. (default: false) cfg-loopexit (bool) Whether or not the end of the loop information should be included in the CFG. (default: false) cfg-rich-constructors (bool) Whether or not construction site information should be included in the CFG C++ constructor elements. (default: true) cfg-scopes (bool) Whether or not scope information should be included in the CFG. (default: false) cfg-temporary-dtors (bool) Whether or not the destructors for C++ temporary objects should be included in the CFG. (default: true) crosscheck-with-z3 (bool) Whether bug reports should be crosschecked with the Z3 constraint manager backend. (default: false) ctu-dir The directory containing the CTU related files. ctu-index-name the name of the file containing the CTU index of functions. (default: "externalFnMap.txt") eagerly-assume (bool) Whether we should eagerly assume evaluations of conditionals, thus, bifurcating the path. This indicates how the engine should handle expressions such as: 'x = (y != 0)'. When this is true then the subexpression 'y != 0' will be eagerly assumed to be true or false, thus evaluating it to the integers 0 or 1 respectively. The upside is that this can increase analysis precision until we have a better way to lazily evaluate such logic. The downside is that it eagerly bifurcates paths. (default: true) elide-constructors (bool) Whether elidable C++ copy-constructors and move-constructors should be actually elided during analysis. Both behaviors are allowed by the C++ standard, and the analyzer, like CodeGen, defaults to eliding. Starting with C++17 some elisions become mandatory, and in these cases the option will be ignored. (default: true) experimental-enable-naive-ctu-analysis (bool) Whether naive cross translation unit analysis is enabled. This is an experimental feature to inline functions from another translation units. (default: false) exploration_strategy (string) Value: "dfs", "bfs", "unexplored_first", "unexplored_first_queue" (default), "unexplored_first_location_queue", "bfs_block_dfs_contents". faux-bodies (bool) Whether the analyzer engine should synthesize fake bodies for well-known functions. (default: true) graph-trim-interval (unsigned) How often nodes in the ExplodedGraph should be recycled to save memory. To disable node reclamation, set the option to 0. (default: 1000) inline-lambdas (bool) Whether lambdas should be inlined. Otherwise a sink node will be generated each time a LambdaExpr is visited. (default: true) ipa (string) Controls the mode of inter-procedural analysis. Value: "none", "basic-inlining", "inlining" (default for shallow mode), "dynamic", "dynamic-bifurcate" (default for deep mode).: ipa-always-inline-size (unsigned) The size of the functions (in basic blocks), which should be considered to be small enough to always inline. (default: 3) max-inlinable-size (unsigned) The bound on the number of basic blocks in an inlined function. (default: 4 in shallow mode, 100 in deep mode) max-nodes (unsigned) The maximum number of nodes the analyzer can generate while exploring a top level function (for each exploded graph). 0 means no limit. (default: 75000 in shallow mode, 225000 in deep mode) max-symbol-complexity (unsigned) The maximum complexity of symbolic constraint (default: 35). max-times-inline-large (unsigned) The maximum times a large function could be inlined. (default: 32) min-cfg-size-treat-functions-as-large (unsigned) The number of basic blocks a function needs to have to be considered large for the 'max-times-inline-large' config option. (default: 14) mode (string) Controls the high-level analyzer mode, which influences the default settings for some of the lower-level config options (such as IPAMode). Value: "deep" (default), "shallow". model-path notes-as-events (bool) Whether the bug reporter should transparently treat extra note diagnostic pieces as event diagnostic pieces. Useful when the diagnostic consumer doesn't support the extra note pieces. (default: false) objc-inlining (bool) Whether ObjectiveC inlining is enabled, false otherwise. (default: false) prune-paths (bool) Whether irrelevant parts of a bug report path should be pruned out of the final output. (default: true) report-in-main-source-file (bool) Whether or not the diagnostic report should be always reported in the main source file and not the headers. (default: false) serialize-stats (bool) Whether the analyzer should serialize statistics to plist output. Statistics would be serialized in JSON format inside the main dictionary under the statistics key. Available only if compiled in assert mode or with LLVM statistics explicitly enabled. (default: false) stable-report-filename (bool) Whether or not the report filename should be random or not. (default: false) suppress-c++-stdlib (bool) Whether or not diagnostics reported within the C++ standard library should be suppressed. (default: true) suppress-inlined-defensive-checks (bool) Whether or not diagnostics containing inlined defensive NULL checks should be suppressed. (default: true) suppress-null-return-paths (bool) Whether or not paths that go through null returns should be suppressed. This is a heuristic for avoiding bug reports with paths that go through inlined functions that are more defensive than their callers. (default: true) unroll-loops (bool) Whether the analysis should try to unroll loops with known bounds. (default: false) widen-loops (bool) Whether the analysis should try to widen loops. Repository: rC Clang https://reviews.llvm.org/D53296 Files: include/clang/Driver/CC1Options.td include/clang/StaticAnalyzer/Core/AnalyzerOptions.h include/clang/StaticAnalyzer/Frontend/FrontendActions.h lib/Frontend/CompilerInvocation.cpp lib/FrontendTool/ExecuteCompilerInvocation.cpp lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -157,3 +157,100 @@ SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts); ClangCheckerRegistry(plugins).printList(out, checkerOpts); } + +void ento::printAnalyzerConfigList(raw_ostream &out) { + out << "OVERVIEW: Clang Static Analyzer -analyzer-config Option List\n\n"; + out << "USAGE: clang [CLANG_OPTIONS] -analyzer-config " + "<OPTION1=VALUE,OPTION2=VALUE,...>\n\n"; + out << " clang [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, " + "-analyzer-config OPTION2=VALUE, ...\n\n"; + out << "OPTIONS:\n\n"; + + using OptionAndDescriptionTy = std::pair<StringRef, StringRef>; + OptionAndDescriptionTy PrintableOptions[] = { +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC) \ + { CMDFLAG, DESC }, +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef BOOL_ANALYZER_OPTION + }; + + llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS, + const OptionAndDescriptionTy &RHS) { + return LHS.first < RHS.first; + }); + + constexpr size_t PadForOptionName = 2; + constexpr size_t MaxWidth = 80; + constexpr size_t OptionNameMaxWidth = 30; + constexpr size_t MinDistance = 2; + + constexpr size_t DescriptionWidth = + MaxWidth - (PadForOptionName + OptionNameMaxWidth + MinDistance); + + constexpr size_t PadForDescription = + MaxWidth - DescriptionWidth + MinDistance; + + static_assert(MaxWidth == + PadForOptionName + OptionNameMaxWidth + MinDistance + DescriptionWidth, + "Wrong setup for printing -analyzer-config list!"); + + for (const auto &Pair : PrintableOptions) { + // Indent and print the option name. + out.indent(PadForOptionName) << Pair.first; + + // Indent before printing the description. + if (Pair.first.size() > OptionNameMaxWidth) { + // If the option's name is longer then OptionNameMaxWidth, print a + // newline. + out << '\n'; + out.indent(PadForDescription); + } else { + int CurrentLineWidth = PadForOptionName + Pair.first.size(); + out.indent(PadForDescription - CurrentLineWidth); + } + + // Print the description in a way that the entire list fits within MaxWidth + // columns. + + // Points to the first character in the description that wasn't printed + // just yet. + const char *NonPrintedTextStart = Pair.second.data(); + const char *const End = Pair.second.data() + Pair.second.size(); + while (NonPrintedTextStart < End) { + + // If the remainder of the description is shorter than DescriptionWidth. + if (NonPrintedTextStart + DescriptionWidth > End) { + out << std::string(NonPrintedTextStart, End); + break; + } + + // Look for a space around NonPrintedTextStart + DescriptionWidth. + + // First, look for the last space within + // [NonPrintedTextStart, NonPrintedTextStart + DescriptionWidth). + size_t LastPrintableCharPos = + StringRef(NonPrintedTextStart, DescriptionWidth).find_last_of(' '); + + // If we didn't find a space just yet, accept the fact that this line will + // not fit within MaxWidth columns, and look for the first space within + // [NonPrintedTextStart, std::end(NonPrintedTextStart)). + if (LastPrintableCharPos == StringRef::npos) + LastPrintableCharPos = + StringRef(NonPrintedTextStart).find_first_of(' '); + + // If there are no spaces left, print the remaining part of the + // description. + if (LastPrintableCharPos == StringRef::npos) { + out << std::string(NonPrintedTextStart, End); + break; + } + + out << StringRef(NonPrintedTextStart, LastPrintableCharPos) << '\n'; + out.indent(PadForDescription); + + // Step the pointer. + NonPrintedTextStart += LastPrintableCharPos + 1; + } + out << "\n\n"; + } +} Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -241,11 +241,19 @@ ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); return true; } + + // Honor -analyzer-list-enabled-checkers. if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) { ento::printEnabledCheckerList(llvm::outs(), Clang->getFrontendOpts().Plugins, *Clang->getAnalyzerOpts()); } + + // Honor -analyzer-list-enabled-checkers. + if (Clang->getAnalyzerOpts()->ShowConfigOptionsList) { + ento::printAnalyzerConfigList(llvm::outs()); + return true; + } #endif // If there were errors in processing arguments, don't do anything else. Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -279,6 +279,7 @@ } Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help); + Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_list_configs); Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers); Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks); Index: include/clang/StaticAnalyzer/Frontend/FrontendActions.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -55,6 +55,7 @@ void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins); void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins, const AnalyzerOptions &opts); +void printAnalyzerConfigList(raw_ostream &OS); } // end GR namespace Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h =================================================================== --- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -172,6 +172,7 @@ unsigned ShowCheckerHelp : 1; unsigned ShowEnabledCheckerList : 1; + unsigned ShowConfigOptionsList : 1; unsigned AnalyzeAll : 1; unsigned AnalyzerDisplayProgress : 1; unsigned AnalyzeNestedBlocks : 1; Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -129,6 +129,9 @@ def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; +def analyzer_list_configs : Flag<["-"], "analyzer-list-configs">, + HelpText<"Display the list of -analyzer-config options">; + def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">, HelpText<"Display the list of enabled analyzer checkers">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits