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