clang 20.0.0git
DiagnosticIDs.h
Go to the documentation of this file.
1//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- 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/// \file
10/// Defines the Diagnostic IDs-related interfaces.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
15#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
16
17#include "clang/Basic/LLVM.h"
18#include "llvm/ADT/IntrusiveRefCntPtr.h"
19#include "llvm/ADT/StringRef.h"
20#include <optional>
21#include <vector>
22
23namespace clang {
24 class DiagnosticsEngine;
25 class SourceLocation;
26
27 // Import the diagnostic enums themselves.
28 namespace diag {
29 enum class Group;
30
31 // Size of each of the diagnostic categories.
32 enum {
46 };
47 // Start position for diagnostics.
48 enum {
63 };
64
65 class CustomDiagInfo;
66
67 /// All of the diagnostics that can be emitted by the frontend.
68 typedef unsigned kind;
69
70 // Get typedefs for common diagnostics.
71 enum {
72#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, CATEGORY, \
73 NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFFERABLE) \
74 ENUM,
75#define COMMONSTART
76#include "clang/Basic/DiagnosticCommonKinds.inc"
78#undef DIAG
79 };
80
81 /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
82 /// to either Ignore (nothing), Remark (emit a remark), Warning
83 /// (emit a warning) or Error (emit as an error). It allows clients to
84 /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
85 enum class Severity {
86 // NOTE: 0 means "uncomputed".
87 Ignored = 1, ///< Do not present this diagnostic, ignore it.
88 Remark = 2, ///< Present this diagnostic as a remark.
89 Warning = 3, ///< Present this diagnostic as a warning.
90 Error = 4, ///< Present this diagnostic as an error.
91 Fatal = 5 ///< Present this diagnostic as a fatal error.
92 };
93
94 /// Flavors of diagnostics we can emit. Used to filter for a particular
95 /// kind of diagnostic (for instance, for -W/-R flags).
96 enum class Flavor {
97 WarningOrError, ///< A diagnostic that indicates a problem or potential
98 ///< problem. Can be made fatal by -Werror.
99 Remark ///< A diagnostic that indicates normal progress through
100 ///< compilation.
101 };
102 }
103
105 LLVM_PREFERRED_TYPE(diag::Severity)
106 unsigned Severity : 3;
107 LLVM_PREFERRED_TYPE(bool)
108 unsigned IsUser : 1;
109 LLVM_PREFERRED_TYPE(bool)
110 unsigned IsPragma : 1;
111 LLVM_PREFERRED_TYPE(bool)
112 unsigned HasNoWarningAsError : 1;
113 LLVM_PREFERRED_TYPE(bool)
114 unsigned HasNoErrorAsFatal : 1;
115 LLVM_PREFERRED_TYPE(bool)
116 unsigned WasUpgradedFromWarning : 1;
117
118public:
119 static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
120 bool IsPragma) {
122 Result.Severity = (unsigned)Severity;
123 Result.IsUser = IsUser;
124 Result.IsPragma = IsPragma;
125 Result.HasNoWarningAsError = 0;
126 Result.HasNoErrorAsFatal = 0;
127 Result.WasUpgradedFromWarning = 0;
128 return Result;
129 }
130
131 diag::Severity getSeverity() const { return (diag::Severity)Severity; }
133
134 bool isUser() const { return IsUser; }
135 bool isPragma() const { return IsPragma; }
136
137 bool isErrorOrFatal() const {
140 }
141
142 bool hasNoWarningAsError() const { return HasNoWarningAsError; }
143 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
144
145 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
146 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
147
148 /// Whether this mapping attempted to map the diagnostic to a warning, but
149 /// was overruled because the diagnostic was already mapped to an error or
150 /// fatal error.
151 bool wasUpgradedFromWarning() const { return WasUpgradedFromWarning; }
152 void setUpgradedFromWarning(bool Value) { WasUpgradedFromWarning = Value; }
153
154 /// Serialize this mapping as a raw integer.
155 unsigned serialize() const {
156 return (IsUser << 7) | (IsPragma << 6) | (HasNoWarningAsError << 5) |
157 (HasNoErrorAsFatal << 4) | (WasUpgradedFromWarning << 3) | Severity;
158 }
159 /// Deserialize a mapping.
160 static DiagnosticMapping deserialize(unsigned Bits) {
162 Result.IsUser = (Bits >> 7) & 1;
163 Result.IsPragma = (Bits >> 6) & 1;
164 Result.HasNoWarningAsError = (Bits >> 5) & 1;
165 Result.HasNoErrorAsFatal = (Bits >> 4) & 1;
166 Result.WasUpgradedFromWarning = (Bits >> 3) & 1;
167 Result.Severity = Bits & 0x7;
168 return Result;
169 }
170
172 return serialize() == Other.serialize();
173 }
174};
175
176/// Used for handling and querying diagnostic IDs.
177///
178/// Can be used and shared by multiple Diagnostics for multiple translation units.
179class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
180public:
181 /// The level of the diagnostic, after it has been through mapping.
182 enum Level {
184 };
185
186private:
187 /// Information for uniquing and looking up custom diags.
188 std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;
189
190public:
193
194 /// Return an ID for a diagnostic with the specified format string and
195 /// level.
196 ///
197 /// If this is the first request for this diagnostic, it is registered and
198 /// created, otherwise the existing ID is returned.
199
200 // FIXME: Replace this function with a create-only facilty like
201 // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
202 // writing, nearly all callers of this function were invalid.
203 unsigned getCustomDiagID(Level L, StringRef FormatString);
204
205 //===--------------------------------------------------------------------===//
206 // Diagnostic classification and reporting interfaces.
207 //
208
209 /// Given a diagnostic ID, return a description of the issue.
210 StringRef getDescription(unsigned DiagID) const;
211
212 /// Return true if the unmapped diagnostic levelof the specified
213 /// diagnostic ID is a Warning or Extension.
214 ///
215 /// This only works on builtin diagnostics, not custom ones, and is not
216 /// legal to call on NOTEs.
217 static bool isBuiltinWarningOrExtension(unsigned DiagID);
218
219 /// Return true if the specified diagnostic is mapped to errors by
220 /// default.
221 static bool isDefaultMappingAsError(unsigned DiagID);
222
223 /// Get the default mapping for this diagnostic.
224 static DiagnosticMapping getDefaultMapping(unsigned DiagID);
225
226 /// Determine whether the given built-in diagnostic ID is a Note.
227 static bool isBuiltinNote(unsigned DiagID);
228
229 /// Determine whether the given built-in diagnostic ID is for an
230 /// extension of some sort.
231 static bool isBuiltinExtensionDiag(unsigned DiagID) {
232 bool ignored;
233 return isBuiltinExtensionDiag(DiagID, ignored);
234 }
235
236 /// Determine whether the given built-in diagnostic ID is for an
237 /// extension of some sort, and whether it is enabled by default.
238 ///
239 /// This also returns EnabledByDefault, which is set to indicate whether the
240 /// diagnostic is ignored by default (in which case -pedantic enables it) or
241 /// treated as a warning/error by default.
242 ///
243 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
244
245 /// Given a group ID, returns the flag that toggles the group.
246 /// For example, for Group::DeprecatedDeclarations, returns
247 /// "deprecated-declarations".
248 static StringRef getWarningOptionForGroup(diag::Group);
249
250 /// Given a diagnostic group ID, return its documentation.
251 static StringRef getWarningOptionDocumentation(diag::Group GroupID);
252
253 /// Given a group ID, returns the flag that toggles the group.
254 /// For example, for "deprecated-declarations", returns
255 /// Group::DeprecatedDeclarations.
256 static std::optional<diag::Group> getGroupForWarningOption(StringRef);
257
258 /// Return the lowest-level group that contains the specified diagnostic.
259 static std::optional<diag::Group> getGroupForDiag(unsigned DiagID);
260
261 /// Return the lowest-level warning option that enables the specified
262 /// diagnostic.
263 ///
264 /// If there is no -Wfoo flag that controls the diagnostic, this returns null.
265 static StringRef getWarningOptionForDiag(unsigned DiagID);
266
267 /// Return the category number that a specified \p DiagID belongs to,
268 /// or 0 if no category.
269 static unsigned getCategoryNumberForDiag(unsigned DiagID);
270
271 /// Return the number of diagnostic categories.
272 static unsigned getNumberOfCategories();
273
274 /// Given a category ID, return the name of the category.
275 static StringRef getCategoryNameFromID(unsigned CategoryID);
276
277 /// Return true if a given diagnostic falls into an ARC diagnostic
278 /// category.
279 static bool isARCDiagnostic(unsigned DiagID);
280
281 /// Return true if a given diagnostic is a codegen-time ABI check.
282 static bool isCodegenABICheckDiagnostic(unsigned DiagID);
283
284 /// Enumeration describing how the emission of a diagnostic should
285 /// be treated when it occurs during C++ template argument deduction.
287 /// The diagnostic should not be reported, but it should cause
288 /// template argument deduction to fail.
289 ///
290 /// The vast majority of errors that occur during template argument
291 /// deduction fall into this category.
293
294 /// The diagnostic should be suppressed entirely.
295 ///
296 /// Warnings generally fall into this category.
298
299 /// The diagnostic should be reported.
300 ///
301 /// The diagnostic should be reported. Various fatal errors (e.g.,
302 /// template instantiation depth exceeded) fall into this category.
304
305 /// The diagnostic is an access-control diagnostic, which will be
306 /// substitution failures in some contexts and reported in others.
308 };
309
310 /// Determines whether the given built-in diagnostic ID is
311 /// for an error that is suppressed if it occurs during C++ template
312 /// argument deduction.
313 ///
314 /// When an error is suppressed due to SFINAE, the template argument
315 /// deduction fails but no diagnostic is emitted. Certain classes of
316 /// errors, such as those errors that involve C++ access control,
317 /// are not SFINAE errors.
318 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
319
320 /// Whether the diagnostic message can be deferred.
321 ///
322 /// For single source offloading languages, a diagnostic message occurred
323 /// in a device host function may be deferred until the function is sure
324 /// to be emitted.
325 static bool isDeferrable(unsigned DiagID);
326
327 /// Get the string of all diagnostic flags.
328 ///
329 /// \returns A list of all diagnostics flags as they would be written in a
330 /// command line invocation including their `no-` variants. For example:
331 /// `{"-Wempty-body", "-Wno-empty-body", ...}`
332 static std::vector<std::string> getDiagnosticFlags();
333
334 /// Get the set of all diagnostic IDs in the group with the given name.
335 ///
336 /// \param[out] Diags - On return, the diagnostics in the group.
337 /// \returns \c true if the given group is unknown, \c false otherwise.
338 bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
339 SmallVectorImpl<diag::kind> &Diags) const;
340
341 /// Get the set of all diagnostic IDs.
342 static void getAllDiagnostics(diag::Flavor Flavor,
343 std::vector<diag::kind> &Diags);
344
345 /// Get the diagnostic option with the closest edit distance to the
346 /// given group name.
347 static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group);
348
349private:
350 /// Classify the specified diagnostic ID into a Level, consumable by
351 /// the DiagnosticClient.
352 ///
353 /// The classification is based on the way the client configured the
354 /// DiagnosticsEngine object.
355 ///
356 /// \param Loc The source location for which we are interested in finding out
357 /// the diagnostic state. Can be null in order to query the latest state.
359 getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
360 const DiagnosticsEngine &Diag) const LLVM_READONLY;
361
363 getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
364 const DiagnosticsEngine &Diag) const LLVM_READONLY;
365
366 /// Used to report a diagnostic that is finally fully formed.
367 ///
368 /// \returns \c true if the diagnostic was emitted, \c false if it was
369 /// suppressed.
370 bool ProcessDiag(DiagnosticsEngine &Diag) const;
371
372 /// Used to emit a diagnostic that is finally fully formed,
373 /// ignoring suppression.
374 void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const;
375
376 /// Whether the diagnostic may leave the AST in a state where some
377 /// invariants can break.
378 bool isUnrecoverable(unsigned DiagID) const;
379
380 friend class DiagnosticsEngine;
381};
382
383} // end namespace clang
384
385#endif
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
SourceLocation Loc
Definition: SemaObjC.cpp:759
Used for handling and querying diagnostic IDs.
static bool isBuiltinExtensionDiag(unsigned DiagID)
Determine whether the given built-in diagnostic ID is for an extension of some sort.
static StringRef getCategoryNameFromID(unsigned CategoryID)
Given a category ID, return the name of the category.
static unsigned getNumberOfCategories()
Return the number of diagnostic categories.
static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group)
Get the diagnostic option with the closest edit distance to the given group name.
bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, SmallVectorImpl< diag::kind > &Diags) const
Get the set of all diagnostic IDs in the group with the given name.
static std::vector< std::string > getDiagnosticFlags()
Get the string of all diagnostic flags.
static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID)
Determines whether the given built-in diagnostic ID is for an error that is suppressed if it occurs d...
static bool isDefaultMappingAsError(unsigned DiagID)
Return true if the specified diagnostic is mapped to errors by default.
static bool isBuiltinNote(unsigned DiagID)
Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinWarningOrExtension(unsigned DiagID)
Return true if the unmapped diagnostic levelof the specified diagnostic ID is a Warning or Extension.
static bool isCodegenABICheckDiagnostic(unsigned DiagID)
Return true if a given diagnostic is a codegen-time ABI check.
StringRef getDescription(unsigned DiagID) const
Given a diagnostic ID, return a description of the issue.
SFINAEResponse
Enumeration describing how the emission of a diagnostic should be treated when it occurs during C++ t...
@ SFINAE_SubstitutionFailure
The diagnostic should not be reported, but it should cause template argument deduction to fail.
@ SFINAE_Suppress
The diagnostic should be suppressed entirely.
@ SFINAE_AccessControl
The diagnostic is an access-control diagnostic, which will be substitution failures in some contexts ...
@ SFINAE_Report
The diagnostic should be reported.
static StringRef getWarningOptionForDiag(unsigned DiagID)
Return the lowest-level warning option that enables the specified diagnostic.
static StringRef getWarningOptionDocumentation(diag::Group GroupID)
Given a diagnostic group ID, return its documentation.
static std::optional< diag::Group > getGroupForWarningOption(StringRef)
Given a group ID, returns the flag that toggles the group.
static unsigned getCategoryNumberForDiag(unsigned DiagID)
Return the category number that a specified DiagID belongs to, or 0 if no category.
static std::optional< diag::Group > getGroupForDiag(unsigned DiagID)
Return the lowest-level group that contains the specified diagnostic.
static StringRef getWarningOptionForGroup(diag::Group)
Given a group ID, returns the flag that toggles the group.
static bool isARCDiagnostic(unsigned DiagID)
Return true if a given diagnostic falls into an ARC diagnostic category.
Level
The level of the diagnostic, after it has been through mapping.
static void getAllDiagnostics(diag::Flavor Flavor, std::vector< diag::kind > &Diags)
Get the set of all diagnostic IDs.
static DiagnosticMapping getDefaultMapping(unsigned DiagID)
Get the default mapping for this diagnostic.
unsigned getCustomDiagID(Level L, StringRef FormatString)
Return an ID for a diagnostic with the specified format string and level.
static bool isDeferrable(unsigned DiagID)
Whether the diagnostic message can be deferred.
bool hasNoErrorAsFatal() const
bool wasUpgradedFromWarning() const
Whether this mapping attempted to map the diagnostic to a warning, but was overruled because the diag...
unsigned serialize() const
Serialize this mapping as a raw integer.
bool operator==(DiagnosticMapping Other) const
void setNoWarningAsError(bool Value)
void setSeverity(diag::Severity Value)
static DiagnosticMapping deserialize(unsigned Bits)
Deserialize a mapping.
diag::Severity getSeverity() const
void setUpgradedFromWarning(bool Value)
static DiagnosticMapping Make(diag::Severity Severity, bool IsUser, bool IsPragma)
void setNoErrorAsFatal(bool Value)
bool hasNoWarningAsError() const
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
Encodes a location in the source.
@ DIAG_START_INSTALLAPI
Definition: DiagnosticIDs.h:61
@ DIAG_START_SERIALIZATION
Definition: DiagnosticIDs.h:52
@ DIAG_START_REFACTORING
Definition: DiagnosticIDs.h:60
@ NUM_BUILTIN_COMMON_DIAGNOSTICS
Definition: DiagnosticIDs.h:77
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
Definition: DiagnosticIDs.h:85
@ Warning
Present this diagnostic as a warning.
@ Fatal
Present this diagnostic as a fatal error.
@ Error
Present this diagnostic as an error.
@ Remark
Present this diagnostic as a remark.
@ Ignored
Do not present this diagnostic, ignore it.
Flavor
Flavors of diagnostics we can emit.
Definition: DiagnosticIDs.h:96
@ WarningOrError
A diagnostic that indicates a problem or potential problem.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:68
@ DIAG_SIZE_INSTALLAPI
Definition: DiagnosticIDs.h:45
@ DIAG_SIZE_SERIALIZATION
Definition: DiagnosticIDs.h:36
@ DIAG_SIZE_REFACTORING
Definition: DiagnosticIDs.h:44
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
@ Other
Other implicit parameter.