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