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" |
| 19 | |
| 20 | namespace clang { |
| 21 | class Diagnostic; |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 22 | class SourceLocation; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 23 | |
| 24 | // Import the diagnostic enums themselves. |
| 25 | namespace diag { |
| 26 | // Start position for diagnostics. |
| 27 | enum { |
| 28 | DIAG_START_DRIVER = 300, |
| 29 | DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, |
Fariborz Jahanian | f84109e | 2011-01-07 18:59:25 +0000 | [diff] [blame] | 30 | DIAG_START_LEX = DIAG_START_FRONTEND + 120, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 31 | DIAG_START_PARSE = DIAG_START_LEX + 300, |
| 32 | DIAG_START_AST = DIAG_START_PARSE + 300, |
| 33 | DIAG_START_SEMA = DIAG_START_AST + 100, |
Chandler Carruth | d24eda8 | 2011-02-16 19:41:58 +0000 | [diff] [blame^] | 34 | DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 35 | DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 |
| 36 | }; |
| 37 | |
| 38 | class CustomDiagInfo; |
| 39 | |
| 40 | /// diag::kind - All of the diagnostics that can be emitted by the frontend. |
| 41 | typedef unsigned kind; |
| 42 | |
| 43 | // Get typedefs for common diagnostics. |
| 44 | enum { |
Douglas Gregor | 418df34 | 2011-01-27 21:06:28 +0000 | [diff] [blame] | 45 | #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 46 | #include "clang/Basic/DiagnosticCommonKinds.inc" |
| 47 | NUM_BUILTIN_COMMON_DIAGNOSTICS |
| 48 | #undef DIAG |
| 49 | }; |
| 50 | |
| 51 | /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs |
| 52 | /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR |
| 53 | /// (emit as an error). It allows clients to map errors to |
| 54 | /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this |
| 55 | /// one). |
| 56 | enum Mapping { |
| 57 | // NOTE: 0 means "uncomputed". |
| 58 | MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. |
| 59 | MAP_WARNING = 2, //< Map this diagnostic to a warning. |
| 60 | MAP_ERROR = 3, //< Map this diagnostic to an error. |
| 61 | MAP_FATAL = 4, //< Map this diagnostic to a fatal error. |
| 62 | |
| 63 | /// Map this diagnostic to "warning", but make it immune to -Werror. This |
| 64 | /// happens when you specify -Wno-error=foo. |
| 65 | MAP_WARNING_NO_WERROR = 5, |
| 66 | /// Map this diagnostic to "error", but make it immune to -Wfatal-errors. |
| 67 | /// This happens for -Wno-fatal-errors=foo. |
| 68 | MAP_ERROR_NO_WFATAL = 6 |
| 69 | }; |
| 70 | } |
| 71 | |
| 72 | /// \brief Used for handling and querying diagnostic IDs. Can be used and shared |
| 73 | /// by multiple Diagnostics for multiple translation units. |
| 74 | class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> { |
| 75 | public: |
| 76 | /// Level - The level of the diagnostic, after it has been through mapping. |
| 77 | enum Level { |
| 78 | Ignored, Note, Warning, Error, Fatal |
| 79 | }; |
| 80 | |
| 81 | private: |
| 82 | /// CustomDiagInfo - Information for uniquing and looking up custom diags. |
| 83 | diag::CustomDiagInfo *CustomDiagInfo; |
| 84 | |
| 85 | public: |
| 86 | DiagnosticIDs(); |
| 87 | ~DiagnosticIDs(); |
| 88 | |
| 89 | /// getCustomDiagID - Return an ID for a diagnostic with the specified message |
| 90 | /// and level. If this is the first request for this diagnosic, it is |
| 91 | /// registered and created, otherwise the existing ID is returned. |
| 92 | unsigned getCustomDiagID(Level L, llvm::StringRef Message); |
| 93 | |
| 94 | //===--------------------------------------------------------------------===// |
| 95 | // Diagnostic classification and reporting interfaces. |
| 96 | // |
| 97 | |
| 98 | /// getDescription - Given a diagnostic ID, return a description of the |
| 99 | /// issue. |
| 100 | const char *getDescription(unsigned DiagID) const; |
| 101 | |
| 102 | /// isNoteWarningOrExtension - Return true if the unmapped diagnostic |
| 103 | /// level of the specified diagnostic ID is a Warning or Extension. |
| 104 | /// This only works on builtin diagnostics, not custom ones, and is not legal to |
| 105 | /// call on NOTEs. |
| 106 | static bool isBuiltinWarningOrExtension(unsigned DiagID); |
| 107 | |
| 108 | /// \brief Determine whether the given built-in diagnostic ID is a |
| 109 | /// Note. |
| 110 | static bool isBuiltinNote(unsigned DiagID); |
| 111 | |
| 112 | /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic |
| 113 | /// ID is for an extension of some sort. |
| 114 | /// |
| 115 | static bool isBuiltinExtensionDiag(unsigned DiagID) { |
| 116 | bool ignored; |
| 117 | return isBuiltinExtensionDiag(DiagID, ignored); |
| 118 | } |
| 119 | |
| 120 | /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic |
| 121 | /// ID is for an extension of some sort. This also returns EnabledByDefault, |
| 122 | /// which is set to indicate whether the diagnostic is ignored by default (in |
| 123 | /// which case -pedantic enables it) or treated as a warning/error by default. |
| 124 | /// |
| 125 | static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); |
| 126 | |
| 127 | |
| 128 | /// getWarningOptionForDiag - Return the lowest-level warning option that |
| 129 | /// enables the specified diagnostic. If there is no -Wfoo flag that controls |
| 130 | /// the diagnostic, this returns null. |
| 131 | static const char *getWarningOptionForDiag(unsigned DiagID); |
| 132 | |
| 133 | /// getWarningOptionForDiag - Return the category number that a specified |
| 134 | /// DiagID belongs to, or 0 if no category. |
| 135 | static unsigned getCategoryNumberForDiag(unsigned DiagID); |
| 136 | |
| 137 | /// getCategoryNameFromID - Given a category ID, return the name of the |
| 138 | /// category. |
| 139 | static const char *getCategoryNameFromID(unsigned CategoryID); |
| 140 | |
| 141 | /// \brief Enumeration describing how the the emission of a diagnostic should |
| 142 | /// be treated when it occurs during C++ template argument deduction. |
| 143 | enum SFINAEResponse { |
| 144 | /// \brief The diagnostic should not be reported, but it should cause |
| 145 | /// template argument deduction to fail. |
| 146 | /// |
| 147 | /// The vast majority of errors that occur during template argument |
| 148 | /// deduction fall into this category. |
| 149 | SFINAE_SubstitutionFailure, |
| 150 | |
| 151 | /// \brief The diagnostic should be suppressed entirely. |
| 152 | /// |
| 153 | /// Warnings generally fall into this category. |
| 154 | SFINAE_Suppress, |
| 155 | |
| 156 | /// \brief The diagnostic should be reported. |
| 157 | /// |
| 158 | /// The diagnostic should be reported. Various fatal errors (e.g., |
| 159 | /// template instantiation depth exceeded) fall into this category. |
Douglas Gregor | 418df34 | 2011-01-27 21:06:28 +0000 | [diff] [blame] | 160 | SFINAE_Report, |
| 161 | |
| 162 | /// \brief The diagnostic is an access-control diagnostic, which will be |
| 163 | /// substitution failures in some contexts and reported in others. |
| 164 | SFINAE_AccessControl |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 165 | }; |
| 166 | |
| 167 | /// \brief Determines whether the given built-in diagnostic ID is |
| 168 | /// for an error that is suppressed if it occurs during C++ template |
| 169 | /// argument deduction. |
| 170 | /// |
| 171 | /// When an error is suppressed due to SFINAE, the template argument |
| 172 | /// deduction fails but no diagnostic is emitted. Certain classes of |
| 173 | /// errors, such as those errors that involve C++ access control, |
| 174 | /// are not SFINAE errors. |
| 175 | static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); |
| 176 | |
| 177 | private: |
| 178 | /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. |
| 179 | /// "unknown-pragmas" to have the specified mapping. This returns true and |
| 180 | /// ignores the request if "Group" was unknown, false otherwise. |
| 181 | bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map, |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 182 | SourceLocation Loc, Diagnostic &Diag) const; |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 183 | |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 184 | /// \brief Based on the way the client configured the Diagnostic |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 185 | /// object, classify the specified diagnostic ID into a Level, consumable by |
| 186 | /// the DiagnosticClient. |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 187 | /// |
| 188 | /// \param Loc The source location we are interested in finding out the |
| 189 | /// diagnostic state. Can be null in order to query the latest state. |
| 190 | DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 191 | const Diagnostic &Diag) const; |
| 192 | |
| 193 | /// getDiagnosticLevel - This is an internal implementation helper used when |
| 194 | /// DiagClass is already known. |
| 195 | DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, |
| 196 | unsigned DiagClass, |
Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 197 | SourceLocation Loc, |
Argyrios Kyrtzidis | 33e4e70 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 198 | const Diagnostic &Diag) const; |
| 199 | |
| 200 | /// ProcessDiag - This is the method used to report a diagnostic that is |
| 201 | /// finally fully formed. |
| 202 | /// |
| 203 | /// \returns true if the diagnostic was emitted, false if it was |
| 204 | /// suppressed. |
| 205 | bool ProcessDiag(Diagnostic &Diag) const; |
| 206 | |
| 207 | friend class Diagnostic; |
| 208 | }; |
| 209 | |
| 210 | } // end namespace clang |
| 211 | |
| 212 | #endif |