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