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