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