14
14
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
15
15
#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
16
16
17
+ #include " clang/Basic/DiagnosticCategories.h"
17
18
#include " clang/Basic/LLVM.h"
18
19
#include " llvm/ADT/IntrusiveRefCntPtr.h"
19
20
#include " llvm/ADT/StringRef.h"
@@ -80,7 +81,7 @@ namespace clang {
80
81
// / to either Ignore (nothing), Remark (emit a remark), Warning
81
82
// / (emit a warning) or Error (emit as an error). It allows clients to
82
83
// / map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
83
- enum class Severity {
84
+ enum class Severity : uint8_t {
84
85
// NOTE: 0 means "uncomputed".
85
86
Ignored = 1 , // /< Do not present this diagnostic, ignore it.
86
87
Remark = 2 , // /< Present this diagnostic as a remark.
@@ -171,13 +172,61 @@ class DiagnosticMapping {
171
172
class DiagnosticIDs : public RefCountedBase <DiagnosticIDs> {
172
173
public:
173
174
// / The level of the diagnostic, after it has been through mapping.
174
- enum Level {
175
+ enum Level : uint8_t {
175
176
Ignored, Note, Remark, Warning, Error, Fatal
176
177
};
177
178
179
+ // Diagnostic classes.
180
+ enum Class {
181
+ CLASS_NOTE = 0x01 ,
182
+ CLASS_REMARK = 0x02 ,
183
+ CLASS_WARNING = 0x03 ,
184
+ CLASS_EXTENSION = 0x04 ,
185
+ CLASS_ERROR = 0x05
186
+ };
187
+
188
+ class CustomDiagDesc {
189
+ diag::Severity DefaultSeverity : 3 ;
190
+ unsigned Class : 3 ;
191
+ unsigned ShowInSystemHeader : 1 ;
192
+ unsigned ShowInSystemMacro : 1 ;
193
+ unsigned HasGroup : 1 ;
194
+ diag::Group Group;
195
+ std::string Description;
196
+
197
+ auto get_as_tuple () const {
198
+ return std::tuple (Class, ShowInSystemHeader, ShowInSystemMacro, HasGroup,
199
+ Group, std::string_view{Description});
200
+ }
201
+
202
+ public:
203
+ CustomDiagDesc (diag::Severity DefaultSeverity, std::string Description,
204
+ unsigned Class = CLASS_WARNING,
205
+ bool ShowInSystemHeader = false ,
206
+ bool ShowInSystemMacro = false ,
207
+ std::optional<diag::Group> Group = std::nullopt)
208
+ : DefaultSeverity(DefaultSeverity), Class(Class),
209
+ ShowInSystemHeader (ShowInSystemHeader),
210
+ ShowInSystemMacro(ShowInSystemMacro), HasGroup(Group != std::nullopt),
211
+ Group(Group.value_or(diag::Group{})) {}
212
+
213
+ friend bool operator ==(const CustomDiagDesc &lhs,
214
+ const CustomDiagDesc &rhs) {
215
+ return lhs.get_as_tuple () == rhs.get_as_tuple ();
216
+ }
217
+
218
+ friend bool operator <(const CustomDiagDesc &lhs,
219
+ const CustomDiagDesc &rhs) {
220
+ return lhs.get_as_tuple () < rhs.get_as_tuple ();
221
+ }
222
+ };
223
+
178
224
private:
179
225
// / Information for uniquing and looking up custom diags.
180
226
std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;
227
+ std::unique_ptr<diag::Severity[]> GroupSeverity =
228
+ std::make_unique<diag::Severity[]>(
229
+ static_cast <size_t >(diag::Group::NUM_GROUPS));
181
230
182
231
public:
183
232
DiagnosticIDs ();
@@ -192,7 +241,27 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
192
241
// FIXME: Replace this function with a create-only facilty like
193
242
// createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
194
243
// writing, nearly all callers of this function were invalid.
195
- unsigned getCustomDiagID (Level L, StringRef FormatString);
244
+ unsigned getCustomDiagID (CustomDiagDesc Diag);
245
+
246
+ [[deprecated(" Use a CustomDiagDesc instead of a Level" )]] unsigned
247
+ getCustomDiagID (Level Level, StringRef Message) {
248
+ return getCustomDiagID ([&] -> CustomDiagDesc {
249
+ switch (Level) {
250
+ case DiagnosticIDs::Level::Ignored:
251
+ return {diag::Severity::Ignored, std::string (Message), CLASS_WARNING};
252
+ case DiagnosticIDs::Level::Note:
253
+ return {diag::Severity::Fatal, std::string (Message), CLASS_NOTE};
254
+ case DiagnosticIDs::Level::Remark:
255
+ return {diag::Severity::Remark, std::string (Message), CLASS_REMARK};
256
+ case DiagnosticIDs::Level::Warning:
257
+ return {diag::Severity::Warning, std::string (Message), CLASS_WARNING};
258
+ case DiagnosticIDs::Level::Error:
259
+ return {diag::Severity::Error, std::string (Message), CLASS_ERROR};
260
+ case DiagnosticIDs::Level::Fatal:
261
+ return {diag::Severity::Fatal, std::string (Message), CLASS_ERROR};
262
+ }
263
+ }());
264
+ }
196
265
197
266
// ===--------------------------------------------------------------------===//
198
267
// Diagnostic classification and reporting interfaces.
@@ -204,35 +273,34 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
204
273
// / Return true if the unmapped diagnostic levelof the specified
205
274
// / diagnostic ID is a Warning or Extension.
206
275
// /
207
- // / This only works on builtin diagnostics, not custom ones, and is not
208
- // / legal to call on NOTEs.
209
- static bool isBuiltinWarningOrExtension (unsigned DiagID);
276
+ // / This is not legal to call on NOTEs.
277
+ bool isWarningOrExtension (unsigned DiagID) const ;
210
278
211
279
// / Return true if the specified diagnostic is mapped to errors by
212
280
// / default.
213
- static bool isDefaultMappingAsError (unsigned DiagID);
281
+ bool isDefaultMappingAsError (unsigned DiagID) const ;
214
282
215
283
// / Get the default mapping for this diagnostic.
216
- static DiagnosticMapping getDefaultMapping (unsigned DiagID);
284
+ DiagnosticMapping getDefaultMapping (unsigned DiagID) const ;
217
285
218
- // / Determine whether the given built-in diagnostic ID is a Note.
219
- static bool isBuiltinNote (unsigned DiagID);
286
+ // / Determine whether the given diagnostic ID is a Note.
287
+ bool isNote (unsigned DiagID) const ;
220
288
221
- // / Determine whether the given built-in diagnostic ID is for an
289
+ // / Determine whether the given diagnostic ID is for an
222
290
// / extension of some sort.
223
- static bool isBuiltinExtensionDiag (unsigned DiagID) {
291
+ bool isExtensionDiag (unsigned DiagID) const {
224
292
bool ignored;
225
- return isBuiltinExtensionDiag (DiagID, ignored);
293
+ return isExtensionDiag (DiagID, ignored);
226
294
}
227
295
228
- // / Determine whether the given built-in diagnostic ID is for an
296
+ // / Determine whether the given diagnostic ID is for an
229
297
// / extension of some sort, and whether it is enabled by default.
230
298
// /
231
299
// / This also returns EnabledByDefault, which is set to indicate whether the
232
300
// / diagnostic is ignored by default (in which case -pedantic enables it) or
233
301
// / treated as a warning/error by default.
234
302
// /
235
- static bool isBuiltinExtensionDiag (unsigned DiagID, bool &EnabledByDefault);
303
+ bool isExtensionDiag (unsigned DiagID, bool &EnabledByDefault) const ;
236
304
237
305
// / Given a group ID, returns the flag that toggles the group.
238
306
// / For example, for Group::DeprecatedDeclarations, returns
@@ -242,19 +310,21 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
242
310
// / Given a diagnostic group ID, return its documentation.
243
311
static StringRef getWarningOptionDocumentation (diag::Group GroupID);
244
312
313
+ void setGroupSeverity (StringRef Group, diag::Severity);
314
+
245
315
// / Given a group ID, returns the flag that toggles the group.
246
316
// / For example, for "deprecated-declarations", returns
247
317
// / Group::DeprecatedDeclarations.
248
318
static std::optional<diag::Group> getGroupForWarningOption (StringRef);
249
319
250
320
// / Return the lowest-level group that contains the specified diagnostic.
251
- static std::optional<diag::Group> getGroupForDiag (unsigned DiagID);
321
+ std::optional<diag::Group> getGroupForDiag (unsigned DiagID) const ;
252
322
253
323
// / Return the lowest-level warning option that enables the specified
254
324
// / diagnostic.
255
325
// /
256
326
// / If there is no -Wfoo flag that controls the diagnostic, this returns null.
257
- static StringRef getWarningOptionForDiag (unsigned DiagID);
327
+ StringRef getWarningOptionForDiag (unsigned DiagID);
258
328
259
329
// / Return the category number that a specified \p DiagID belongs to,
260
330
// / or 0 if no category.
@@ -352,6 +422,8 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
352
422
getDiagnosticSeverity (unsigned DiagID, SourceLocation Loc,
353
423
const DiagnosticsEngine &Diag) const LLVM_READONLY;
354
424
425
+ Class getDiagClass (unsigned DiagID) const ;
426
+
355
427
// / Used to report a diagnostic that is finally fully formed.
356
428
// /
357
429
// / \returns \c true if the diagnostic was emitted, \c false if it was
0 commit comments