aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
blob: 1e45ee96145ab41406987e3d67888c8f0a84031e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines the registration function for the analyzer checkers.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>

using namespace clang;
using namespace ento;

std::unique_ptr<CheckerManager> ento::createCheckerManager(
    ASTContext &context,
    AnalyzerOptions &opts,
    ArrayRef<std::string> plugins,
    ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns,
    DiagnosticsEngine &diags) {
  auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);

  CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(),
                              checkerRegistrationFns);

  allCheckers.initializeManager(*checkerMgr);
  allCheckers.validateCheckerOptions();
  checkerMgr->finishedCheckerRegistration();

  return checkerMgr;
}

void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
                            AnalyzerOptions &anopts,
                            DiagnosticsEngine &diags,
                            const LangOptions &langOpts) {
  out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
  out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";

  CheckerRegistry(plugins, diags, anopts, langOpts)
      .printCheckerWithDescList(out);
}

void ento::printEnabledCheckerList(raw_ostream &out,
                                   ArrayRef<std::string> plugins,
                                   AnalyzerOptions &anopts,
                                   DiagnosticsEngine &diags,
                                   const LangOptions &langOpts) {
  out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";

  CheckerRegistry(plugins, diags, anopts, langOpts)
      .printEnabledCheckerList(out);
}

void ento::printCheckerConfigList(raw_ostream &OS,
                                  ArrayRef<std::string> plugins,
                                  AnalyzerOptions &opts,
                                  DiagnosticsEngine &diags,
                                  const LangOptions &LangOpts) {
  CheckerRegistry(plugins, diags, opts, LangOpts)
      .printCheckerOptionList(OS);
}

void ento::printAnalyzerConfigList(raw_ostream &out) {
  out << "OVERVIEW: Clang Static Analyzer -analyzer-config Option List\n\n";
  out << "USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>\n\n";
  out << "       -analyzer-config OPTION1=VALUE, -analyzer-config "
         "OPTION2=VALUE, ...\n\n";
  out << "OPTIONS:\n\n";

  using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
  OptionAndDescriptionTy PrintableOptions[] = {
#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
    {                                                                          \
      CMDFLAG,                                                                 \
      llvm::Twine(llvm::Twine() + "(" +                                        \
                  (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +      \
                  ") " DESC                                                    \
                  " (default: " #DEFAULT_VAL ")").str()                        \
    },

#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
                                             SHALLOW_VAL, DEEP_VAL)            \
    {                                                                          \
      CMDFLAG,                                                                 \
      llvm::Twine(llvm::Twine() + "(" +                                        \
                  (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +      \
                  ") " DESC                                                    \
                  " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL    \
                  " in deep mode)").str()                                      \
    },
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
  };

  llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS,
                                  const OptionAndDescriptionTy &RHS) {
    return LHS.first < RHS.first;
  });

  for (const auto &Pair : PrintableOptions) {
    AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2,
                                         /*EntryWidth*/ 30,
                                         /*MinLineWidth*/ 70);
    out << "\n\n";
  }
}