12aac0c47SKristóf Umann //===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
22aac0c47SKristóf Umann //
32aac0c47SKristóf Umann // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42aac0c47SKristóf Umann // See https://llvm.org/LICENSE.txt for license information.
52aac0c47SKristóf Umann // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62aac0c47SKristóf Umann //
72aac0c47SKristóf Umann //===----------------------------------------------------------------------===//
82aac0c47SKristóf Umann //
92aac0c47SKristóf Umann // Defines the registration function for the analyzer checkers.
102aac0c47SKristóf Umann //
112aac0c47SKristóf Umann //===----------------------------------------------------------------------===//
122aac0c47SKristóf Umann
132aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
142aac0c47SKristóf Umann #include "clang/Basic/Diagnostic.h"
152aac0c47SKristóf Umann #include "clang/Frontend/CompilerInstance.h"
162aac0c47SKristóf Umann #include "clang/Frontend/FrontendDiagnostic.h"
172aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
182aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Core/CheckerManager.h"
192aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
202aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
212aac0c47SKristóf Umann #include "llvm/ADT/SmallVector.h"
222aac0c47SKristóf Umann #include "llvm/Support/raw_ostream.h"
232aac0c47SKristóf Umann #include <memory>
242aac0c47SKristóf Umann
252aac0c47SKristóf Umann using namespace clang;
262aac0c47SKristóf Umann using namespace ento;
272aac0c47SKristóf Umann
printCheckerHelp(raw_ostream & out,CompilerInstance & CI)282aac0c47SKristóf Umann void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) {
292aac0c47SKristóf Umann out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
302aac0c47SKristóf Umann out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
312aac0c47SKristóf Umann
322aac0c47SKristóf Umann auto CheckerMgr = std::make_unique<CheckerManager>(
33*8e0c9bb9SJan Svoboda CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
342aac0c47SKristóf Umann CI.getFrontendOpts().Plugins);
352aac0c47SKristóf Umann
36b6cbe6cbSKirstóf Umann CheckerMgr->getCheckerRegistryData().printCheckerWithDescList(
37*8e0c9bb9SJan Svoboda CI.getAnalyzerOpts(), out);
382aac0c47SKristóf Umann }
392aac0c47SKristóf Umann
printEnabledCheckerList(raw_ostream & out,CompilerInstance & CI)402aac0c47SKristóf Umann void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) {
412aac0c47SKristóf Umann out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
422aac0c47SKristóf Umann
432aac0c47SKristóf Umann auto CheckerMgr = std::make_unique<CheckerManager>(
44*8e0c9bb9SJan Svoboda CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
452aac0c47SKristóf Umann CI.getFrontendOpts().Plugins);
462aac0c47SKristóf Umann
47b6cbe6cbSKirstóf Umann CheckerMgr->getCheckerRegistryData().printEnabledCheckerList(out);
482aac0c47SKristóf Umann }
492aac0c47SKristóf Umann
printCheckerConfigList(raw_ostream & out,CompilerInstance & CI)502aac0c47SKristóf Umann void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) {
512aac0c47SKristóf Umann
522aac0c47SKristóf Umann auto CheckerMgr = std::make_unique<CheckerManager>(
53*8e0c9bb9SJan Svoboda CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
542aac0c47SKristóf Umann CI.getFrontendOpts().Plugins);
552aac0c47SKristóf Umann
56b6cbe6cbSKirstóf Umann CheckerMgr->getCheckerRegistryData().printCheckerOptionList(
57*8e0c9bb9SJan Svoboda CI.getAnalyzerOpts(), out);
582aac0c47SKristóf Umann }
592aac0c47SKristóf Umann
printAnalyzerConfigList(raw_ostream & out)602aac0c47SKristóf Umann void ento::printAnalyzerConfigList(raw_ostream &out) {
612aac0c47SKristóf Umann // FIXME: This message sounds scary, should be scary, but incorrectly states
622aac0c47SKristóf Umann // that all configs are super dangerous. In reality, many of them should be
632aac0c47SKristóf Umann // accessible to the user. We should create a user-facing subset of config
642aac0c47SKristóf Umann // options under a different frontend flag.
652aac0c47SKristóf Umann out << R"(
662aac0c47SKristóf Umann OVERVIEW: Clang Static Analyzer -analyzer-config Option List
672aac0c47SKristóf Umann
682aac0c47SKristóf Umann The following list of configurations are meant for development purposes only, as
692aac0c47SKristóf Umann some of the variables they define are set to result in the most optimal
702aac0c47SKristóf Umann analysis. Setting them to other values may drastically change how the analyzer
712aac0c47SKristóf Umann behaves, and may even result in instabilities, crashes!
722aac0c47SKristóf Umann
732aac0c47SKristóf Umann USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
742aac0c47SKristóf Umann -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
752aac0c47SKristóf Umann OPTIONS:
762aac0c47SKristóf Umann )";
772aac0c47SKristóf Umann
782aac0c47SKristóf Umann using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
792aac0c47SKristóf Umann OptionAndDescriptionTy PrintableOptions[] = {
802aac0c47SKristóf Umann #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
812aac0c47SKristóf Umann { \
822aac0c47SKristóf Umann CMDFLAG, \
832aac0c47SKristóf Umann llvm::Twine(llvm::Twine() + "(" + \
842aac0c47SKristóf Umann (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
852aac0c47SKristóf Umann ") " DESC \
862aac0c47SKristóf Umann " (default: " #DEFAULT_VAL ")").str() \
872aac0c47SKristóf Umann },
882aac0c47SKristóf Umann
892aac0c47SKristóf Umann #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
902aac0c47SKristóf Umann SHALLOW_VAL, DEEP_VAL) \
912aac0c47SKristóf Umann { \
922aac0c47SKristóf Umann CMDFLAG, \
932aac0c47SKristóf Umann llvm::Twine(llvm::Twine() + "(" + \
942aac0c47SKristóf Umann (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
952aac0c47SKristóf Umann ") " DESC \
962aac0c47SKristóf Umann " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \
972aac0c47SKristóf Umann " in deep mode)").str() \
982aac0c47SKristóf Umann },
992aac0c47SKristóf Umann #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1002aac0c47SKristóf Umann #undef ANALYZER_OPTION
1012aac0c47SKristóf Umann #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
1022aac0c47SKristóf Umann };
1032aac0c47SKristóf Umann
1044969a692SKazu Hirata llvm::sort(PrintableOptions, llvm::less_first());
1052aac0c47SKristóf Umann
1062aac0c47SKristóf Umann for (const auto &Pair : PrintableOptions) {
1072aac0c47SKristóf Umann AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2,
1082aac0c47SKristóf Umann /*EntryWidth*/ 30,
1092aac0c47SKristóf Umann /*MinLineWidth*/ 70);
1102aac0c47SKristóf Umann out << "\n\n";
1112aac0c47SKristóf Umann }
1122aac0c47SKristóf Umann }
113