blob: 76b6aaa4ba68a0e538454fb42fc0728d3ff246d3 [file] [log] [blame]
Daniel Jasperd07c8402013-07-29 08:19:24 +00001//===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
12
13#include "clang/Basic/Diagnostic.h"
14#include "clang/Basic/SourceManager.h"
15#include "clang/Tooling/Refactoring.h"
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000016#include "llvm/ADT/DenseMap.h"
Daniel Jasperd07c8402013-07-29 08:19:24 +000017
18namespace clang {
19
20class CompilerInstance;
21namespace ast_matchers {
22class MatchFinder;
23}
24namespace tooling {
25class CompilationDatabase;
26}
27
28namespace tidy {
29
Manuel Klimek814f9bd2013-11-14 15:49:44 +000030/// \brief A message from a clang-tidy check.
31///
32/// Note that this is independent of a \c SourceManager.
33struct ClangTidyMessage {
34 ClangTidyMessage(StringRef Message = "");
35 ClangTidyMessage(StringRef Message, const SourceManager &Sources,
36 SourceLocation Loc);
37 std::string Message;
38 std::string FilePath;
39 unsigned FileOffset;
40};
41
42/// \brief A detected error complete with information to display diagnostic and
43/// automatic fix.
44///
45/// This is used as an intermediate format to transport Diagnostics without a
46/// dependency on a SourceManager.
47///
48/// FIXME: Make Diagnostics flexible enough to support this directly.
49struct ClangTidyError {
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000050 ClangTidyError(StringRef CheckName, const ClangTidyMessage &Message);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000051
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000052 std::string CheckName;
Manuel Klimek814f9bd2013-11-14 15:49:44 +000053 ClangTidyMessage Message;
54 tooling::Replacements Fix;
55 SmallVector<ClangTidyMessage, 1> Notes;
56};
57
58/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
59/// provided by this context.
60///
61/// A \c ClangTidyCheck always has access to the active context to report
62/// warnings like:
63/// \code
64/// Context->Diag(Loc, "Single-argument constructors must be explicit")
65/// << FixItHint::CreateInsertion(Loc, "explicit ");
66/// \endcode
67class ClangTidyContext {
68public:
Alexander Kornienko175fefb2014-01-03 09:31:57 +000069 ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors)
70 : Errors(Errors), DiagEngine(0) {}
Manuel Klimek814f9bd2013-11-14 15:49:44 +000071
72 /// \brief Report any errors detected using this method.
73 ///
74 /// This is still under heavy development and will likely change towards using
75 /// tablegen'd diagnostic IDs.
76 /// FIXME: Figure out a way to manage ID spaces.
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000077 DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
Alexander Kornienko54461eb2014-02-06 14:50:10 +000078 StringRef Message,
79 DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
Manuel Klimek814f9bd2013-11-14 15:49:44 +000080
81 /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
82 /// correctly.
83 ///
84 /// This is called from the \c ClangTidyCheck base class.
85 void setDiagnosticsEngine(DiagnosticsEngine *Engine);
86
87 /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
88 ///
89 /// This is called from the \c ClangTidyCheck base class.
90 void setSourceManager(SourceManager *SourceMgr);
91
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +000092 /// \brief Returns the name of the clang-tidy check which produced this
93 /// diagnostic ID.
94 StringRef getCheckName(unsigned DiagnosticID) const;
95
Manuel Klimek814f9bd2013-11-14 15:49:44 +000096private:
97 friend class ClangTidyDiagnosticConsumer; // Calls storeError().
98
99 /// \brief Store a \c ClangTidyError.
100 void storeError(const ClangTidyError &Error);
101
102 SmallVectorImpl<ClangTidyError> *Errors;
103 DiagnosticsEngine *DiagEngine;
Alexander Kornienko41bfe8d2014-01-13 10:50:51 +0000104 llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000105};
106
Daniel Jasperd07c8402013-07-29 08:19:24 +0000107/// \brief A diagnostic consumer that turns each \c Diagnostic into a
108/// \c SourceManager-independent \c ClangTidyError.
109//
110// FIXME: If we move away from unit-tests, this can be moved to a private
111// implementation file.
112class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
113public:
Alexander Kornienko0ba86b72014-01-09 16:31:25 +0000114 ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx);
Daniel Jasperd07c8402013-07-29 08:19:24 +0000115
116 // FIXME: The concept of converting between FixItHints and Replacements is
117 // more generic and should be pulled out into a more useful Diagnostics
118 // library.
Alexander Kornienkocb9272f2014-02-27 13:14:51 +0000119 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Craig Toppera3dbe842014-03-02 10:20:11 +0000120 const Diagnostic &Info) override;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000121
Alexander Kornienkofc589872014-01-03 15:34:40 +0000122 // Flushes the internal diagnostics buffer to the ClangTidyContext.
Craig Toppera3dbe842014-03-02 10:20:11 +0000123 void finish() override;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000124
125private:
Alexander Kornienko0ba86b72014-01-09 16:31:25 +0000126 void addFixes(const Diagnostic &Info, ClangTidyError &Error);
127 ClangTidyMessage getMessage(const Diagnostic &Info) const;
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000128 void finalizeLastError();
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000129
Daniel Jasperd07c8402013-07-29 08:19:24 +0000130 ClangTidyContext &Context;
131 OwningPtr<DiagnosticsEngine> Diags;
Manuel Klimek814f9bd2013-11-14 15:49:44 +0000132 SmallVector<ClangTidyError, 8> Errors;
Alexander Kornienko54461eb2014-02-06 14:50:10 +0000133 bool LastErrorRelatesToUserCode;
Daniel Jasperd07c8402013-07-29 08:19:24 +0000134};
135
136} // end namespace tidy
137} // end namespace clang
138
139#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H