blob: f4f06e32cd1d7d876e7187ad3751e07ebcba1cd0 [file] [log] [blame]
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +00001//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Defines the registration function for the analyzer checkers.
10//
11//===----------------------------------------------------------------------===//
12
Argyrios Kyrtzidis6fa0d202011-02-15 16:54:12 +000013#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000014#include "clang/Basic/Diagnostic.h"
15#include "clang/Frontend/FrontendDiagnostic.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000016#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000017#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Kristof Umann76a21502018-12-15 16:23:51 +000018#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000019#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "llvm/ADT/SmallVector.h"
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000021#include "llvm/Support/raw_ostream.h"
Ahmed Charlesdfca6f92014-03-09 11:36:40 +000022#include <memory>
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000023
24using namespace clang;
25using namespace ento;
Jordy Rose075d73b2011-08-17 04:56:03 +000026
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000027std::unique_ptr<CheckerManager> ento::createCheckerManager(
George Karpenkov4ece68a2018-08-06 23:09:07 +000028 ASTContext &context,
29 AnalyzerOptions &opts,
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000030 ArrayRef<std::string> plugins,
31 ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns,
32 DiagnosticsEngine &diags) {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +000033 auto checkerMgr = std::make_unique<CheckerManager>(context, opts);
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000034
Kristof Umann98217ad2019-01-26 17:27:40 +000035 CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(),
36 checkerRegistrationFns);
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000037
Kristof Umanndd9c86e2019-01-26 15:59:21 +000038 allCheckers.initializeManager(*checkerMgr);
39 allCheckers.validateCheckerOptions();
Argyrios Kyrtzidisa15dfec2011-02-28 17:36:09 +000040 checkerMgr->finishedCheckerRegistration();
41
Richard Trieud4b05ce2015-01-17 00:46:55 +000042 return checkerMgr;
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000043}
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000044
Kristof Umannb0be2ab2018-12-15 18:11:49 +000045void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
Kristof Umanndd9c86e2019-01-26 15:59:21 +000046 AnalyzerOptions &anopts,
Kristof Umann058a7a42019-01-26 14:23:08 +000047 DiagnosticsEngine &diags,
48 const LangOptions &langOpts) {
Jordy Rose59cce712011-08-16 21:24:21 +000049 out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
50 out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000051
Kristof Umannb9bc7ec2019-04-18 15:19:16 +000052 CheckerRegistry(plugins, diags, anopts, langOpts)
53 .printCheckerWithDescList(out);
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000054}
Gabor Horvathc4309902016-08-08 13:41:04 +000055
56void ento::printEnabledCheckerList(raw_ostream &out,
57 ArrayRef<std::string> plugins,
Kristof Umanndd9c86e2019-01-26 15:59:21 +000058 AnalyzerOptions &anopts,
Kristof Umann058a7a42019-01-26 14:23:08 +000059 DiagnosticsEngine &diags,
60 const LangOptions &langOpts) {
Gabor Horvathc4309902016-08-08 13:41:04 +000061 out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
62
Kristof Umannb9bc7ec2019-04-18 15:19:16 +000063 CheckerRegistry(plugins, diags, anopts, langOpts)
64 .printEnabledCheckerList(out);
Gabor Horvathc4309902016-08-08 13:41:04 +000065}
Kristof Umannf1f351c2018-11-02 15:59:37 +000066
Kristof Umanne8df27d2019-05-23 20:47:28 +000067void ento::printCheckerConfigList(raw_ostream &OS,
68 ArrayRef<std::string> plugins,
69 AnalyzerOptions &opts,
70 DiagnosticsEngine &diags,
71 const LangOptions &LangOpts) {
72 CheckerRegistry(plugins, diags, opts, LangOpts)
73 .printCheckerOptionList(OS);
74}
75
Kristof Umannf1f351c2018-11-02 15:59:37 +000076void ento::printAnalyzerConfigList(raw_ostream &out) {
Kristof Umanna1aef902019-08-15 08:53:16 +000077 // FIXME: This message sounds scary, should be scary, but incorrectly states
78 // that all configs are super dangerous. In reality, many of them should be
79 // accessible to the user. We should create a user-facing subset of config
80 // options under a different frontend flag.
81 out << R"(
82OVERVIEW: Clang Static Analyzer -analyzer-config Option List
83
84The following list of configurations are meant for development purposes only, as
85some of the variables they define are set to result in the most optimal
86analysis. Setting them to other values may drastically change how the analyzer
87behaves, and may even result in instabilities, crashes!
88
89USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
90 -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
91OPTIONS:
92)";
Kristof Umannf1f351c2018-11-02 15:59:37 +000093
94 using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
95 OptionAndDescriptionTy PrintableOptions[] = {
96#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
97 { \
98 CMDFLAG, \
99 llvm::Twine(llvm::Twine() + "(" + \
Kristof Umann37829b52018-11-02 19:48:56 +0000100 (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
101 ") " DESC \
Kristof Umannf1f351c2018-11-02 15:59:37 +0000102 " (default: " #DEFAULT_VAL ")").str() \
103 },
104
105#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
106 SHALLOW_VAL, DEEP_VAL) \
107 { \
108 CMDFLAG, \
109 llvm::Twine(llvm::Twine() + "(" + \
Kristof Umann37829b52018-11-02 19:48:56 +0000110 (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
111 ") " DESC \
Kristof Umannf1f351c2018-11-02 15:59:37 +0000112 " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \
113 " in deep mode)").str() \
114 },
115#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
116#undef ANALYZER_OPTION
117#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
118 };
119
120 llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS,
121 const OptionAndDescriptionTy &RHS) {
122 return LHS.first < RHS.first;
123 });
124
Kristof Umannf1f351c2018-11-02 15:59:37 +0000125 for (const auto &Pair : PrintableOptions) {
Kristof Umanne8df27d2019-05-23 20:47:28 +0000126 AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2,
127 /*EntryWidth*/ 30,
128 /*MinLineWidth*/ 70);
129 out << "\n\n";
Kristof Umannf1f351c2018-11-02 15:59:37 +0000130 }
131}