111397Sswallace//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===// 211397Sswallace// 33584Ssos// The LLVM Compiler Infrastructure 411397Sswallace// 5123786Speter// This file is distributed under the University of Illinois Open Source 6227692Sed// License. See LICENSE.TXT for details. 73584Ssos// 83584Ssos//===----------------------------------------------------------------------===// 93584Ssos/// 103584Ssos/// \file 1111397Sswallace/// \brief Defines the Diagnostic IDs-related interfaces. 1211397Sswallace/// 1311397Sswallace//===----------------------------------------------------------------------===// 1411397Sswallace 153584Ssos#ifndef LLVM_CLANG_DIAGNOSTICIDS_H 1660290Sbde#define LLVM_CLANG_DIAGNOSTICIDS_H 1760290Sbde 1811397Sswallace#include "clang/Basic/LLVM.h" 1911397Sswallace#include "llvm/ADT/IntrusiveRefCntPtr.h" 20209581Skib#include "llvm/ADT/StringRef.h" 21225618Skmacy 22225618Skmacynamespace clang { 23209581Skib class DiagnosticsEngine; 24225618Skmacy class SourceLocation; 25209581Skib 26225618Skmacy // Import the diagnostic enums themselves. 27209581Skib namespace diag { 28209581Skib // Start position for diagnostics. 29225618Skmacy enum { 30209581Skib DIAG_START_COMMON = 0, 31209581Skib DIAG_START_DRIVER = DIAG_START_COMMON + 300, 32209581Skib DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, 33209581Skib DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, 34209581Skib DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 35209581Skib DIAG_START_PARSE = DIAG_START_LEX + 300, 36209581Skib DIAG_START_AST = DIAG_START_PARSE + 400, 37225618Skmacy DIAG_START_COMMENT = DIAG_START_AST + 100, 38209581Skib DIAG_START_SEMA = DIAG_START_COMMENT + 100, 39209581Skib DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 40225618Skmacy DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 41209581Skib }; 42209581Skib 43209581Skib class CustomDiagInfo; 44225618Skmacy 45209581Skib /// \brief All of the diagnostics that can be emitted by the frontend. 46225618Skmacy typedef unsigned kind; 47209581Skib 48209581Skib // Get typedefs for common diagnostics. 49209581Skib enum { 50209581Skib#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 51209581Skib SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 52209581Skib#define COMMONSTART 53209581Skib#include "clang/Basic/DiagnosticCommonKinds.inc" 54209581Skib NUM_BUILTIN_COMMON_DIAGNOSTICS 55209581Skib#undef DIAG 56225618Skmacy }; 57209581Skib 58209581Skib /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 59209581Skib /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR 60209581Skib /// (emit as an error). It allows clients to map errors to 61225618Skmacy /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this 62225618Skmacy /// one). 63209581Skib enum Mapping { 64225618Skmacy // NOTE: 0 means "uncomputed". 65209581Skib MAP_IGNORE = 1, ///< Map this diagnostic to nothing, ignore it. 66209581Skib MAP_WARNING = 2, ///< Map this diagnostic to a warning. 67225618Skmacy MAP_ERROR = 3, ///< Map this diagnostic to an error. 68209581Skib MAP_FATAL = 4 ///< Map this diagnostic to a fatal error. 69209581Skib }; 70209581Skib } 71209581Skib 72209581Skibclass DiagnosticMappingInfo { 73209581Skib unsigned Mapping : 3; 74209581Skib unsigned IsUser : 1; 75209581Skib unsigned IsPragma : 1; 76209581Skib unsigned HasShowInSystemHeader : 1; 77209581Skib unsigned HasNoWarningAsError : 1; 78225618Skmacy unsigned HasNoErrorAsFatal : 1; 79209581Skib 80225618Skmacypublic: 81225618Skmacy static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, 82209581Skib bool IsPragma) { 83209581Skib DiagnosticMappingInfo Result; 84209581Skib Result.Mapping = Mapping; 85209581Skib Result.IsUser = IsUser; 86209581Skib Result.IsPragma = IsPragma; 87209581Skib Result.HasShowInSystemHeader = 0; 88209581Skib Result.HasNoWarningAsError = 0; 89209581Skib Result.HasNoErrorAsFatal = 0; 90209581Skib return Result; 91209581Skib } 92209581Skib 93209581Skib diag::Mapping getMapping() const { return diag::Mapping(Mapping); } 94209581Skib void setMapping(diag::Mapping Value) { Mapping = Value; } 95209581Skib 96209581Skib bool isUser() const { return IsUser; } 97209581Skib bool isPragma() const { return IsPragma; } 98209581Skib 99209581Skib bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } 100209581Skib void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } 101209581Skib 102209581Skib bool hasNoWarningAsError() const { return HasNoWarningAsError; } 103209581Skib void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 104209581Skib 105209581Skib bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } 106209581Skib void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 107225618Skmacy}; 108209581Skib 109209581Skib/// \brief Used for handling and querying diagnostic IDs. 110209581Skib/// 111209581Skib/// Can be used and shared by multiple Diagnostics for multiple translation units. 112209581Skibclass DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 113209581Skibpublic: 114209581Skib /// \brief The level of the diagnostic, after it has been through mapping. 115209581Skib enum Level { 116209581Skib Ignored, Note, Warning, Error, Fatal 117209581Skib }; 118209581Skib 119209581Skibprivate: 120209581Skib /// \brief Information for uniquing and looking up custom diags. 121209581Skib diag::CustomDiagInfo *CustomDiagInfo; 122209581Skib 123225618Skmacypublic: 124209581Skib DiagnosticIDs(); 125209581Skib ~DiagnosticIDs(); 126209581Skib 127209581Skib /// \brief Return an ID for a diagnostic with the specified message and level. 128209581Skib /// 129209581Skib /// If this is the first request for this diagnostic, it is registered and 130209581Skib /// created, otherwise the existing ID is returned. 131209581Skib unsigned getCustomDiagID(Level L, StringRef Message); 132209581Skib 133209581Skib //===--------------------------------------------------------------------===// 134209581Skib // Diagnostic classification and reporting interfaces. 135209581Skib // 136209581Skib 137209581Skib /// \brief Given a diagnostic ID, return a description of the issue. 138209581Skib StringRef getDescription(unsigned DiagID) const; 139209581Skib 140209581Skib /// \brief Return true if the unmapped diagnostic levelof the specified 141209581Skib /// diagnostic ID is a Warning or Extension. 142209581Skib /// 143209581Skib /// This only works on builtin diagnostics, not custom ones, and is not 144209581Skib /// legal to call on NOTEs. 145209581Skib static bool isBuiltinWarningOrExtension(unsigned DiagID); 146209581Skib 147209581Skib /// \brief Return true if the specified diagnostic is mapped to errors by 1483584Ssos /// 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