Argyrios Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 1 | //===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // 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 Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // Defines the registration function for the analyzer checkers. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
Argyrios Kyrtzidis | 6fa0d20 | 2011-02-15 16:54:12 +0000 | [diff] [blame] | 13 | #include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" |
Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 14 | #include "clang/Basic/Diagnostic.h" |
| 15 | #include "clang/Frontend/FrontendDiagnostic.h" |
Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 16 | #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" |
Argyrios Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 17 | #include "clang/StaticAnalyzer/Core/CheckerManager.h" |
Kristof Umann | 76a2150 | 2018-12-15 16:23:51 +0000 | [diff] [blame] | 18 | #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" |
Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 19 | #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" |
Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/SmallVector.h" |
Argyrios Kyrtzidis | 17bee3e | 2011-02-25 00:09:51 +0000 | [diff] [blame] | 21 | #include "llvm/Support/raw_ostream.h" |
Ahmed Charles | dfca6f9 | 2014-03-09 11:36:40 +0000 | [diff] [blame] | 22 | #include <memory> |
Argyrios Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 23 | |
| 24 | using namespace clang; |
| 25 | using namespace ento; |
Jordy Rose | 075d73b | 2011-08-17 04:56:03 +0000 | [diff] [blame] | 26 | |
Alexander Kornienko | d00ed8e | 2018-06-27 14:56:12 +0000 | [diff] [blame] | 27 | std::unique_ptr<CheckerManager> ento::createCheckerManager( |
George Karpenkov | 4ece68a | 2018-08-06 23:09:07 +0000 | [diff] [blame] | 28 | ASTContext &context, |
| 29 | AnalyzerOptions &opts, |
Alexander Kornienko | d00ed8e | 2018-06-27 14:56:12 +0000 | [diff] [blame] | 30 | ArrayRef<std::string> plugins, |
| 31 | ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, |
| 32 | DiagnosticsEngine &diags) { |
Jonas Devlieghere | 2b3d49b | 2019-08-14 23:04:18 +0000 | [diff] [blame] | 33 | auto checkerMgr = std::make_unique<CheckerManager>(context, opts); |
Argyrios Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 34 | |
Kristof Umann | 98217ad | 2019-01-26 17:27:40 +0000 | [diff] [blame] | 35 | CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(), |
| 36 | checkerRegistrationFns); |
Alexander Kornienko | d00ed8e | 2018-06-27 14:56:12 +0000 | [diff] [blame] | 37 | |
Kristof Umann | dd9c86e | 2019-01-26 15:59:21 +0000 | [diff] [blame] | 38 | allCheckers.initializeManager(*checkerMgr); |
| 39 | allCheckers.validateCheckerOptions(); |
Argyrios Kyrtzidis | a15dfec | 2011-02-28 17:36:09 +0000 | [diff] [blame] | 40 | checkerMgr->finishedCheckerRegistration(); |
| 41 | |
Richard Trieu | d4b05ce | 2015-01-17 00:46:55 +0000 | [diff] [blame] | 42 | return checkerMgr; |
Argyrios Kyrtzidis | 556c45e | 2011-02-14 18:13:31 +0000 | [diff] [blame] | 43 | } |
Argyrios Kyrtzidis | 17bee3e | 2011-02-25 00:09:51 +0000 | [diff] [blame] | 44 | |
Kristof Umann | b0be2ab | 2018-12-15 18:11:49 +0000 | [diff] [blame] | 45 | void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins, |
Kristof Umann | dd9c86e | 2019-01-26 15:59:21 +0000 | [diff] [blame] | 46 | AnalyzerOptions &anopts, |
Kristof Umann | 058a7a4 | 2019-01-26 14:23:08 +0000 | [diff] [blame] | 47 | DiagnosticsEngine &diags, |
| 48 | const LangOptions &langOpts) { |
Jordy Rose | 59cce71 | 2011-08-16 21:24:21 +0000 | [diff] [blame] | 49 | out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; |
| 50 | out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; |
Argyrios Kyrtzidis | 17bee3e | 2011-02-25 00:09:51 +0000 | [diff] [blame] | 51 | |
Kristof Umann | b9bc7ec | 2019-04-18 15:19:16 +0000 | [diff] [blame] | 52 | CheckerRegistry(plugins, diags, anopts, langOpts) |
| 53 | .printCheckerWithDescList(out); |
Argyrios Kyrtzidis | 17bee3e | 2011-02-25 00:09:51 +0000 | [diff] [blame] | 54 | } |
Gabor Horvath | c430990 | 2016-08-08 13:41:04 +0000 | [diff] [blame] | 55 | |
| 56 | void ento::printEnabledCheckerList(raw_ostream &out, |
| 57 | ArrayRef<std::string> plugins, |
Kristof Umann | dd9c86e | 2019-01-26 15:59:21 +0000 | [diff] [blame] | 58 | AnalyzerOptions &anopts, |
Kristof Umann | 058a7a4 | 2019-01-26 14:23:08 +0000 | [diff] [blame] | 59 | DiagnosticsEngine &diags, |
| 60 | const LangOptions &langOpts) { |
Gabor Horvath | c430990 | 2016-08-08 13:41:04 +0000 | [diff] [blame] | 61 | out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; |
| 62 | |
Kristof Umann | b9bc7ec | 2019-04-18 15:19:16 +0000 | [diff] [blame] | 63 | CheckerRegistry(plugins, diags, anopts, langOpts) |
| 64 | .printEnabledCheckerList(out); |
Gabor Horvath | c430990 | 2016-08-08 13:41:04 +0000 | [diff] [blame] | 65 | } |
Kristof Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 66 | |
Kristof Umann | e8df27d | 2019-05-23 20:47:28 +0000 | [diff] [blame] | 67 | void 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 Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 76 | void ento::printAnalyzerConfigList(raw_ostream &out) { |
Kristof Umann | a1aef90 | 2019-08-15 08:53:16 +0000 | [diff] [blame] | 77 | // 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"( |
| 82 | OVERVIEW: Clang Static Analyzer -analyzer-config Option List |
| 83 | |
| 84 | The following list of configurations are meant for development purposes only, as |
| 85 | some of the variables they define are set to result in the most optimal |
| 86 | analysis. Setting them to other values may drastically change how the analyzer |
| 87 | behaves, and may even result in instabilities, crashes! |
| 88 | |
| 89 | USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...> |
| 90 | -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ... |
| 91 | OPTIONS: |
| 92 | )"; |
Kristof Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 93 | |
| 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 Umann | 37829b5 | 2018-11-02 19:48:56 +0000 | [diff] [blame] | 100 | (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ |
| 101 | ") " DESC \ |
Kristof Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 102 | " (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 Umann | 37829b5 | 2018-11-02 19:48:56 +0000 | [diff] [blame] | 110 | (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ |
| 111 | ") " DESC \ |
Kristof Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 112 | " (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 Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 125 | for (const auto &Pair : PrintableOptions) { |
Kristof Umann | e8df27d | 2019-05-23 20:47:28 +0000 | [diff] [blame] | 126 | AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2, |
| 127 | /*EntryWidth*/ 30, |
| 128 | /*MinLineWidth*/ 70); |
| 129 | out << "\n\n"; |
Kristof Umann | f1f351c | 2018-11-02 15:59:37 +0000 | [diff] [blame] | 130 | } |
| 131 | } |