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