Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 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 | // 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 Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 19 | #include "clang/Basic/LLVM.h" |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 20 | |
Daniel Dunbar | 3f83946 | 2011-09-29 01:47:16 +0000 | [diff] [blame] | 21 | namespace llvm { |
| 22 | template<typename T, unsigned> class SmallVector; |
| 23 | } |
| 24 | |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 25 | namespace clang { |
David Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 26 | class DiagnosticsEngine; |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 27 | class SourceLocation; |
Daniel Dunbar | 3f83946 | 2011-09-29 01:47:16 +0000 | [diff] [blame] | 28 | struct WarningOption; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 29 | |
| 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 Jahanian | f84109e | 2011-01-07 18:59:25 +0000 | [diff] [blame] | 36 | DIAG_START_LEX = DIAG_START_FRONTEND + 120, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 37 | DIAG_START_PARSE = DIAG_START_LEX + 300, |
| 38 | DIAG_START_AST = DIAG_START_PARSE + 300, |
| 39 | DIAG_START_SEMA = DIAG_START_AST + 100, |
Chandler Carruth | d24eda8 | 2011-02-16 19:41:58 +0000 | [diff] [blame] | 40 | DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 41 | 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 Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 51 | #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ |
Daniel Dunbar | 4213df3 | 2011-09-29 00:34:06 +0000 | [diff] [blame] | 52 | SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 53 | #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 Dunbar | be1aa41 | 2011-09-29 01:58:05 +0000 | [diff] [blame] | 68 | MAP_FATAL = 4 //< Map this diagnostic to a fatal error. |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 69 | }; |
| 70 | } |
| 71 | |
Daniel Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 72 | class DiagnosticMappingInfo { |
| 73 | unsigned Mapping : 3; |
| 74 | unsigned IsUser : 1; |
| 75 | unsigned IsPragma : 1; |
Daniel Dunbar | a5e4133 | 2011-09-29 01:52:06 +0000 | [diff] [blame] | 76 | unsigned HasShowInSystemHeader : 1; |
| 77 | unsigned HasNoWarningAsError : 1; |
| 78 | unsigned HasNoErrorAsFatal : 1; |
Daniel Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 79 | |
| 80 | public: |
Daniel Dunbar | aeacae5 | 2011-09-29 02:03:01 +0000 | [diff] [blame] | 81 | static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, |
| 82 | bool IsPragma) { |
Daniel Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 83 | DiagnosticMappingInfo Result; |
| 84 | Result.Mapping = Mapping; |
| 85 | Result.IsUser = IsUser; |
| 86 | Result.IsPragma = IsPragma; |
Daniel Dunbar | a5e4133 | 2011-09-29 01:52:06 +0000 | [diff] [blame] | 87 | Result.HasShowInSystemHeader = 0; |
| 88 | Result.HasNoWarningAsError = 0; |
| 89 | Result.HasNoErrorAsFatal = 0; |
Daniel Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 90 | return Result; |
| 91 | } |
| 92 | |
| 93 | diag::Mapping getMapping() const { return diag::Mapping(Mapping); } |
Daniel Dunbar | a5e4133 | 2011-09-29 01:52:06 +0000 | [diff] [blame] | 94 | void setMapping(diag::Mapping Value) { Mapping = Value; } |
| 95 | |
Daniel Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 96 | bool isUser() const { return IsUser; } |
| 97 | bool isPragma() const { return IsPragma; } |
| 98 | |
Daniel Dunbar | a5e4133 | 2011-09-29 01:52:06 +0000 | [diff] [blame] | 99 | 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 Dunbar | b1c99c6 | 2011-09-29 01:30:00 +0000 | [diff] [blame] | 107 | }; |
| 108 | |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 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> { |
| 112 | public: |
| 113 | /// Level - The level of the diagnostic, after it has been through mapping. |
| 114 | enum Level { |
| 115 | Ignored, Note, Warning, Error, Fatal |
| 116 | }; |
| 117 | |
| 118 | private: |
| 119 | /// CustomDiagInfo - Information for uniquing and looking up custom diags. |
| 120 | diag::CustomDiagInfo *CustomDiagInfo; |
| 121 | |
| 122 | public: |
| 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 Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 129 | unsigned getCustomDiagID(Level L, StringRef Message); |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 130 | |
| 131 | //===--------------------------------------------------------------------===// |
| 132 | // Diagnostic classification and reporting interfaces. |
| 133 | // |
| 134 | |
| 135 | /// getDescription - Given a diagnostic ID, return a description of the |
| 136 | /// issue. |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 137 | StringRef getDescription(unsigned DiagID) const; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 138 | |
Daniel Dunbar | 80d572d | 2011-09-29 00:53:50 +0000 | [diff] [blame] | 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 |
| 142 | /// NOTEs. |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 143 | static bool isBuiltinWarningOrExtension(unsigned DiagID); |
| 144 | |
Daniel Dunbar | 76101cf | 2011-09-29 01:01:08 +0000 | [diff] [blame] | 145 | /// \brief Return true if the specified diagnostic is mapped to errors by |
| 146 | /// default. |
| 147 | static bool isDefaultMappingAsError(unsigned DiagID); |
| 148 | |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 149 | /// \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 Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 172 | static StringRef getWarningOptionForDiag(unsigned DiagID); |
Argyrios Kyrtzidis | 477aab6 | 2011-05-25 05:05:01 +0000 | [diff] [blame] | 173 | |
Douglas Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 174 | /// getCategoryNumberForDiag - Return the category number that a specified |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 175 | /// DiagID belongs to, or 0 if no category. |
| 176 | static unsigned getCategoryNumberForDiag(unsigned DiagID); |
| 177 | |
Argyrios Kyrtzidis | 477aab6 | 2011-05-25 05:05:01 +0000 | [diff] [blame] | 178 | /// getNumberOfCategories - Return the number of categories |
| 179 | static unsigned getNumberOfCategories(); |
| 180 | |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 181 | /// getCategoryNameFromID - Given a category ID, return the name of the |
| 182 | /// category. |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 183 | static StringRef getCategoryNameFromID(unsigned CategoryID); |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 184 | |
Ted Kremenek | afdc21a | 2011-10-20 05:07:47 +0000 | [diff] [blame] | 185 | /// isARCDiagnostic - Return true if a given diagnostic falls into an |
| 186 | /// ARC diagnostic category; |
| 187 | static bool isARCDiagnostic(unsigned DiagID); |
| 188 | |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 189 | /// \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 Gregor | 418df34 | 2011-01-27 21:06:28 +0000 | [diff] [blame] | 208 | 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 Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 213 | }; |
| 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 Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 225 | /// getName - Given a diagnostic ID, return its name |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 226 | static StringRef getName(unsigned DiagID); |
Douglas Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 227 | |
| 228 | /// getIdFromName - Given a diagnostic name, return its ID, or 0 |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 229 | static unsigned getIdFromName(StringRef Name); |
Douglas Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 230 | |
| 231 | /// getBriefExplanation - Given a diagnostic ID, return a brief explanation |
| 232 | /// of the issue |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 233 | static StringRef getBriefExplanation(unsigned DiagID); |
Douglas Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 234 | |
| 235 | /// getFullExplanation - Given a diagnostic ID, return a full explanation |
| 236 | /// of the issue |
Chris Lattner | 686775d | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 237 | static StringRef getFullExplanation(unsigned DiagID); |
Ted Kremenek | 6948bc4 | 2011-08-09 03:39:14 +0000 | [diff] [blame] | 238 | |
| 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 Wendling | cb9657c | 2011-08-12 01:29:32 +0000 | [diff] [blame] | 245 | diag_iterator(const void *im) : impl(im) {} |
Ted Kremenek | 6948bc4 | 2011-08-09 03:39:14 +0000 | [diff] [blame] | 246 | 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 Gregor | 7d2b8c1 | 2011-04-15 22:04:17 +0000 | [diff] [blame] | 257 | |
Daniel Dunbar | 3f83946 | 2011-09-29 01:47:16 +0000 | [diff] [blame] | 258 | /// \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 Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 264 | |
Ted Kremenek | d768150 | 2011-10-12 19:46:30 +0000 | [diff] [blame] | 265 | private: |
Daniel Dunbar | 3f83946 | 2011-09-29 01:47:16 +0000 | [diff] [blame] | 266 | /// \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 Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 272 | /// \brief Based on the way the client configured the DiagnosticsEngine |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 273 | /// object, classify the specified diagnostic ID into a Level, consumable by |
| 274 | /// the DiagnosticClient. |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 275 | /// |
| 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 Dunbar | 1656aae | 2011-09-29 01:20:28 +0000 | [diff] [blame] | 279 | const DiagnosticsEngine &Diag) const; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 280 | |
| 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 Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 285 | SourceLocation Loc, |
Daniel Dunbar | 1656aae | 2011-09-29 01:20:28 +0000 | [diff] [blame] | 286 | const DiagnosticsEngine &Diag) const; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 287 | |
| 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 Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 293 | bool ProcessDiag(DiagnosticsEngine &Diag) const; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 294 | |
John McCall | add80bb | 2011-06-15 22:11:51 +0000 | [diff] [blame] | 295 | /// \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 Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 299 | friend class DiagnosticsEngine; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 300 | }; |
| 301 | |
| 302 | } // end namespace clang |
| 303 | |
| 304 | #endif |