clang-tools  10.0.0svn
ClangTidyCheck.h
Go to the documentation of this file.
1 //===--- ClangTidyCheck.h - clang-tidy --------------------------*- C++ -*-===//
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 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
11 
13 #include "ClangTidyOptions.h"
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include <memory>
19 #include <type_traits>
20 #include <vector>
21 
22 namespace clang {
23 
24 class CompilerInstance;
25 
26 namespace tidy {
27 
28 /// Base class for all clang-tidy checks.
29 ///
30 /// To implement a ``ClangTidyCheck``, write a subclass and override some of the
31 /// base class's methods. E.g. to implement a check that validates namespace
32 /// declarations, override ``registerMatchers``:
33 ///
34 /// ~~~{.cpp}
35 /// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
36 /// Finder->addMatcher(namespaceDecl().bind("namespace"), this);
37 /// }
38 /// ~~~
39 ///
40 /// and then override ``check(const MatchResult &Result)`` to do the actual
41 /// check for each match.
42 ///
43 /// A new ``ClangTidyCheck`` instance is created per translation unit.
44 ///
45 /// FIXME: Figure out whether carrying information from one TU to another is
46 /// useful/necessary.
47 class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
48 public:
49  /// Initializes the check with \p CheckName and \p Context.
50  ///
51  /// Derived classes must implement the constructor with this signature or
52  /// delegate it. If a check needs to read options, it can do this in the
53  /// constructor using the Options.get() methods below.
54  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
55 
56  /// Override this to register ``PPCallbacks`` in the preprocessor.
57  ///
58  /// This should be used for clang-tidy checks that analyze preprocessor-
59  /// dependent properties, e.g. include directives and macro definitions.
60  ///
61  /// There are two Preprocessors to choose from that differ in how they handle
62  /// modular #includes:
63  /// - PP is the real Preprocessor. It doesn't walk into modular #includes and
64  /// thus doesn't generate PPCallbacks for their contents.
65  /// - ModuleExpanderPP preprocesses the whole translation unit in the
66  /// non-modular mode, which allows it to generate PPCallbacks not only for
67  /// the main file and textual headers, but also for all transitively
68  /// included modular headers when the analysis runs with modules enabled.
69  /// When modules are not enabled ModuleExpanderPP just points to the real
70  /// preprocessor.
71  virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
72  Preprocessor *ModuleExpanderPP) {}
73 
74  /// Override this to register AST matchers with \p Finder.
75  ///
76  /// This should be used by clang-tidy checks that analyze code properties that
77  /// dependent on AST knowledge.
78  ///
79  /// You can register as many matchers as necessary with \p Finder. Usually,
80  /// "this" will be used as callback, but you can also specify other callback
81  /// classes. Thereby, different matchers can trigger different callbacks.
82  ///
83  /// If you need to merge information between the different matchers, you can
84  /// store these as members of the derived class. However, note that all
85  /// matches occur in the order of the AST traversal.
86  virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {}
87 
88  /// ``ClangTidyChecks`` that register ASTMatchers should do the actual
89  /// work in here.
90  virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
91 
92  /// Add a diagnostic with the check's name.
93  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
94  DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
95 
96  /// Should store all options supported by this check with their
97  /// current values or default values for options that haven't been overridden.
98  ///
99  /// The check should use ``Options.store()`` to store each option it supports
100  /// whether it has the default value or it has been overridden.
102 
103  /// Provides access to the ``ClangTidyCheck`` options via check-local
104  /// names.
105  ///
106  /// Methods of this class prepend ``CheckName + "."`` to translate check-local
107  /// option names to global option names.
108  class OptionsView {
109  public:
110  /// Initializes the instance using \p CheckName + "." as a prefix.
111  OptionsView(StringRef CheckName,
112  const ClangTidyOptions::OptionMap &CheckOptions);
113 
114  /// Read a named option from the ``Context``.
115  ///
116  /// Reads the option with the check-local name \p LocalName from the
117  /// ``CheckOptions``. If the corresponding key is not present, returns
118  /// \p Default.
119  std::string get(StringRef LocalName, StringRef Default) const;
120 
121  /// Read a named option from the ``Context``.
122  ///
123  /// Reads the option with the check-local name \p LocalName from local or
124  /// global ``CheckOptions``. Gets local option first. If local is not
125  /// present, falls back to get global option. If global option is not
126  /// present either, returns Default.
127  std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
128 
129  /// Read a named option from the ``Context`` and parse it as an
130  /// integral type ``T``.
131  ///
132  /// Reads the option with the check-local name \p LocalName from the
133  /// ``CheckOptions``. If the corresponding key is not present, returns
134  /// \p Default.
135  template <typename T>
136  typename std::enable_if<std::is_integral<T>::value, T>::type
137  get(StringRef LocalName, T Default) const {
138  std::string Value = get(LocalName, "");
139  T Result = Default;
140  if (!Value.empty())
141  StringRef(Value).getAsInteger(10, Result);
142  return Result;
143  }
144 
145  /// Read a named option from the ``Context`` and parse it as an
146  /// integral type ``T``.
147  ///
148  /// Reads the option with the check-local name \p LocalName from local or
149  /// global ``CheckOptions``. Gets local option first. If local is not
150  /// present, falls back to get global option. If global option is not
151  /// present either, returns Default.
152  template <typename T>
153  typename std::enable_if<std::is_integral<T>::value, T>::type
154  getLocalOrGlobal(StringRef LocalName, T Default) const {
155  std::string Value = getLocalOrGlobal(LocalName, "");
156  T Result = Default;
157  if (!Value.empty())
158  StringRef(Value).getAsInteger(10, Result);
159  return Result;
160  }
161 
162  /// Stores an option with the check-local name \p LocalName with
163  /// string value \p Value to \p Options.
164  void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
165  StringRef Value) const;
166 
167  /// Stores an option with the check-local name \p LocalName with
168  /// ``int64_t`` value \p Value to \p Options.
169  void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
170  int64_t Value) const;
171 
172  private:
173  std::string NamePrefix;
174  const ClangTidyOptions::OptionMap &CheckOptions;
175  };
176 
177 private:
178  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
179  StringRef getID() const override { return CheckName; }
180  std::string CheckName;
181  ClangTidyContext *Context;
182 
183 protected:
185  /// Returns the main file name of the current translation unit.
186  StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
187  /// Returns the language options from the context.
188  const LangOptions &getLangOpts() const { return Context->getLangOpts(); }
189 };
190 
191 } // namespace tidy
192 } // namespace clang
193 
194 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
SourceLocation Loc
&#39;#&#39; location in the include directive
virtual void registerMatchers(ast_matchers::MatchFinder *Finder)
Override this to register AST matchers with Finder.
Provides access to the ClangTidyCheck options via check-local names.
StringRef getCurrentMainFile() const
Returns the main file name of the current translation unit.
Base class for all clang-tidy checks.
virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP)
Override this to register PPCallbacks in the preprocessor.
const LangOptions & getLangOpts() const
Returns the language options from the context.
std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const
Read a named option from the Context.
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
const LangOptions & getLangOpts() const
Gets the language options from the AST context.
StringRef getCurrentFile() const
Returns the main file name of the current translation unit.
std::map< std::string, std::string > OptionMap
ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
Initializes the check with CheckName and Context.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
OptionsView(StringRef CheckName, const ClangTidyOptions::OptionMap &CheckOptions)
Initializes the instance using CheckName + "." as a prefix.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
const char * Description
Definition: Dexp.cpp:257
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result)
ClangTidyChecks that register ASTMatchers should do the actual work in here.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check&#39;s name.
virtual void storeOptions(ClangTidyOptions::OptionMap &Options)
Should store all options supported by this check with their current values or default values for opti...
std::enable_if< std::is_integral< T >::value, T >::type getLocalOrGlobal(StringRef LocalName, T Default) const
Read a named option from the Context and parse it as an integral type T.