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 #include "clang/Basic/LLVM.h" 20 21 namespace llvm { 22 template<typename T, unsigned> class SmallVector; 23 } 24 25 namespace clang { 26 class DiagnosticsEngine; 27 class SourceLocation; 28 struct WarningOption; 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, 36 DIAG_START_LEX = DIAG_START_FRONTEND + 120, 37 DIAG_START_PARSE = DIAG_START_LEX + 300, 38 DIAG_START_AST = DIAG_START_PARSE + 300, 39 DIAG_START_SEMA = DIAG_START_AST + 100, 40 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 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 { 51 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 52 SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM, 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. 68 MAP_FATAL = 4 //< Map this diagnostic to a fatal error. 69 }; 70 } 71 72 class DiagnosticMappingInfo { 73 unsigned Mapping : 3; 74 unsigned IsUser : 1; 75 unsigned IsPragma : 1; 76 unsigned HasShowInSystemHeader : 1; 77 unsigned HasNoWarningAsError : 1; 78 unsigned HasNoErrorAsFatal : 1; 79 80 public: 81 static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, 82 bool IsPragma) { 83 DiagnosticMappingInfo Result; 84 Result.Mapping = Mapping; 85 Result.IsUser = IsUser; 86 Result.IsPragma = IsPragma; 87 Result.HasShowInSystemHeader = 0; 88 Result.HasNoWarningAsError = 0; 89 Result.HasNoErrorAsFatal = 0; 90 return Result; 91 } 92 93 diag::Mapping getMapping() const { return diag::Mapping(Mapping); } 94 void setMapping(diag::Mapping Value) { Mapping = Value; } 95 96 bool isUser() const { return IsUser; } 97 bool isPragma() const { return IsPragma; } 98 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; } 107 }; 108 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. 129 unsigned getCustomDiagID(Level L, StringRef Message); 130 131 //===--------------------------------------------------------------------===// 132 // Diagnostic classification and reporting interfaces. 133 // 134 135 /// getDescription - Given a diagnostic ID, return a description of the 136 /// issue. 137 StringRef getDescription(unsigned DiagID) const; 138 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. 143 static bool isBuiltinWarningOrExtension(unsigned DiagID); 144 145 /// \brief Return true if the specified diagnostic is mapped to errors by 146 /// default. 147 static bool isDefaultMappingAsError(unsigned DiagID); 148 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. 172 static StringRef getWarningOptionForDiag(unsigned DiagID); 173 174 /// getCategoryNumberForDiag - Return the category number that a specified 175 /// DiagID belongs to, or 0 if no category. 176 static unsigned getCategoryNumberForDiag(unsigned DiagID); 177 178 /// getNumberOfCategories - Return the number of categories 179 static unsigned getNumberOfCategories(); 180 181 /// getCategoryNameFromID - Given a category ID, return the name of the 182 /// category. 183 static StringRef getCategoryNameFromID(unsigned CategoryID); 184 185 /// \brief Enumeration describing how the the emission of a diagnostic should 186 /// be treated when it occurs during C++ template argument deduction. 187 enum SFINAEResponse { 188 /// \brief The diagnostic should not be reported, but it should cause 189 /// template argument deduction to fail. 190 /// 191 /// The vast majority of errors that occur during template argument 192 /// deduction fall into this category. 193 SFINAE_SubstitutionFailure, 194 195 /// \brief The diagnostic should be suppressed entirely. 196 /// 197 /// Warnings generally fall into this category. 198 SFINAE_Suppress, 199 200 /// \brief The diagnostic should be reported. 201 /// 202 /// The diagnostic should be reported. Various fatal errors (e.g., 203 /// template instantiation depth exceeded) fall into this category. 204 SFINAE_Report, 205 206 /// \brief The diagnostic is an access-control diagnostic, which will be 207 /// substitution failures in some contexts and reported in others. 208 SFINAE_AccessControl 209 }; 210 211 /// \brief Determines whether the given built-in diagnostic ID is 212 /// for an error that is suppressed if it occurs during C++ template 213 /// argument deduction. 214 /// 215 /// When an error is suppressed due to SFINAE, the template argument 216 /// deduction fails but no diagnostic is emitted. Certain classes of 217 /// errors, such as those errors that involve C++ access control, 218 /// are not SFINAE errors. 219 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 220 221 /// getName - Given a diagnostic ID, return its name 222 static StringRef getName(unsigned DiagID); 223 224 /// getIdFromName - Given a diagnostic name, return its ID, or 0 225 static unsigned getIdFromName(StringRef Name); 226 227 /// getBriefExplanation - Given a diagnostic ID, return a brief explanation 228 /// of the issue 229 static StringRef getBriefExplanation(unsigned DiagID); 230 231 /// getFullExplanation - Given a diagnostic ID, return a full explanation 232 /// of the issue 233 static StringRef getFullExplanation(unsigned DiagID); 234 235 /// Iterator class used for traversing all statically declared 236 /// diagnostics. 237 class diag_iterator { 238 const void *impl; 239 240 friend class DiagnosticIDs; 241 diag_iterator(const void *im) : impl(im) {} 242 public: 243 diag_iterator &operator++(); 244 bool operator==(const diag_iterator &x) const { return impl == x.impl; } 245 bool operator!=(const diag_iterator &x) const { return impl != x.impl; } 246 247 llvm::StringRef getDiagName() const; 248 unsigned getDiagID() const; 249 }; 250 251 static diag_iterator diags_begin(); 252 static diag_iterator diags_end(); 253 254 /// \brief Get the set of all diagnostic IDs in the group with the given name. 255 /// 256 /// \param Diags [out] - On return, the diagnostics in the group. 257 /// \returns True if the given group is unknown, false otherwise. 258 bool getDiagnosticsInGroup(StringRef Group, 259 llvm::SmallVectorImpl<diag::kind> &Diags) const; 260 261 private: 262 /// \brief Get the set of all diagnostic IDs in the given group. 263 /// 264 /// \param Diags [out] - On return, the diagnostics in the group. 265 void getDiagnosticsInGroup(const WarningOption *Group, 266 llvm::SmallVectorImpl<diag::kind> &Diags) const; 267 268 /// \brief Based on the way the client configured the DiagnosticsEngine 269 /// object, classify the specified diagnostic ID into a Level, consumable by 270 /// the DiagnosticClient. 271 /// 272 /// \param Loc The source location we are interested in finding out the 273 /// diagnostic state. Can be null in order to query the latest state. 274 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 275 const DiagnosticsEngine &Diag) const; 276 277 /// getDiagnosticLevel - This is an internal implementation helper used when 278 /// DiagClass is already known. 279 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, 280 unsigned DiagClass, 281 SourceLocation Loc, 282 const DiagnosticsEngine &Diag) const; 283 284 /// ProcessDiag - This is the method used to report a diagnostic that is 285 /// finally fully formed. 286 /// 287 /// \returns true if the diagnostic was emitted, false if it was 288 /// suppressed. 289 bool ProcessDiag(DiagnosticsEngine &Diag) const; 290 291 /// \brief Whether the diagnostic may leave the AST in a state where some 292 /// invariants can break. 293 bool isUnrecoverable(unsigned DiagID) const; 294 295 friend class DiagnosticsEngine; 296 }; 297 298 } // end namespace clang 299 300 #endif 301