blob: 6a6a87e0fd7333fff9ab5fd2fd3486ea0e65f00e [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.
68 MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
69
70 /// Map this diagnostic to "warning", but make it immune to -Werror. This
71 /// happens when you specify -Wno-error=foo.
72 MAP_WARNING_NO_WERROR = 5,
Argyrios Kyrtzidis144bc082011-04-21 23:08:23 +000073 /// Map this diagnostic to "warning", but make it immune to
74 /// -Wno-system-headers.
75 MAP_WARNING_SHOW_IN_SYSTEM_HEADER = 6,
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000076 /// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
77 /// This happens for -Wno-fatal-errors=foo.
Argyrios Kyrtzidis144bc082011-04-21 23:08:23 +000078 MAP_ERROR_NO_WFATAL = 7
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +000079 };
80 }
81
Daniel Dunbarb1c99c62011-09-29 01:30:00 +000082class DiagnosticMappingInfo {
83 unsigned Mapping : 3;
84 unsigned IsUser : 1;
85 unsigned IsPragma : 1;
86
87public:
88 static DiagnosticMappingInfo MakeUnset() {
89 DiagnosticMappingInfo Result;
90 Result.Mapping = Result.IsUser = Result.IsPragma = 0;
91 return Result;
92 }
93
94 static DiagnosticMappingInfo MakeInfo(diag::Mapping Mapping,
95 bool IsUser, bool IsPragma) {
96 DiagnosticMappingInfo Result;
97 Result.Mapping = Mapping;
98 Result.IsUser = IsUser;
99 Result.IsPragma = IsPragma;
100 return Result;
101 }
102
103 diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
104 bool isUser() const { return IsUser; }
105 bool isPragma() const { return IsPragma; }
106
107 bool isUnset() const { return Mapping == 0; }
108};
109
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000110/// \brief Used for handling and querying diagnostic IDs. Can be used and shared
111/// by multiple Diagnostics for multiple translation units.
112class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
113public:
114 /// Level - The level of the diagnostic, after it has been through mapping.
115 enum Level {
116 Ignored, Note, Warning, Error, Fatal
117 };
118
119private:
120 /// CustomDiagInfo - Information for uniquing and looking up custom diags.
121 diag::CustomDiagInfo *CustomDiagInfo;
122
123public:
124 DiagnosticIDs();
125 ~DiagnosticIDs();
126
127 /// getCustomDiagID - Return an ID for a diagnostic with the specified message
128 /// and level. If this is the first request for this diagnosic, it is
129 /// registered and created, otherwise the existing ID is returned.
Chris Lattner686775d2011-07-20 06:58:45 +0000130 unsigned getCustomDiagID(Level L, StringRef Message);
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000131
132 //===--------------------------------------------------------------------===//
133 // Diagnostic classification and reporting interfaces.
134 //
135
136 /// getDescription - Given a diagnostic ID, return a description of the
137 /// issue.
Chris Lattner686775d2011-07-20 06:58:45 +0000138 StringRef getDescription(unsigned DiagID) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000139
Daniel Dunbar80d572d2011-09-29 00:53:50 +0000140 /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic level
141 /// of the specified diagnostic ID is a Warning or Extension. This only works
142 /// on builtin diagnostics, not custom ones, and is not legal to call on
143 /// NOTEs.
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000144 static bool isBuiltinWarningOrExtension(unsigned DiagID);
145
Daniel Dunbar76101cf2011-09-29 01:01:08 +0000146 /// \brief Return true if the specified diagnostic is mapped to errors by
147 /// default.
148 static bool isDefaultMappingAsError(unsigned DiagID);
149
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000150 /// \brief Determine whether the given built-in diagnostic ID is a
151 /// Note.
152 static bool isBuiltinNote(unsigned DiagID);
153
154 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
155 /// ID is for an extension of some sort.
156 ///
157 static bool isBuiltinExtensionDiag(unsigned DiagID) {
158 bool ignored;
159 return isBuiltinExtensionDiag(DiagID, ignored);
160 }
161
162 /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
163 /// ID is for an extension of some sort. This also returns EnabledByDefault,
164 /// which is set to indicate whether the diagnostic is ignored by default (in
165 /// which case -pedantic enables it) or treated as a warning/error by default.
166 ///
167 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
168
169
170 /// getWarningOptionForDiag - Return the lowest-level warning option that
171 /// enables the specified diagnostic. If there is no -Wfoo flag that controls
172 /// the diagnostic, this returns null.
Chris Lattner686775d2011-07-20 06:58:45 +0000173 static StringRef getWarningOptionForDiag(unsigned DiagID);
Argyrios Kyrtzidis477aab62011-05-25 05:05:01 +0000174
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000175 /// getCategoryNumberForDiag - Return the category number that a specified
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000176 /// DiagID belongs to, or 0 if no category.
177 static unsigned getCategoryNumberForDiag(unsigned DiagID);
178
Argyrios Kyrtzidis477aab62011-05-25 05:05:01 +0000179 /// getNumberOfCategories - Return the number of categories
180 static unsigned getNumberOfCategories();
181
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000182 /// getCategoryNameFromID - Given a category ID, return the name of the
183 /// category.
Chris Lattner686775d2011-07-20 06:58:45 +0000184 static StringRef getCategoryNameFromID(unsigned CategoryID);
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000185
186 /// \brief Enumeration describing how the the emission of a diagnostic should
187 /// be treated when it occurs during C++ template argument deduction.
188 enum SFINAEResponse {
189 /// \brief The diagnostic should not be reported, but it should cause
190 /// template argument deduction to fail.
191 ///
192 /// The vast majority of errors that occur during template argument
193 /// deduction fall into this category.
194 SFINAE_SubstitutionFailure,
195
196 /// \brief The diagnostic should be suppressed entirely.
197 ///
198 /// Warnings generally fall into this category.
199 SFINAE_Suppress,
200
201 /// \brief The diagnostic should be reported.
202 ///
203 /// The diagnostic should be reported. Various fatal errors (e.g.,
204 /// template instantiation depth exceeded) fall into this category.
Douglas Gregor418df342011-01-27 21:06:28 +0000205 SFINAE_Report,
206
207 /// \brief The diagnostic is an access-control diagnostic, which will be
208 /// substitution failures in some contexts and reported in others.
209 SFINAE_AccessControl
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000210 };
211
212 /// \brief Determines whether the given built-in diagnostic ID is
213 /// for an error that is suppressed if it occurs during C++ template
214 /// argument deduction.
215 ///
216 /// When an error is suppressed due to SFINAE, the template argument
217 /// deduction fails but no diagnostic is emitted. Certain classes of
218 /// errors, such as those errors that involve C++ access control,
219 /// are not SFINAE errors.
220 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
221
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000222 /// getName - Given a diagnostic ID, return its name
Chris Lattner686775d2011-07-20 06:58:45 +0000223 static StringRef getName(unsigned DiagID);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000224
225 /// getIdFromName - Given a diagnostic name, return its ID, or 0
Chris Lattner686775d2011-07-20 06:58:45 +0000226 static unsigned getIdFromName(StringRef Name);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000227
228 /// getBriefExplanation - Given a diagnostic ID, return a brief explanation
229 /// of the issue
Chris Lattner686775d2011-07-20 06:58:45 +0000230 static StringRef getBriefExplanation(unsigned DiagID);
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000231
232 /// getFullExplanation - Given a diagnostic ID, return a full explanation
233 /// of the issue
Chris Lattner686775d2011-07-20 06:58:45 +0000234 static StringRef getFullExplanation(unsigned DiagID);
Ted Kremenek6948bc42011-08-09 03:39:14 +0000235
236 /// Iterator class used for traversing all statically declared
237 /// diagnostics.
238 class diag_iterator {
239 const void *impl;
240
241 friend class DiagnosticIDs;
Bill Wendlingcb9657c2011-08-12 01:29:32 +0000242 diag_iterator(const void *im) : impl(im) {}
Ted Kremenek6948bc42011-08-09 03:39:14 +0000243 public:
244 diag_iterator &operator++();
245 bool operator==(const diag_iterator &x) const { return impl == x.impl; }
246 bool operator!=(const diag_iterator &x) const { return impl != x.impl; }
247
248 llvm::StringRef getDiagName() const;
249 unsigned getDiagID() const;
250 };
251
252 static diag_iterator diags_begin();
253 static diag_iterator diags_end();
Douglas Gregor7d2b8c12011-04-15 22:04:17 +0000254
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000255private:
Daniel Dunbar3f839462011-09-29 01:47:16 +0000256 /// \brief Get the set of all diagnostic IDs in the group with the given name.
257 ///
258 /// \param Diags [out] - On return, the diagnostics in the group.
259 /// \returns True if the given group is unknown, false otherwise.
260 bool getDiagnosticsInGroup(StringRef Group,
261 llvm::SmallVectorImpl<diag::kind> &Diags) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000262
Daniel Dunbar3f839462011-09-29 01:47:16 +0000263 /// \brief Get the set of all diagnostic IDs in the given group.
264 ///
265 /// \param Diags [out] - On return, the diagnostics in the group.
266 void getDiagnosticsInGroup(const WarningOption *Group,
267 llvm::SmallVectorImpl<diag::kind> &Diags) const;
268
David Blaikied6471f72011-09-25 23:23:43 +0000269 /// \brief Based on the way the client configured the DiagnosticsEngine
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000270 /// object, classify the specified diagnostic ID into a Level, consumable by
271 /// the DiagnosticClient.
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000272 ///
273 /// \param Loc The source location we are interested in finding out the
274 /// diagnostic state. Can be null in order to query the latest state.
275 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
Daniel Dunbar1656aae2011-09-29 01:20:28 +0000276 const DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000277
278 /// getDiagnosticLevel - This is an internal implementation helper used when
279 /// DiagClass is already known.
280 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
281 unsigned DiagClass,
Argyrios Kyrtzidis08274082010-12-15 18:44:22 +0000282 SourceLocation Loc,
Daniel Dunbar1656aae2011-09-29 01:20:28 +0000283 const DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000284
285 /// ProcessDiag - This is the method used to report a diagnostic that is
286 /// finally fully formed.
287 ///
288 /// \returns true if the diagnostic was emitted, false if it was
289 /// suppressed.
David Blaikied6471f72011-09-25 23:23:43 +0000290 bool ProcessDiag(DiagnosticsEngine &Diag) const;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000291
John McCalladd80bb2011-06-15 22:11:51 +0000292 /// \brief Whether the diagnostic may leave the AST in a state where some
293 /// invariants can break.
294 bool isUnrecoverable(unsigned DiagID) const;
295
David Blaikied6471f72011-09-25 23:23:43 +0000296 friend class DiagnosticsEngine;
Argyrios Kyrtzidis33e4e702010-11-18 20:06:41 +0000297};
298
299} // end namespace clang
300
301#endif