1 | //===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Defines the registration function for the analyzer checkers. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h" |
14 | #include "clang/Basic/Diagnostic.h" |
15 | #include "clang/Frontend/CompilerInstance.h" |
16 | #include "clang/Frontend/FrontendDiagnostic.h" |
17 | #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" |
18 | #include "clang/StaticAnalyzer/Core/CheckerManager.h" |
19 | #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" |
20 | #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" |
21 | #include "llvm/ADT/SmallVector.h" |
22 | #include "llvm/Support/raw_ostream.h" |
23 | #include <memory> |
24 | |
25 | using namespace clang; |
26 | using namespace ento; |
27 | |
28 | void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) { |
29 | out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n" ; |
30 | out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n" ; |
31 | |
32 | auto CheckerMgr = std::make_unique<CheckerManager>( |
33 | args&: CI.getAnalyzerOpts(), args&: CI.getLangOpts(), args&: CI.getDiagnostics(), |
34 | args&: CI.getFrontendOpts().Plugins); |
35 | |
36 | CheckerMgr->getCheckerRegistryData().printCheckerWithDescList( |
37 | AnOpts: CI.getAnalyzerOpts(), Out&: out); |
38 | } |
39 | |
40 | void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) { |
41 | out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n" ; |
42 | |
43 | auto CheckerMgr = std::make_unique<CheckerManager>( |
44 | args&: CI.getAnalyzerOpts(), args&: CI.getLangOpts(), args&: CI.getDiagnostics(), |
45 | args&: CI.getFrontendOpts().Plugins); |
46 | |
47 | CheckerMgr->getCheckerRegistryData().printEnabledCheckerList(Out&: out); |
48 | } |
49 | |
50 | void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) { |
51 | |
52 | auto CheckerMgr = std::make_unique<CheckerManager>( |
53 | args&: CI.getAnalyzerOpts(), args&: CI.getLangOpts(), args&: CI.getDiagnostics(), |
54 | args&: CI.getFrontendOpts().Plugins); |
55 | |
56 | CheckerMgr->getCheckerRegistryData().printCheckerOptionList( |
57 | AnOpts: CI.getAnalyzerOpts(), Out&: out); |
58 | } |
59 | |
60 | void ento::printAnalyzerConfigList(raw_ostream &out) { |
61 | // FIXME: This message sounds scary, should be scary, but incorrectly states |
62 | // that all configs are super dangerous. In reality, many of them should be |
63 | // accessible to the user. We should create a user-facing subset of config |
64 | // options under a different frontend flag. |
65 | out << R"( |
66 | OVERVIEW: Clang Static Analyzer -analyzer-config Option List |
67 | |
68 | The following list of configurations are meant for development purposes only, as |
69 | some of the variables they define are set to result in the most optimal |
70 | analysis. Setting them to other values may drastically change how the analyzer |
71 | behaves, and may even result in instabilities, crashes! |
72 | |
73 | USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...> |
74 | -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ... |
75 | OPTIONS: |
76 | )" ; |
77 | |
78 | using OptionAndDescriptionTy = std::pair<StringRef, std::string>; |
79 | OptionAndDescriptionTy PrintableOptions[] = { |
80 | #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ |
81 | { \ |
82 | CMDFLAG, \ |
83 | llvm::Twine(llvm::Twine() + "(" + \ |
84 | (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ |
85 | ") " DESC \ |
86 | " (default: " #DEFAULT_VAL ")").str() \ |
87 | }, |
88 | |
89 | #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ |
90 | SHALLOW_VAL, DEEP_VAL) \ |
91 | { \ |
92 | CMDFLAG, \ |
93 | llvm::Twine(llvm::Twine() + "(" + \ |
94 | (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ |
95 | ") " DESC \ |
96 | " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \ |
97 | " in deep mode)").str() \ |
98 | }, |
99 | #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" |
100 | #undef ANALYZER_OPTION |
101 | #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE |
102 | }; |
103 | |
104 | llvm::sort(C&: PrintableOptions, Comp: llvm::less_first()); |
105 | |
106 | for (const auto &Pair : PrintableOptions) { |
107 | AnalyzerOptions::printFormattedEntry(Out&: out, EntryDescPair: Pair, /*InitialPad*/ 2, |
108 | /*EntryWidth*/ 30, |
109 | /*MinLineWidth*/ 70); |
110 | out << "\n\n" ; |
111 | } |
112 | } |
113 | |