1218887Sdim//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===// 2218887Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6218887Sdim// 7218887Sdim//===----------------------------------------------------------------------===// 8218887Sdim// 9218887Sdim// Defines the registration function for the analyzer checkers. 10218887Sdim// 11218887Sdim//===----------------------------------------------------------------------===// 12218887Sdim 13218887Sdim#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" 14249423Sdim#include "clang/Basic/Diagnostic.h" 15249423Sdim#include "clang/Frontend/FrontendDiagnostic.h" 16249423Sdim#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 17218887Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h" 18344779Sdim#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" 19249423Sdim#include "clang/StaticAnalyzer/Frontend/FrontendActions.h" 20249423Sdim#include "llvm/ADT/SmallVector.h" 21219077Sdim#include "llvm/Support/raw_ostream.h" 22276479Sdim#include <memory> 23218887Sdim 24218887Sdimusing namespace clang; 25218887Sdimusing namespace ento; 26218887Sdim 27341825Sdimstd::unique_ptr<CheckerManager> ento::createCheckerManager( 28344779Sdim ASTContext &context, 29344779Sdim AnalyzerOptions &opts, 30341825Sdim ArrayRef<std::string> plugins, 31341825Sdim ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, 32341825Sdim DiagnosticsEngine &diags) { 33360784Sdim auto checkerMgr = std::make_unique<CheckerManager>(context, opts); 34218887Sdim 35353358Sdim CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(), 36353358Sdim checkerRegistrationFns); 37218887Sdim 38353358Sdim allCheckers.initializeManager(*checkerMgr); 39353358Sdim allCheckers.validateCheckerOptions(); 40221345Sdim checkerMgr->finishedCheckerRegistration(); 41221345Sdim 42288943Sdim return checkerMgr; 43218887Sdim} 44219077Sdim 45344779Sdimvoid ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins, 46353358Sdim AnalyzerOptions &anopts, 47353358Sdim DiagnosticsEngine &diags, 48353358Sdim const LangOptions &langOpts) { 49226633Sdim out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; 50226633Sdim out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; 51219077Sdim 52353358Sdim CheckerRegistry(plugins, diags, anopts, langOpts) 53353358Sdim .printCheckerWithDescList(out); 54219077Sdim} 55314564Sdim 56314564Sdimvoid ento::printEnabledCheckerList(raw_ostream &out, 57314564Sdim ArrayRef<std::string> plugins, 58353358Sdim AnalyzerOptions &anopts, 59353358Sdim DiagnosticsEngine &diags, 60353358Sdim const LangOptions &langOpts) { 61314564Sdim out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; 62314564Sdim 63353358Sdim CheckerRegistry(plugins, diags, anopts, langOpts) 64353358Sdim .printEnabledCheckerList(out); 65314564Sdim} 66344779Sdim 67353358Sdimvoid ento::printCheckerConfigList(raw_ostream &OS, 68353358Sdim ArrayRef<std::string> plugins, 69353358Sdim AnalyzerOptions &opts, 70353358Sdim DiagnosticsEngine &diags, 71353358Sdim const LangOptions &LangOpts) { 72353358Sdim CheckerRegistry(plugins, diags, opts, LangOpts) 73353358Sdim .printCheckerOptionList(OS); 74353358Sdim} 75353358Sdim 76344779Sdimvoid ento::printAnalyzerConfigList(raw_ostream &out) { 77360784Sdim // FIXME: This message sounds scary, should be scary, but incorrectly states 78360784Sdim // that all configs are super dangerous. In reality, many of them should be 79360784Sdim // accessible to the user. We should create a user-facing subset of config 80360784Sdim // options under a different frontend flag. 81360784Sdim out << R"( 82360784SdimOVERVIEW: Clang Static Analyzer -analyzer-config Option List 83344779Sdim 84360784SdimThe following list of configurations are meant for development purposes only, as 85360784Sdimsome of the variables they define are set to result in the most optimal 86360784Sdimanalysis. Setting them to other values may drastically change how the analyzer 87360784Sdimbehaves, and may even result in instabilities, crashes! 88360784Sdim 89360784SdimUSAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...> 90360784Sdim -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ... 91360784SdimOPTIONS: 92360784Sdim)"; 93360784Sdim 94344779Sdim using OptionAndDescriptionTy = std::pair<StringRef, std::string>; 95344779Sdim OptionAndDescriptionTy PrintableOptions[] = { 96344779Sdim#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ 97344779Sdim { \ 98344779Sdim CMDFLAG, \ 99344779Sdim llvm::Twine(llvm::Twine() + "(" + \ 100344779Sdim (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ 101344779Sdim ") " DESC \ 102344779Sdim " (default: " #DEFAULT_VAL ")").str() \ 103344779Sdim }, 104344779Sdim 105344779Sdim#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ 106344779Sdim SHALLOW_VAL, DEEP_VAL) \ 107344779Sdim { \ 108344779Sdim CMDFLAG, \ 109344779Sdim llvm::Twine(llvm::Twine() + "(" + \ 110344779Sdim (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \ 111344779Sdim ") " DESC \ 112344779Sdim " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \ 113344779Sdim " in deep mode)").str() \ 114344779Sdim }, 115344779Sdim#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" 116344779Sdim#undef ANALYZER_OPTION 117344779Sdim#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE 118344779Sdim }; 119344779Sdim 120344779Sdim llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS, 121344779Sdim const OptionAndDescriptionTy &RHS) { 122344779Sdim return LHS.first < RHS.first; 123344779Sdim }); 124344779Sdim 125344779Sdim for (const auto &Pair : PrintableOptions) { 126353358Sdim AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2, 127353358Sdim /*EntryWidth*/ 30, 128353358Sdim /*MinLineWidth*/ 70); 129353358Sdim out << "\n\n"; 130344779Sdim } 131344779Sdim} 132