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 /// \file 11 /// \brief Defines the Diagnostic IDs-related interfaces. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_DIAGNOSTICIDS_H 16 #define LLVM_CLANG_DIAGNOSTICIDS_H 17 18 #include "clang/Basic/LLVM.h" 19 #include "llvm/ADT/IntrusiveRefCntPtr.h" 20 #include "llvm/ADT/StringRef.h" 21 22 namespace clang { 23 class DiagnosticsEngine; 24 class SourceLocation; 25 struct WarningOption; 26 27 // Import the diagnostic enums themselves. 28 namespace diag { 29 // Start position for diagnostics. 30 enum { 31 DIAG_START_COMMON = 0, 32 DIAG_START_DRIVER = DIAG_START_COMMON + 300, 33 DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, 34 DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, 35 DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 36 DIAG_START_PARSE = DIAG_START_LEX + 300, 37 DIAG_START_AST = DIAG_START_PARSE + 400, 38 DIAG_START_COMMENT = DIAG_START_AST + 100, 39 DIAG_START_SEMA = DIAG_START_COMMENT + 100, 40 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 41 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 42 }; 43 44 class CustomDiagInfo; 45 46 /// \brief 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) ENUM, 53 #define COMMONSTART 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: 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 94 diag::Mapping getMapping() const { return diag::Mapping(Mapping); } 95 void setMapping(diag::Mapping Value) { Mapping = Value; } 96 97 bool isUser() const { return IsUser; } 98 bool isPragma() const { return IsPragma; } 99 100 bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } 101 void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } 102 103 bool hasNoWarningAsError() const { return HasNoWarningAsError; } 104 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 105 106 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } 107 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 108 }; 109 110 /// \brief Used for handling and querying diagnostic IDs. 111 /// 112 /// Can be used and shared by multiple Diagnostics for multiple translation units. 113 class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 114 public: 115 /// \brief The level of the diagnostic, after it has been through mapping. 116 enum Level { 117 Ignored, Note, Warning, Error, Fatal 118 }; 119 120 private: 121 /// \brief Information for uniquing and looking up custom diags. 122 diag::CustomDiagInfo *CustomDiagInfo; 123 124 public: 125 DiagnosticIDs(); 126 ~DiagnosticIDs(); 127 128 /// \brief Return an ID for a diagnostic with the specified message and level. 129 /// 130 /// If this is the first request for this diagnostic, it is registered and 131 /// created, otherwise the existing ID is returned. 132 unsigned getCustomDiagID(Level L, StringRef Message); 133 134 //===--------------------------------------------------------------------===// 135 // Diagnostic classification and reporting interfaces. 136 // 137 138 /// \brief Given a diagnostic ID, return a description of the issue. 139 StringRef getDescription(unsigned DiagID) const; 140 141 /// \brief Return true if the unmapped diagnostic levelof the specified 142 /// diagnostic ID is a Warning or Extension. 143 /// 144 /// This only works on builtin diagnostics, not custom ones, and is not 145 /// legal to call on NOTEs. 146 static bool isBuiltinWarningOrExtension(unsigned DiagID); 147 148 /// \brief Return true if the specified diagnostic is mapped to errors by 149 /// default. 150 static bool isDefaultMappingAsError(unsigned DiagID); 151 152 /// \brief Determine whether the given built-in diagnostic ID is a Note. 153 static bool isBuiltinNote(unsigned DiagID); 154 155 /// \brief Determine whether the given built-in diagnostic ID is for an 156 /// extension of some sort. 157 static bool isBuiltinExtensionDiag(unsigned DiagID) { 158 bool ignored; 159 return isBuiltinExtensionDiag(DiagID, ignored); 160 } 161 162 /// \brief Determine whether the given built-in diagnostic ID is for an 163 /// extension of some sort, and whether it is enabled by default. 164 /// 165 /// This also returns EnabledByDefault, which is set to indicate whether the 166 /// diagnostic is ignored by default (in which case -pedantic enables it) or 167 /// treated as a warning/error by default. 168 /// 169 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); 170 171 172 /// \brief Return the lowest-level warning option that enables the specified 173 /// diagnostic. 174 /// 175 /// If there is no -Wfoo flag that controls the diagnostic, this returns null. 176 static StringRef getWarningOptionForDiag(unsigned DiagID); 177 178 /// \brief Return the category number that a specified \p DiagID belongs to, 179 /// or 0 if no category. 180 static unsigned getCategoryNumberForDiag(unsigned DiagID); 181 182 /// \brief Return the number of diagnostic categories. 183 static unsigned getNumberOfCategories(); 184 185 /// \brief Given a category ID, return the name of the category. 186 static StringRef getCategoryNameFromID(unsigned CategoryID); 187 188 /// \brief Return true if a given diagnostic falls into an ARC diagnostic 189 /// category. 190 static bool isARCDiagnostic(unsigned DiagID); 191 192 /// \brief Enumeration describing how the emission of a diagnostic should 193 /// be treated when it occurs during C++ template argument deduction. 194 enum SFINAEResponse { 195 /// \brief The diagnostic should not be reported, but it should cause 196 /// template argument deduction to fail. 197 /// 198 /// The vast majority of errors that occur during template argument 199 /// deduction fall into this category. 200 SFINAE_SubstitutionFailure, 201 202 /// \brief The diagnostic should be suppressed entirely. 203 /// 204 /// Warnings generally fall into this category. 205 SFINAE_Suppress, 206 207 /// \brief The diagnostic should be reported. 208 /// 209 /// The diagnostic should be reported. Various fatal errors (e.g., 210 /// template instantiation depth exceeded) fall into this category. 211 SFINAE_Report, 212 213 /// \brief The diagnostic is an access-control diagnostic, which will be 214 /// substitution failures in some contexts and reported in others. 215 SFINAE_AccessControl 216 }; 217 218 /// \brief Determines whether the given built-in diagnostic ID is 219 /// for an error that is suppressed if it occurs during C++ template 220 /// argument deduction. 221 /// 222 /// When an error is suppressed due to SFINAE, the template argument 223 /// deduction fails but no diagnostic is emitted. Certain classes of 224 /// errors, such as those errors that involve C++ access control, 225 /// are not SFINAE errors. 226 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 227 228 /// \brief Get the set of all diagnostic IDs in the group with the given name. 229 /// 230 /// \param[out] Diags - On return, the diagnostics in the group. 231 /// \returns \c true if the given group is unknown, \c false otherwise. 232 bool getDiagnosticsInGroup(StringRef Group, 233 SmallVectorImpl<diag::kind> &Diags) const; 234 235 /// \brief Get the set of all diagnostic IDs. 236 void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const; 237 238 /// \brief Get the warning option with the closest edit distance to the given 239 /// group name. 240 static StringRef getNearestWarningOption(StringRef Group); 241 242 private: 243 /// \brief Get the set of all diagnostic IDs in the given group. 244 /// 245 /// \param[out] Diags - On return, the diagnostics in the group. 246 void getDiagnosticsInGroup(const WarningOption *Group, 247 SmallVectorImpl<diag::kind> &Diags) const; 248 249 /// \brief Classify the specified diagnostic ID into a Level, consumable by 250 /// the DiagnosticClient. 251 /// 252 /// The classification is based on the way the client configured the 253 /// DiagnosticsEngine object. 254 /// 255 /// \param Loc The source location for which we are interested in finding out 256 /// the diagnostic state. Can be null in order to query the latest state. 257 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 258 const DiagnosticsEngine &Diag) const; 259 260 /// \brief An internal implementation helper used when \p DiagClass is 261 /// already known. 262 DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, 263 unsigned DiagClass, 264 SourceLocation Loc, 265 const DiagnosticsEngine &Diag) const; 266 267 /// \brief Used to report a diagnostic that is finally fully formed. 268 /// 269 /// \returns \c true if the diagnostic was emitted, \c false if it was 270 /// suppressed. 271 bool ProcessDiag(DiagnosticsEngine &Diag) const; 272 273 /// \brief Used to emit a diagnostic that is finally fully formed, 274 /// ignoring suppression. 275 void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const; 276 277 /// \brief Whether the diagnostic may leave the AST in a state where some 278 /// invariants can break. 279 bool isUnrecoverable(unsigned DiagID) const; 280 281 friend class DiagnosticsEngine; 282 }; 283 284 } // end namespace clang 285 286 #endif 287