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