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