1 //===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the Diagnostic IDs-related interfaces.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_DIAGNOSTICIDS_H
15 #define LLVM_CLANG_DIAGNOSTICIDS_H
17 #include "llvm/ADT/IntrusiveRefCntPtr.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "clang/Basic/LLVM.h"
22 template<typename T, unsigned> class SmallVector;
26 class DiagnosticsEngine;
30 // Import the diagnostic enums themselves.
32 // Start position for diagnostics.
34 DIAG_START_DRIVER = 300,
35 DIAG_START_FRONTEND = DIAG_START_DRIVER + 100,
36 DIAG_START_LEX = DIAG_START_FRONTEND + 120,
37 DIAG_START_PARSE = DIAG_START_LEX + 300,
38 DIAG_START_AST = DIAG_START_PARSE + 300,
39 DIAG_START_SEMA = DIAG_START_AST + 100,
40 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
41 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
46 /// diag::kind - All of the diagnostics that can be emitted by the frontend.
47 typedef unsigned kind;
49 // Get typedefs for common diagnostics.
51 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
52 SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM,
53 #include "clang/Basic/DiagnosticCommonKinds.inc"
54 NUM_BUILTIN_COMMON_DIAGNOSTICS
58 /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
59 /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
60 /// (emit as an error). It allows clients to map errors to
61 /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
64 // NOTE: 0 means "uncomputed".
65 MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
66 MAP_WARNING = 2, //< Map this diagnostic to a warning.
67 MAP_ERROR = 3, //< Map this diagnostic to an error.
68 MAP_FATAL = 4 //< Map this diagnostic to a fatal error.
72 class DiagnosticMappingInfo {
75 unsigned IsPragma : 1;
76 unsigned HasShowInSystemHeader : 1;
77 unsigned HasNoWarningAsError : 1;
78 unsigned HasNoErrorAsFatal : 1;
81 static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser,
83 DiagnosticMappingInfo Result;
84 Result.Mapping = Mapping;
85 Result.IsUser = IsUser;
86 Result.IsPragma = IsPragma;
87 Result.HasShowInSystemHeader = 0;
88 Result.HasNoWarningAsError = 0;
89 Result.HasNoErrorAsFatal = 0;
93 diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
94 void setMapping(diag::Mapping Value) { Mapping = Value; }
96 bool isUser() const { return IsUser; }
97 bool isPragma() const { return IsPragma; }
99 bool hasShowInSystemHeader() const { return HasShowInSystemHeader; }
100 void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; }
102 bool hasNoWarningAsError() const { return HasNoWarningAsError; }
103 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
105 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
106 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
109 /// \brief Used for handling and querying diagnostic IDs. Can be used and shared
110 /// by multiple Diagnostics for multiple translation units.
111 class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
113 /// Level - The level of the diagnostic, after it has been through mapping.
115 Ignored, Note, Warning, Error, Fatal
119 /// CustomDiagInfo - Information for uniquing and looking up custom diags.
120 diag::CustomDiagInfo *CustomDiagInfo;
126 /// getCustomDiagID - Return an ID for a diagnostic with the specified message
127 /// and level. If this is the first request for this diagnosic, it is
128 /// registered and created, otherwise the existing ID is returned.
129 unsigned getCustomDiagID(Level L, StringRef Message);
131 //===--------------------------------------------------------------------===//
132 // Diagnostic classification and reporting interfaces.
135 /// getDescription - Given a diagnostic ID, return a description of the
137 StringRef getDescription(unsigned DiagID) const;
139 /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic level
140 /// of the specified diagnostic ID is a Warning or Extension. This only works
141 /// on builtin diagnostics, not custom ones, and is not legal to call on
143 static bool isBuiltinWarningOrExtension(unsigned DiagID);
145 /// \brief Return true if the specified diagnostic is mapped to errors by
147 static bool isDefaultMappingAsError(unsigned DiagID);
149 /// \brief Determine whether the given built-in diagnostic ID is a
151 static bool isBuiltinNote(unsigned DiagID);
153 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
154 /// ID is for an extension of some sort.
156 static bool isBuiltinExtensionDiag(unsigned DiagID) {
158 return isBuiltinExtensionDiag(DiagID, ignored);
161 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
162 /// ID is for an extension of some sort. This also returns EnabledByDefault,
163 /// which is set to indicate whether the diagnostic is ignored by default (in
164 /// which case -pedantic enables it) or treated as a warning/error by default.
166 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
169 /// getWarningOptionForDiag - Return the lowest-level warning option that
170 /// enables the specified diagnostic. If there is no -Wfoo flag that controls
171 /// the diagnostic, this returns null.
172 static StringRef getWarningOptionForDiag(unsigned DiagID);
174 /// getCategoryNumberForDiag - Return the category number that a specified
175 /// DiagID belongs to, or 0 if no category.
176 static unsigned getCategoryNumberForDiag(unsigned DiagID);
178 /// getNumberOfCategories - Return the number of categories
179 static unsigned getNumberOfCategories();
181 /// getCategoryNameFromID - Given a category ID, return the name of the
183 static StringRef getCategoryNameFromID(unsigned CategoryID);
185 /// \brief Enumeration describing how the the emission of a diagnostic should
186 /// be treated when it occurs during C++ template argument deduction.
187 enum SFINAEResponse {
188 /// \brief The diagnostic should not be reported, but it should cause
189 /// template argument deduction to fail.
191 /// The vast majority of errors that occur during template argument
192 /// deduction fall into this category.
193 SFINAE_SubstitutionFailure,
195 /// \brief The diagnostic should be suppressed entirely.
197 /// Warnings generally fall into this category.
200 /// \brief The diagnostic should be reported.
202 /// The diagnostic should be reported. Various fatal errors (e.g.,
203 /// template instantiation depth exceeded) fall into this category.
206 /// \brief The diagnostic is an access-control diagnostic, which will be
207 /// substitution failures in some contexts and reported in others.
211 /// \brief Determines whether the given built-in diagnostic ID is
212 /// for an error that is suppressed if it occurs during C++ template
213 /// argument deduction.
215 /// When an error is suppressed due to SFINAE, the template argument
216 /// deduction fails but no diagnostic is emitted. Certain classes of
217 /// errors, such as those errors that involve C++ access control,
218 /// are not SFINAE errors.
219 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
221 /// getName - Given a diagnostic ID, return its name
222 static StringRef getName(unsigned DiagID);
224 /// getIdFromName - Given a diagnostic name, return its ID, or 0
225 static unsigned getIdFromName(StringRef Name);
227 /// getBriefExplanation - Given a diagnostic ID, return a brief explanation
229 static StringRef getBriefExplanation(unsigned DiagID);
231 /// getFullExplanation - Given a diagnostic ID, return a full explanation
233 static StringRef getFullExplanation(unsigned DiagID);
235 /// Iterator class used for traversing all statically declared
237 class diag_iterator {
240 friend class DiagnosticIDs;
241 diag_iterator(const void *im) : impl(im) {}
243 diag_iterator &operator++();
244 bool operator==(const diag_iterator &x) const { return impl == x.impl; }
245 bool operator!=(const diag_iterator &x) const { return impl != x.impl; }
247 llvm::StringRef getDiagName() const;
248 unsigned getDiagID() const;
251 static diag_iterator diags_begin();
252 static diag_iterator diags_end();
254 /// \brief Get the set of all diagnostic IDs in the group with the given name.
256 /// \param Diags [out] - On return, the diagnostics in the group.
257 /// \returns True if the given group is unknown, false otherwise.
258 bool getDiagnosticsInGroup(StringRef Group,
259 llvm::SmallVectorImpl<diag::kind> &Diags) const;
262 /// \brief Get the set of all diagnostic IDs in the given group.
264 /// \param Diags [out] - On return, the diagnostics in the group.
265 void getDiagnosticsInGroup(const WarningOption *Group,
266 llvm::SmallVectorImpl<diag::kind> &Diags) const;
268 /// \brief Based on the way the client configured the DiagnosticsEngine
269 /// object, classify the specified diagnostic ID into a Level, consumable by
270 /// the DiagnosticClient.
272 /// \param Loc The source location we are interested in finding out the
273 /// diagnostic state. Can be null in order to query the latest state.
274 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
275 const DiagnosticsEngine &Diag) const;
277 /// getDiagnosticLevel - This is an internal implementation helper used when
278 /// DiagClass is already known.
279 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
282 const DiagnosticsEngine &Diag) const;
284 /// ProcessDiag - This is the method used to report a diagnostic that is
285 /// finally fully formed.
287 /// \returns true if the diagnostic was emitted, false if it was
289 bool ProcessDiag(DiagnosticsEngine &Diag) const;
291 /// \brief Whether the diagnostic may leave the AST in a state where some
292 /// invariants can break.
293 bool isUnrecoverable(unsigned DiagID) const;
295 friend class DiagnosticsEngine;
298 } // end namespace clang