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