blob: 1c31c35b75e4a10e9358345042b4c54d3d67f687 [file] [log] [blame]
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +00001//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Defines the registration function for the analyzer checkers.
11//
12//===----------------------------------------------------------------------===//
13
Argyrios Kyrtzidis6fa0d202011-02-15 16:54:12 +000014#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/Basic/Diagnostic.h"
16#include "clang/Frontend/FrontendDiagnostic.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000017#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000018#include "clang/StaticAnalyzer/Core/CheckerManager.h"
Kristof Umann76a21502018-12-15 16:23:51 +000019#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "llvm/ADT/SmallVector.h"
Kristof Umannf1f351c2018-11-02 15:59:37 +000022#include "llvm/Support/FormattedStream.h"
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000023#include "llvm/Support/raw_ostream.h"
Ahmed Charlesdfca6f92014-03-09 11:36:40 +000024#include <memory>
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000025
26using namespace clang;
27using namespace ento;
Jordy Rose075d73b2011-08-17 04:56:03 +000028
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000029std::unique_ptr<CheckerManager> ento::createCheckerManager(
George Karpenkov4ece68a2018-08-06 23:09:07 +000030 ASTContext &context,
31 AnalyzerOptions &opts,
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000032 ArrayRef<std::string> plugins,
33 ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns,
34 DiagnosticsEngine &diags) {
George Karpenkov4ece68a2018-08-06 23:09:07 +000035 auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000036
Kristof Umannb0be2ab2018-12-15 18:11:49 +000037 CheckerRegistry allCheckers(plugins, diags);
Alexander Kornienkod00ed8e2018-06-27 14:56:12 +000038
39 for (const auto &Fn : checkerRegistrationFns)
40 Fn(allCheckers);
41
Kristof Umannb0be2ab2018-12-15 18:11:49 +000042 allCheckers.initializeManager(*checkerMgr, opts);
43 allCheckers.validateCheckerOptions(opts);
Argyrios Kyrtzidisa15dfec2011-02-28 17:36:09 +000044 checkerMgr->finishedCheckerRegistration();
45
Richard Trieud4b05ce2015-01-17 00:46:55 +000046 return checkerMgr;
Argyrios Kyrtzidis556c45e2011-02-14 18:13:31 +000047}
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000048
Kristof Umannb0be2ab2018-12-15 18:11:49 +000049void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
50 DiagnosticsEngine &diags) {
Jordy Rose59cce712011-08-16 21:24:21 +000051 out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
52 out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000053
Kristof Umannb0be2ab2018-12-15 18:11:49 +000054 CheckerRegistry(plugins, diags).printHelp(out);
Argyrios Kyrtzidis17bee3e2011-02-25 00:09:51 +000055}
Gabor Horvathc4309902016-08-08 13:41:04 +000056
57void ento::printEnabledCheckerList(raw_ostream &out,
58 ArrayRef<std::string> plugins,
Kristof Umannf282d272018-12-15 15:44:05 +000059 const AnalyzerOptions &opts,
60 DiagnosticsEngine &diags) {
Gabor Horvathc4309902016-08-08 13:41:04 +000061 out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
62
Kristof Umannb0be2ab2018-12-15 18:11:49 +000063 CheckerRegistry(plugins, diags).printList(out, opts);
Gabor Horvathc4309902016-08-08 13:41:04 +000064}
Kristof Umannf1f351c2018-11-02 15:59:37 +000065
66void ento::printAnalyzerConfigList(raw_ostream &out) {
67 out << "OVERVIEW: Clang Static Analyzer -analyzer-config Option List\n\n";
68 out << "USAGE: clang -cc1 [CLANG_OPTIONS] -analyzer-config "
69 "<OPTION1=VALUE,OPTION2=VALUE,...>\n\n";
70 out << " clang -cc1 [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, "
71 "-analyzer-config OPTION2=VALUE, ...\n\n";
72 out << " clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang"
73 "<OPTION1=VALUE,OPTION2=VALUE,...>\n\n";
74 out << " clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang "
75 "OPTION1=VALUE, -Xclang -analyzer-config -Xclang "
76 "OPTION2=VALUE, ...\n\n";
77 out << "OPTIONS:\n\n";
78
79 using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
80 OptionAndDescriptionTy PrintableOptions[] = {
81#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
82 { \
83 CMDFLAG, \
84 llvm::Twine(llvm::Twine() + "(" + \
Kristof Umann37829b52018-11-02 19:48:56 +000085 (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
86 ") " DESC \
Kristof Umannf1f351c2018-11-02 15:59:37 +000087 " (default: " #DEFAULT_VAL ")").str() \
88 },
89
90#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
91 SHALLOW_VAL, DEEP_VAL) \
92 { \
93 CMDFLAG, \
94 llvm::Twine(llvm::Twine() + "(" + \
Kristof Umann37829b52018-11-02 19:48:56 +000095 (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
96 ") " DESC \
Kristof Umannf1f351c2018-11-02 15:59:37 +000097 " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \
98 " in deep mode)").str() \
99 },
100#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
101#undef ANALYZER_OPTION
102#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
103 };
104
105 llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS,
106 const OptionAndDescriptionTy &RHS) {
107 return LHS.first < RHS.first;
108 });
109
110 constexpr size_t MinLineWidth = 70;
111 constexpr size_t PadForOpt = 2;
112 constexpr size_t OptionWidth = 30;
113 constexpr size_t PadForDesc = PadForOpt + OptionWidth;
114 static_assert(MinLineWidth > PadForDesc, "MinLineWidth must be greater!");
115
116 llvm::formatted_raw_ostream FOut(out);
117
118 for (const auto &Pair : PrintableOptions) {
119 FOut.PadToColumn(PadForOpt) << Pair.first;
120
121 // If the buffer's length is greater then PadForDesc, print a newline.
122 if (FOut.getColumn() > PadForDesc)
123 FOut << '\n';
124
125 FOut.PadToColumn(PadForDesc);
126
127 for (char C : Pair.second) {
128 if (FOut.getColumn() > MinLineWidth && C == ' ') {
129 FOut << '\n';
130 FOut.PadToColumn(PadForDesc);
131 continue;
132 }
133 FOut << C;
134 }
135 FOut << "\n\n";
136 }
137}