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