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