comparison clang-tools-extra/clangd/Diagnostics.h @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
11 11
12 #include "Protocol.h" 12 #include "Protocol.h"
13 #include "support/Path.h" 13 #include "support/Path.h"
14 #include "clang/Basic/Diagnostic.h" 14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/LangOptions.h" 15 #include "clang/Basic/LangOptions.h"
16 #include "clang/Basic/SourceLocation.h"
16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/DenseSet.h" 18 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/ADT/None.h" 19 #include "llvm/ADT/None.h"
19 #include "llvm/ADT/Optional.h" 20 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringSet.h" 22 #include "llvm/ADT/StringSet.h"
23 #include "llvm/Support/JSON.h"
24 #include "llvm/Support/SourceMgr.h"
22 #include <cassert> 25 #include <cassert>
26 #include <functional>
27 #include <memory>
23 #include <string> 28 #include <string>
29 #include <utility>
30 #include <vector>
24 31
25 namespace clang { 32 namespace clang {
26 namespace tidy { 33 namespace tidy {
27 class ClangTidyContext; 34 class ClangTidyContext;
28 } // namespace tidy 35 } // namespace tidy
62 DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note; 69 DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note;
63 std::string Category; 70 std::string Category;
64 // Since File is only descriptive, we store a separate flag to distinguish 71 // Since File is only descriptive, we store a separate flag to distinguish
65 // diags from the main file. 72 // diags from the main file.
66 bool InsideMainFile = false; 73 bool InsideMainFile = false;
74 unsigned ID; // e.g. member of clang::diag, or clang-tidy assigned ID.
75 // Feature modules can make use of this field to propagate data from a
76 // diagnostic to a CodeAction request. Each module should only append to the
77 // list.
78 llvm::json::Object OpaqueData;
67 }; 79 };
68 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D); 80 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D);
69 81
70 /// Represents a single fix-it that editor can apply to fix the error. 82 /// Represents a single fix-it that editor can apply to fix the error.
71 struct Fix { 83 struct Fix {
80 /// or 'remark'. 92 /// or 'remark'.
81 struct Note : DiagBase {}; 93 struct Note : DiagBase {};
82 94
83 /// A top-level diagnostic that may have Notes and Fixes. 95 /// A top-level diagnostic that may have Notes and Fixes.
84 struct Diag : DiagBase { 96 struct Diag : DiagBase {
85 unsigned ID; // e.g. member of clang::diag, or clang-tidy assigned ID.
86 std::string Name; // if ID was recognized. 97 std::string Name; // if ID was recognized.
87 // The source of this diagnostic. 98 // The source of this diagnostic.
88 enum { 99 enum DiagSource {
89 Unknown, 100 Unknown,
90 Clang, 101 Clang,
91 ClangTidy, 102 ClangTidy,
103 ClangdConfig,
92 } Source = Unknown; 104 } Source = Unknown;
93 /// Elaborate on the problem, usually pointing to a related piece of code. 105 /// Elaborate on the problem, usually pointing to a related piece of code.
94 std::vector<Note> Notes; 106 std::vector<Note> Notes;
95 /// *Alternative* fixes for this diagnostic, one should be chosen. 107 /// *Alternative* fixes for this diagnostic, one should be chosen.
96 std::vector<Fix> Fixes; 108 std::vector<Fix> Fixes;
97 }; 109 };
98 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diag &D); 110 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diag &D);
111
112 Diag toDiag(const llvm::SMDiagnostic &, Diag::DiagSource Source);
99 113
100 /// Conversion to LSP diagnostics. Formats the error message of each diagnostic 114 /// Conversion to LSP diagnostics. Formats the error message of each diagnostic
101 /// to include all its notes. Notes inside main file are also provided as 115 /// to include all its notes. Notes inside main file are also provided as
102 /// separate diagnostics with their corresponding fixits. Notes outside main 116 /// separate diagnostics with their corresponding fixits. Notes outside main
103 /// file do not have a corresponding LSP diagnostic, but can still be included 117 /// file do not have a corresponding LSP diagnostic, but can still be included
119 class StoreDiags : public DiagnosticConsumer { 133 class StoreDiags : public DiagnosticConsumer {
120 public: 134 public:
121 // The ClangTidyContext populates Source and Name for clang-tidy diagnostics. 135 // The ClangTidyContext populates Source and Name for clang-tidy diagnostics.
122 std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr); 136 std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr);
123 137
124 void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override; 138 void BeginSourceFile(const LangOptions &Opts,
139 const Preprocessor *PP) override;
125 void EndSourceFile() override; 140 void EndSourceFile() override;
126 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 141 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
127 const clang::Diagnostic &Info) override; 142 const clang::Diagnostic &Info) override;
128 143
129 using DiagFixer = std::function<std::vector<Fix>(DiagnosticsEngine::Level, 144 using DiagFixer = std::function<std::vector<Fix>(DiagnosticsEngine::Level,
130 const clang::Diagnostic &)>; 145 const clang::Diagnostic &)>;
131 using LevelAdjuster = std::function<DiagnosticsEngine::Level( 146 using LevelAdjuster = std::function<DiagnosticsEngine::Level(
132 DiagnosticsEngine::Level, const clang::Diagnostic &)>; 147 DiagnosticsEngine::Level, const clang::Diagnostic &)>;
148 using DiagCallback =
149 std::function<void(const clang::Diagnostic &, clangd::Diag &)>;
133 /// If set, possibly adds fixes for diagnostics using \p Fixer. 150 /// If set, possibly adds fixes for diagnostics using \p Fixer.
134 void contributeFixes(DiagFixer Fixer) { this->Fixer = Fixer; } 151 void contributeFixes(DiagFixer Fixer) { this->Fixer = Fixer; }
135 /// If set, this allows the client of this class to adjust the level of 152 /// If set, this allows the client of this class to adjust the level of
136 /// diagnostics, such as promoting warnings to errors, or ignoring 153 /// diagnostics, such as promoting warnings to errors, or ignoring
137 /// diagnostics. 154 /// diagnostics.
138 void setLevelAdjuster(LevelAdjuster Adjuster) { this->Adjuster = Adjuster; } 155 void setLevelAdjuster(LevelAdjuster Adjuster) { this->Adjuster = Adjuster; }
156 /// Invokes a callback every time a diagnostics is completely formed. Handler
157 /// of the callback can also mutate the diagnostic.
158 void setDiagCallback(DiagCallback CB) { DiagCB = std::move(CB); }
139 159
140 private: 160 private:
141 void flushLastDiag(); 161 void flushLastDiag();
142 162
143 DiagFixer Fixer = nullptr; 163 DiagFixer Fixer = nullptr;
144 LevelAdjuster Adjuster = nullptr; 164 LevelAdjuster Adjuster = nullptr;
165 DiagCallback DiagCB = nullptr;
145 std::vector<Diag> Output; 166 std::vector<Diag> Output;
146 llvm::Optional<LangOptions> LangOpts; 167 llvm::Optional<LangOptions> LangOpts;
147 llvm::Optional<Diag> LastDiag; 168 llvm::Optional<Diag> LastDiag;
148 /// Set iff adjustDiagFromHeader resulted in changes to LastDiag. 169 llvm::Optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set.
149 bool LastDiagWasAdjusted = false; 170 bool LastDiagOriginallyError = false; // Valid only when LastDiag is set.
150 llvm::DenseSet<int> IncludeLinesWithErrors; 171 SourceManager *OrigSrcMgr = nullptr;
172
173 llvm::DenseSet<std::pair<unsigned, unsigned>> IncludedErrorLocations;
151 bool LastPrimaryDiagnosticWasSuppressed = false; 174 bool LastPrimaryDiagnosticWasSuppressed = false;
152 }; 175 };
176
177 /// Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
178 bool isBuiltinDiagnosticSuppressed(unsigned ID,
179 const llvm::StringSet<> &Suppressed);
180 /// Take a user-specified diagnostic code, and convert it to a normalized form
181 /// stored in the config and consumed by isBuiltinDiagnosticsSuppressed.
182 ///
183 /// (This strips err_ and -W prefix so we can match with or without them.)
184 llvm::StringRef normalizeSuppressedCode(llvm::StringRef);
153 185
154 } // namespace clangd 186 } // namespace clangd
155 } // namespace clang 187 } // namespace clang
156 188
157 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H 189 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_DIAGNOSTICS_H