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_SERIALIZATION = DIAG_START_FRONTEND + 100, 37 DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 38 DIAG_START_PARSE = DIAG_START_LEX + 300, 39 DIAG_START_AST = DIAG_START_PARSE + 400, 40 DIAG_START_SEMA = DIAG_START_AST + 100, 41 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 42 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 43 }; 44 45 class CustomDiagInfo; 46 47 /// diag::kind - All of the diagnostics that can be emitted by the frontend. 48 typedef unsigned kind; 49 50 // Get typedefs for common diagnostics. 51 enum { 52 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 53 SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 54 #include "clang/Basic/DiagnosticCommonKinds.inc" 55 NUM_BUILTIN_COMMON_DIAGNOSTICS 56 #undef DIAG 57 }; 58 59 /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 60 /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR 61 /// (emit as an error). It allows clients to map errors to 62 /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this 63 /// one). 64 enum Mapping { 65 // NOTE: 0 means "uncomputed". 66 MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. 67 MAP_WARNING = 2, //< Map this diagnostic to a warning. 68 MAP_ERROR = 3, //< Map this diagnostic to an error. 69 MAP_FATAL = 4 //< Map this diagnostic to a fatal error. 70 }; 71 } 72 73 class DiagnosticMappingInfo { 74 unsigned Mapping : 3; 75 unsigned IsUser : 1; 76 unsigned IsPragma : 1; 77 unsigned HasShowInSystemHeader : 1; 78 unsigned HasNoWarningAsError : 1; 79 unsigned HasNoErrorAsFatal : 1; 80 81 public: Make(diag::Mapping Mapping,bool IsUser,bool IsPragma)82 static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, 83 bool IsPragma) { 84 DiagnosticMappingInfo Result; 85 Result.Mapping = Mapping; 86 Result.IsUser = IsUser; 87 Result.IsPragma = IsPragma; 88 Result.HasShowInSystemHeader = 0; 89 Result.HasNoWarningAsError = 0; 90 Result.HasNoErrorAsFatal = 0; 91 return Result; 92 } 93 getMapping()94 diag::Mapping getMapping() const { return diag::Mapping(Mapping); } setMapping(diag::Mapping Value)95 void setMapping(diag::Mapping Value) { Mapping = Value; } 96 isUser()97 bool isUser() const { return IsUser; } isPragma()98 bool isPragma() const { return IsPragma; } 99 hasShowInSystemHeader()100 bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } setShowInSystemHeader(bool Value)101 void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } 102 hasNoWarningAsError()103 bool hasNoWarningAsError() const { return HasNoWarningAsError; } setNoWarningAsError(bool Value)104 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 105 hasNoErrorAsFatal()106 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } setNoErrorAsFatal(bool Value)107 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 108 }; 109 110 /// \brief Used for handling and querying diagnostic IDs. Can be used and shared 111 /// by multiple Diagnostics for multiple translation units. 112 class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 113 public: 114 /// Level - The level of the diagnostic, after it has been through mapping. 115 enum Level { 116 Ignored, Note, Warning, Error, Fatal 117 }; 118 119 private: 120 /// CustomDiagInfo - Information for uniquing and looking up custom diags. 121 diag::CustomDiagInfo *CustomDiagInfo; 122 123 public: 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. 130 unsigned getCustomDiagID(Level L, StringRef Message); 131 132 //===--------------------------------------------------------------------===// 133 // Diagnostic classification and reporting interfaces. 134 // 135 136 /// getDescription - Given a diagnostic ID, return a description of the 137 /// issue. 138 StringRef getDescription(unsigned DiagID) const; 139 140 /// 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. 144 static bool isBuiltinWarningOrExtension(unsigned DiagID); 145 146 /// \brief Return true if the specified diagnostic is mapped to errors by 147 /// default. 148 static bool isDefaultMappingAsError(unsigned DiagID); 149 150 /// \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 /// isBuiltinExtensionDiag(unsigned DiagID)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. 173 static StringRef getWarningOptionForDiag(unsigned DiagID); 174 175 /// getCategoryNumberForDiag - Return the category number that a specified 176 /// DiagID belongs to, or 0 if no category. 177 static unsigned getCategoryNumberForDiag(unsigned DiagID); 178 179 /// getNumberOfCategories - Return the number of categories 180 static unsigned getNumberOfCategories(); 181 182 /// getCategoryNameFromID - Given a category ID, return the name of the 183 /// category. 184 static StringRef getCategoryNameFromID(unsigned CategoryID); 185 186 /// isARCDiagnostic - Return true if a given diagnostic falls into an 187 /// ARC diagnostic category; 188 static bool isARCDiagnostic(unsigned DiagID); 189 190 /// \brief Enumeration describing how the the emission of a diagnostic should 191 /// be treated when it occurs during C++ template argument deduction. 192 enum SFINAEResponse { 193 /// \brief The diagnostic should not be reported, but it should cause 194 /// template argument deduction to fail. 195 /// 196 /// The vast majority of errors that occur during template argument 197 /// deduction fall into this category. 198 SFINAE_SubstitutionFailure, 199 200 /// \brief The diagnostic should be suppressed entirely. 201 /// 202 /// Warnings generally fall into this category. 203 SFINAE_Suppress, 204 205 /// \brief The diagnostic should be reported. 206 /// 207 /// The diagnostic should be reported. Various fatal errors (e.g., 208 /// template instantiation depth exceeded) fall into this category. 209 SFINAE_Report, 210 211 /// \brief The diagnostic is an access-control diagnostic, which will be 212 /// substitution failures in some contexts and reported in others. 213 SFINAE_AccessControl 214 }; 215 216 /// \brief Determines whether the given built-in diagnostic ID is 217 /// for an error that is suppressed if it occurs during C++ template 218 /// argument deduction. 219 /// 220 /// When an error is suppressed due to SFINAE, the template argument 221 /// deduction fails but no diagnostic is emitted. Certain classes of 222 /// errors, such as those errors that involve C++ access control, 223 /// are not SFINAE errors. 224 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 225 226 /// \brief Get the set of all diagnostic IDs in the group with the given name. 227 /// 228 /// \param Diags [out] - On return, the diagnostics in the group. 229 /// \returns True if the given group is unknown, false otherwise. 230 bool getDiagnosticsInGroup(StringRef Group, 231 llvm::SmallVectorImpl<diag::kind> &Diags) const; 232 233 /// \brief Get the set of all diagnostic IDs. 234 void getAllDiagnostics(llvm::SmallVectorImpl<diag::kind> &Diags) const; 235 236 /// \brief Get the warning option with the closest edit distance to the given 237 /// group name. 238 static StringRef getNearestWarningOption(StringRef Group); 239 240 private: 241 /// \brief Get the set of all diagnostic IDs in the given group. 242 /// 243 /// \param Diags [out] - On return, the diagnostics in the group. 244 void getDiagnosticsInGroup(const WarningOption *Group, 245 llvm::SmallVectorImpl<diag::kind> &Diags) const; 246 247 /// \brief Based on the way the client configured the DiagnosticsEngine 248 /// object, classify the specified diagnostic ID into a Level, consumable by 249 /// the DiagnosticClient. 250 /// 251 /// \param Loc The source location we are interested in finding out the 252 /// diagnostic state. Can be null in order to query the latest state. 253 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 254 const DiagnosticsEngine &Diag) const; 255 256 /// getDiagnosticLevel - This is an internal implementation helper used when 257 /// DiagClass is already known. 258 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, 259 unsigned DiagClass, 260 SourceLocation Loc, 261 const DiagnosticsEngine &Diag) const; 262 263 /// ProcessDiag - This is the method used to report a diagnostic that is 264 /// finally fully formed. 265 /// 266 /// \returns true if the diagnostic was emitted, false if it was 267 /// suppressed. 268 bool ProcessDiag(DiagnosticsEngine &Diag) const; 269 270 /// \brief Whether the diagnostic may leave the AST in a state where some 271 /// invariants can break. 272 bool isUnrecoverable(unsigned DiagID) const; 273 274 friend class DiagnosticsEngine; 275 }; 276 277 } // end namespace clang 278 279 #endif 280