blob: 1ff6c1192487a4295831a0674541f2adb2340045 [file] [log] [blame]
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +00001//===--- 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// This file defines the Diagnostic IDs-related interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
15#define LLVM_CLANG_DIAGNOSTICIDS_H
16
17#include "llvm/ADT/IntrusiveRefCntPtr.h"
18#include "llvm/ADT/StringRef.h"
Chris Lattner686775d2011-07-20 06:58:45 +000019#include "clang/Basic/LLVM.h"
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000020
Daniel Dunbar3f839462011-09-29 01:47:16 +000021namespace llvm {
22 template<typename T, unsigned> class SmallVector;
23}
24
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000025namespace clang {
David Blaikied6471f72011-09-25 23:23:43 +000026 class DiagnosticsEngine;
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +000027 class SourceLocation;
Daniel Dunbar3f839462011-09-29 01:47:16 +000028 struct WarningOption;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000029
30 // Import the diagnostic enums themselves.
31 namespace diag {
32 // Start position for diagnostics.
33 enum {
34 DIAG_START_DRIVER = 300,
35 DIAG_START_FRONTEND = DIAG_START_DRIVER + 100,
Fariborz Jahanianf84109e2011-01-07 18:59:25 +000036 DIAG_START_LEX = DIAG_START_FRONTEND + 120,
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000037 DIAG_START_PARSE = DIAG_START_LEX + 300,
38 DIAG_START_AST = DIAG_START_PARSE + 300,
39 DIAG_START_SEMA = DIAG_START_AST + 100,
Chandler Carruthd24eda82011-02-16 19:41:58 +000040 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000041 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
42 };
43
44 class CustomDiagInfo;
45
46 /// diag::kind - All of the diagnostics that can be emitted by the frontend.
47 typedef unsigned kind;
48
49 // Get typedefs for common diagnostics.
50 enum {
Douglas Gregor7d2b8c12011-04-15 22:04:17 +000051#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
Daniel Dunbar4213df32011-09-29 00:34:06 +000052 SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM,
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000053#include "clang/Basic/DiagnosticCommonKinds.inc"
54 NUM_BUILTIN_COMMON_DIAGNOSTICS
55#undef DIAG
56 };
57
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
62 /// one).
63 enum Mapping {
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.
Daniel Dunbarbe1aa412011-09-29 01:58:05 +000068 MAP_FATAL = 4 //< Map this diagnostic to a fatal error.
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000069 };
70 }
71
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000072class DiagnosticMappingInfo {
73 unsigned Mapping : 3;
74 unsigned IsUser : 1;
75 unsigned IsPragma : 1;
Daniel Dunbara5e41332011-09-29 01:52:06 +000076 unsigned HasShowInSystemHeader : 1;
77 unsigned HasNoWarningAsError : 1;
78 unsigned HasNoErrorAsFatal : 1;
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000079
80public:
Daniel Dunbaraeacae52011-09-29 02:03:01 +000081 static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser,
82 bool IsPragma) {
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000083 DiagnosticMappingInfo Result;
84 Result.Mapping = Mapping;
85 Result.IsUser = IsUser;
86 Result.IsPragma = IsPragma;
Daniel Dunbara5e41332011-09-29 01:52:06 +000087 Result.HasShowInSystemHeader = 0;
88 Result.HasNoWarningAsError = 0;
89 Result.HasNoErrorAsFatal = 0;
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000090 return Result;
91 }
92
93 diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
Daniel Dunbara5e41332011-09-29 01:52:06 +000094 void setMapping(diag::Mapping Value) { Mapping = Value; }
95
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000096 bool isUser() const { return IsUser; }
97 bool isPragma() const { return IsPragma; }
98
Daniel Dunbara5e41332011-09-29 01:52:06 +000099 bool hasShowInSystemHeader() const { return HasShowInSystemHeader; }
100 void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; }
101
102 bool hasNoWarningAsError() const { return HasNoWarningAsError; }
103 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
104
105 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
106 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
Daniel Dunbarb1c99c62011-09-29 01:30:00 +0000107};
108
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000109/// \brief Used for handling and querying diagnostic IDs. Can be used and shared
110/// by multiple Diagnostics for multiple translation units.
111class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
112public:
113 /// Level - The level of the diagnostic, after it has been through mapping.
114 enum Level {
115 Ignored, Note, Warning, Error, Fatal
116 };
117
118private:
119 /// CustomDiagInfo - Information for uniquing and looking up custom diags.
120 diag::CustomDiagInfo *CustomDiagInfo;
121
122public:
123 DiagnosticIDs();
124 ~DiagnosticIDs();
125
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.
Chris Lattner686775d2011-07-20 06:58:45 +0000129 unsigned getCustomDiagID(Level L, StringRef Message);
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000130
131 //===--------------------------------------------------------------------===//
132 // Diagnostic classification and reporting interfaces.
133 //
134
135 /// getDescription - Given a diagnostic ID, return a description of the
136 /// issue.
Chris Lattner686775d2011-07-20 06:58:45 +0000137 StringRef getDescription(unsigned DiagID) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000138
Daniel Dunbar80d572d2011-09-29 00:53:50 +0000139 /// 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
142 /// NOTEs.
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000143 static bool isBuiltinWarningOrExtension(unsigned DiagID);
144
Daniel Dunbar76101cf2011-09-29 01:01:08 +0000145 /// \brief Return true if the specified diagnostic is mapped to errors by
146 /// default.
147 static bool isDefaultMappingAsError(unsigned DiagID);
148
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000149 /// \brief Determine whether the given built-in diagnostic ID is a
150 /// Note.
151 static bool isBuiltinNote(unsigned DiagID);
152
153 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
154 /// ID is for an extension of some sort.
155 ///
156 static bool isBuiltinExtensionDiag(unsigned DiagID) {
157 bool ignored;
158 return isBuiltinExtensionDiag(DiagID, ignored);
159 }
160
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.
165 ///
166 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
167
168
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.
Chris Lattner686775d2011-07-20 06:58:45 +0000172 static StringRef getWarningOptionForDiag(unsigned DiagID);
Argyrios Kyrtzidis477aab62011-05-25 05:05:01 +0000173
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000174 /// getCategoryNumberForDiag - Return the category number that a specified
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000175 /// DiagID belongs to, or 0 if no category.
176 static unsigned getCategoryNumberForDiag(unsigned DiagID);
177
Argyrios Kyrtzidis477aab62011-05-25 05:05:01 +0000178 /// getNumberOfCategories - Return the number of categories
179 static unsigned getNumberOfCategories();
180
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000181 /// getCategoryNameFromID - Given a category ID, return the name of the
182 /// category.
Chris Lattner686775d2011-07-20 06:58:45 +0000183 static StringRef getCategoryNameFromID(unsigned CategoryID);
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000184
Ted Kremenekafdc21a2011-10-20 05:07:47 +0000185 /// isARCDiagnostic - Return true if a given diagnostic falls into an
186 /// ARC diagnostic category;
187 static bool isARCDiagnostic(unsigned DiagID);
188
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000189 /// \brief Enumeration describing how the the emission of a diagnostic should
190 /// be treated when it occurs during C++ template argument deduction.
191 enum SFINAEResponse {
192 /// \brief The diagnostic should not be reported, but it should cause
193 /// template argument deduction to fail.
194 ///
195 /// The vast majority of errors that occur during template argument
196 /// deduction fall into this category.
197 SFINAE_SubstitutionFailure,
198
199 /// \brief The diagnostic should be suppressed entirely.
200 ///
201 /// Warnings generally fall into this category.
202 SFINAE_Suppress,
203
204 /// \brief The diagnostic should be reported.
205 ///
206 /// The diagnostic should be reported. Various fatal errors (e.g.,
207 /// template instantiation depth exceeded) fall into this category.
Douglas Gregor418df342011-01-27 21:06:28 +0000208 SFINAE_Report,
209
210 /// \brief The diagnostic is an access-control diagnostic, which will be
211 /// substitution failures in some contexts and reported in others.
212 SFINAE_AccessControl
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000213 };
214
215 /// \brief Determines whether the given built-in diagnostic ID is
216 /// for an error that is suppressed if it occurs during C++ template
217 /// argument deduction.
218 ///
219 /// When an error is suppressed due to SFINAE, the template argument
220 /// deduction fails but no diagnostic is emitted. Certain classes of
221 /// errors, such as those errors that involve C++ access control,
222 /// are not SFINAE errors.
223 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
224
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000225 /// getName - Given a diagnostic ID, return its name
Chris Lattner686775d2011-07-20 06:58:45 +0000226 static StringRef getName(unsigned DiagID);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000227
228 /// getIdFromName - Given a diagnostic name, return its ID, or 0
Chris Lattner686775d2011-07-20 06:58:45 +0000229 static unsigned getIdFromName(StringRef Name);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000230
231 /// getBriefExplanation - Given a diagnostic ID, return a brief explanation
232 /// of the issue
Chris Lattner686775d2011-07-20 06:58:45 +0000233 static StringRef getBriefExplanation(unsigned DiagID);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000234
235 /// getFullExplanation - Given a diagnostic ID, return a full explanation
236 /// of the issue
Chris Lattner686775d2011-07-20 06:58:45 +0000237 static StringRef getFullExplanation(unsigned DiagID);
Ted Kremenek6948bc42011-08-09 03:39:14 +0000238
239 /// Iterator class used for traversing all statically declared
240 /// diagnostics.
241 class diag_iterator {
242 const void *impl;
243
244 friend class DiagnosticIDs;
Bill Wendlingcb9657c2011-08-12 01:29:32 +0000245 diag_iterator(const void *im) : impl(im) {}
Ted Kremenek6948bc42011-08-09 03:39:14 +0000246 public:
247 diag_iterator &operator++();
248 bool operator==(const diag_iterator &x) const { return impl == x.impl; }
249 bool operator!=(const diag_iterator &x) const { return impl != x.impl; }
250
251 llvm::StringRef getDiagName() const;
252 unsigned getDiagID() const;
253 };
254
255 static diag_iterator diags_begin();
256 static diag_iterator diags_end();
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000257
Daniel Dunbar3f839462011-09-29 01:47:16 +0000258 /// \brief Get the set of all diagnostic IDs in the group with the given name.
259 ///
260 /// \param Diags [out] - On return, the diagnostics in the group.
261 /// \returns True if the given group is unknown, false otherwise.
262 bool getDiagnosticsInGroup(StringRef Group,
263 llvm::SmallVectorImpl<diag::kind> &Diags) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000264
Ted Kremenekd7681502011-10-12 19:46:30 +0000265private:
Daniel Dunbar3f839462011-09-29 01:47:16 +0000266 /// \brief Get the set of all diagnostic IDs in the given group.
267 ///
268 /// \param Diags [out] - On return, the diagnostics in the group.
269 void getDiagnosticsInGroup(const WarningOption *Group,
270 llvm::SmallVectorImpl<diag::kind> &Diags) const;
271
David Blaikied6471f72011-09-25 23:23:43 +0000272 /// \brief Based on the way the client configured the DiagnosticsEngine
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000273 /// object, classify the specified diagnostic ID into a Level, consumable by
274 /// the DiagnosticClient.
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000275 ///
276 /// \param Loc The source location we are interested in finding out the
277 /// diagnostic state. Can be null in order to query the latest state.
278 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
Daniel Dunbar1656aae2011-09-29 01:20:28 +0000279 const DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000280
281 /// getDiagnosticLevel - This is an internal implementation helper used when
282 /// DiagClass is already known.
283 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
284 unsigned DiagClass,
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000285 SourceLocation Loc,
Daniel Dunbar1656aae2011-09-29 01:20:28 +0000286 const DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000287
288 /// ProcessDiag - This is the method used to report a diagnostic that is
289 /// finally fully formed.
290 ///
291 /// \returns true if the diagnostic was emitted, false if it was
292 /// suppressed.
David Blaikied6471f72011-09-25 23:23:43 +0000293 bool ProcessDiag(DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000294
John McCalladd80bb2011-06-15 22:11:51 +0000295 /// \brief Whether the diagnostic may leave the AST in a state where some
296 /// invariants can break.
297 bool isUnrecoverable(unsigned DiagID) const;
298
David Blaikied6471f72011-09-25 23:23:43 +0000299 friend class DiagnosticsEngine;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000300};
301
302} // end namespace clang
303
304#endif