xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
1*e038c9c4Sjoerg //===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
2*e038c9c4Sjoerg //
3*e038c9c4Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e038c9c4Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*e038c9c4Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e038c9c4Sjoerg //
7*e038c9c4Sjoerg //===----------------------------------------------------------------------===//
8*e038c9c4Sjoerg //
9*e038c9c4Sjoerg // Defines the registration function for the analyzer checkers.
10*e038c9c4Sjoerg //
11*e038c9c4Sjoerg //===----------------------------------------------------------------------===//
12*e038c9c4Sjoerg 
13*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
14*e038c9c4Sjoerg #include "clang/Basic/Diagnostic.h"
15*e038c9c4Sjoerg #include "clang/Frontend/CompilerInstance.h"
16*e038c9c4Sjoerg #include "clang/Frontend/FrontendDiagnostic.h"
17*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
18*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
20*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
21*e038c9c4Sjoerg #include "llvm/ADT/SmallVector.h"
22*e038c9c4Sjoerg #include "llvm/Support/raw_ostream.h"
23*e038c9c4Sjoerg #include <memory>
24*e038c9c4Sjoerg 
25*e038c9c4Sjoerg using namespace clang;
26*e038c9c4Sjoerg using namespace ento;
27*e038c9c4Sjoerg 
printCheckerHelp(raw_ostream & out,CompilerInstance & CI)28*e038c9c4Sjoerg void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) {
29*e038c9c4Sjoerg   out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
30*e038c9c4Sjoerg   out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
31*e038c9c4Sjoerg 
32*e038c9c4Sjoerg   auto CheckerMgr = std::make_unique<CheckerManager>(
33*e038c9c4Sjoerg       *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
34*e038c9c4Sjoerg       CI.getFrontendOpts().Plugins);
35*e038c9c4Sjoerg 
36*e038c9c4Sjoerg   CheckerMgr->getCheckerRegistryData().printCheckerWithDescList(
37*e038c9c4Sjoerg       *CI.getAnalyzerOpts(), out);
38*e038c9c4Sjoerg }
39*e038c9c4Sjoerg 
printEnabledCheckerList(raw_ostream & out,CompilerInstance & CI)40*e038c9c4Sjoerg void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) {
41*e038c9c4Sjoerg   out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
42*e038c9c4Sjoerg 
43*e038c9c4Sjoerg   auto CheckerMgr = std::make_unique<CheckerManager>(
44*e038c9c4Sjoerg       *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
45*e038c9c4Sjoerg       CI.getFrontendOpts().Plugins);
46*e038c9c4Sjoerg 
47*e038c9c4Sjoerg   CheckerMgr->getCheckerRegistryData().printEnabledCheckerList(out);
48*e038c9c4Sjoerg }
49*e038c9c4Sjoerg 
printCheckerConfigList(raw_ostream & out,CompilerInstance & CI)50*e038c9c4Sjoerg void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) {
51*e038c9c4Sjoerg 
52*e038c9c4Sjoerg   auto CheckerMgr = std::make_unique<CheckerManager>(
53*e038c9c4Sjoerg       *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
54*e038c9c4Sjoerg       CI.getFrontendOpts().Plugins);
55*e038c9c4Sjoerg 
56*e038c9c4Sjoerg   CheckerMgr->getCheckerRegistryData().printCheckerOptionList(
57*e038c9c4Sjoerg       *CI.getAnalyzerOpts(), out);
58*e038c9c4Sjoerg }
59*e038c9c4Sjoerg 
printAnalyzerConfigList(raw_ostream & out)60*e038c9c4Sjoerg void ento::printAnalyzerConfigList(raw_ostream &out) {
61*e038c9c4Sjoerg   // FIXME: This message sounds scary, should be scary, but incorrectly states
62*e038c9c4Sjoerg   // that all configs are super dangerous. In reality, many of them should be
63*e038c9c4Sjoerg   // accessible to the user. We should create a user-facing subset of config
64*e038c9c4Sjoerg   // options under a different frontend flag.
65*e038c9c4Sjoerg   out << R"(
66*e038c9c4Sjoerg OVERVIEW: Clang Static Analyzer -analyzer-config Option List
67*e038c9c4Sjoerg 
68*e038c9c4Sjoerg The following list of configurations are meant for development purposes only, as
69*e038c9c4Sjoerg some of the variables they define are set to result in the most optimal
70*e038c9c4Sjoerg analysis. Setting them to other values may drastically change how the analyzer
71*e038c9c4Sjoerg behaves, and may even result in instabilities, crashes!
72*e038c9c4Sjoerg 
73*e038c9c4Sjoerg USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
74*e038c9c4Sjoerg        -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
75*e038c9c4Sjoerg OPTIONS:
76*e038c9c4Sjoerg )";
77*e038c9c4Sjoerg 
78*e038c9c4Sjoerg   using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
79*e038c9c4Sjoerg   OptionAndDescriptionTy PrintableOptions[] = {
80*e038c9c4Sjoerg #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
81*e038c9c4Sjoerg     {                                                                          \
82*e038c9c4Sjoerg       CMDFLAG,                                                                 \
83*e038c9c4Sjoerg       llvm::Twine(llvm::Twine() + "(" +                                        \
84*e038c9c4Sjoerg                   (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +      \
85*e038c9c4Sjoerg                   ") " DESC                                                    \
86*e038c9c4Sjoerg                   " (default: " #DEFAULT_VAL ")").str()                        \
87*e038c9c4Sjoerg     },
88*e038c9c4Sjoerg 
89*e038c9c4Sjoerg #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
90*e038c9c4Sjoerg                                              SHALLOW_VAL, DEEP_VAL)            \
91*e038c9c4Sjoerg     {                                                                          \
92*e038c9c4Sjoerg       CMDFLAG,                                                                 \
93*e038c9c4Sjoerg       llvm::Twine(llvm::Twine() + "(" +                                        \
94*e038c9c4Sjoerg                   (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +      \
95*e038c9c4Sjoerg                   ") " DESC                                                    \
96*e038c9c4Sjoerg                   " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL    \
97*e038c9c4Sjoerg                   " in deep mode)").str()                                      \
98*e038c9c4Sjoerg     },
99*e038c9c4Sjoerg #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
100*e038c9c4Sjoerg #undef ANALYZER_OPTION
101*e038c9c4Sjoerg #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
102*e038c9c4Sjoerg   };
103*e038c9c4Sjoerg 
104*e038c9c4Sjoerg   llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS,
105*e038c9c4Sjoerg                                   const OptionAndDescriptionTy &RHS) {
106*e038c9c4Sjoerg     return LHS.first < RHS.first;
107*e038c9c4Sjoerg   });
108*e038c9c4Sjoerg 
109*e038c9c4Sjoerg   for (const auto &Pair : PrintableOptions) {
110*e038c9c4Sjoerg     AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2,
111*e038c9c4Sjoerg                                          /*EntryWidth*/ 30,
112*e038c9c4Sjoerg                                          /*MinLineWidth*/ 70);
113*e038c9c4Sjoerg     out << "\n\n";
114*e038c9c4Sjoerg   }
115*e038c9c4Sjoerg }
116