1f4a2713aSLionel Sambuc //===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===// 2f4a2713aSLionel Sambuc // 3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4f4a2713aSLionel Sambuc // 5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7f4a2713aSLionel Sambuc // 8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9f4a2713aSLionel Sambuc /// 10f4a2713aSLionel Sambuc /// \file 11f4a2713aSLionel Sambuc /// \brief Defines the Diagnostic IDs-related interfaces. 12f4a2713aSLionel Sambuc /// 13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 14f4a2713aSLionel Sambuc 15*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H 16*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H 17f4a2713aSLionel Sambuc 18f4a2713aSLionel Sambuc #include "clang/Basic/LLVM.h" 19f4a2713aSLionel Sambuc #include "llvm/ADT/IntrusiveRefCntPtr.h" 20f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h" 21f4a2713aSLionel Sambuc 22f4a2713aSLionel Sambuc namespace clang { 23f4a2713aSLionel Sambuc class DiagnosticsEngine; 24f4a2713aSLionel Sambuc class SourceLocation; 25f4a2713aSLionel Sambuc 26f4a2713aSLionel Sambuc // Import the diagnostic enums themselves. 27f4a2713aSLionel Sambuc namespace diag { 28f4a2713aSLionel Sambuc // Start position for diagnostics. 29f4a2713aSLionel Sambuc enum { 30f4a2713aSLionel Sambuc DIAG_START_COMMON = 0, 31f4a2713aSLionel Sambuc DIAG_START_DRIVER = DIAG_START_COMMON + 300, 32f4a2713aSLionel Sambuc DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, 33f4a2713aSLionel Sambuc DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, 34f4a2713aSLionel Sambuc DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 35f4a2713aSLionel Sambuc DIAG_START_PARSE = DIAG_START_LEX + 300, 36*0a6a1f1dSLionel Sambuc DIAG_START_AST = DIAG_START_PARSE + 500, 37f4a2713aSLionel Sambuc DIAG_START_COMMENT = DIAG_START_AST + 100, 38f4a2713aSLionel Sambuc DIAG_START_SEMA = DIAG_START_COMMENT + 100, 39f4a2713aSLionel Sambuc DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 40f4a2713aSLionel Sambuc DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 41f4a2713aSLionel Sambuc }; 42f4a2713aSLionel Sambuc 43f4a2713aSLionel Sambuc class CustomDiagInfo; 44f4a2713aSLionel Sambuc 45f4a2713aSLionel Sambuc /// \brief All of the diagnostics that can be emitted by the frontend. 46f4a2713aSLionel Sambuc typedef unsigned kind; 47f4a2713aSLionel Sambuc 48f4a2713aSLionel Sambuc // Get typedefs for common diagnostics. 49f4a2713aSLionel Sambuc enum { 50f4a2713aSLionel Sambuc #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 51f4a2713aSLionel Sambuc SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 52f4a2713aSLionel Sambuc #define COMMONSTART 53f4a2713aSLionel Sambuc #include "clang/Basic/DiagnosticCommonKinds.inc" 54f4a2713aSLionel Sambuc NUM_BUILTIN_COMMON_DIAGNOSTICS 55f4a2713aSLionel Sambuc #undef DIAG 56f4a2713aSLionel Sambuc }; 57f4a2713aSLionel Sambuc 58f4a2713aSLionel Sambuc /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 59*0a6a1f1dSLionel Sambuc /// to either Ignore (nothing), Remark (emit a remark), Warning 60*0a6a1f1dSLionel Sambuc /// (emit a warning) or Error (emit as an error). It allows clients to 61*0a6a1f1dSLionel Sambuc /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one). 62*0a6a1f1dSLionel Sambuc enum class Severity { 63f4a2713aSLionel Sambuc // NOTE: 0 means "uncomputed". 64*0a6a1f1dSLionel Sambuc Ignored = 1, ///< Do not present this diagnostic, ignore it. 65*0a6a1f1dSLionel Sambuc Remark = 2, ///< Present this diagnostic as a remark. 66*0a6a1f1dSLionel Sambuc Warning = 3, ///< Present this diagnostic as a warning. 67*0a6a1f1dSLionel Sambuc Error = 4, ///< Present this diagnostic as an error. 68*0a6a1f1dSLionel Sambuc Fatal = 5 ///< Present this diagnostic as a fatal error. 69*0a6a1f1dSLionel Sambuc }; 70*0a6a1f1dSLionel Sambuc 71*0a6a1f1dSLionel Sambuc /// Flavors of diagnostics we can emit. Used to filter for a particular 72*0a6a1f1dSLionel Sambuc /// kind of diagnostic (for instance, for -W/-R flags). 73*0a6a1f1dSLionel Sambuc enum class Flavor { 74*0a6a1f1dSLionel Sambuc WarningOrError, ///< A diagnostic that indicates a problem or potential 75*0a6a1f1dSLionel Sambuc ///< problem. Can be made fatal by -Werror. 76*0a6a1f1dSLionel Sambuc Remark ///< A diagnostic that indicates normal progress through 77*0a6a1f1dSLionel Sambuc ///< compilation. 78f4a2713aSLionel Sambuc }; 79f4a2713aSLionel Sambuc } 80f4a2713aSLionel Sambuc 81*0a6a1f1dSLionel Sambuc class DiagnosticMapping { 82*0a6a1f1dSLionel Sambuc unsigned Severity : 3; 83f4a2713aSLionel Sambuc unsigned IsUser : 1; 84f4a2713aSLionel Sambuc unsigned IsPragma : 1; 85f4a2713aSLionel Sambuc unsigned HasNoWarningAsError : 1; 86f4a2713aSLionel Sambuc unsigned HasNoErrorAsFatal : 1; 87f4a2713aSLionel Sambuc 88f4a2713aSLionel Sambuc public: Make(diag::Severity Severity,bool IsUser,bool IsPragma)89*0a6a1f1dSLionel Sambuc static DiagnosticMapping Make(diag::Severity Severity, bool IsUser, 90f4a2713aSLionel Sambuc bool IsPragma) { 91*0a6a1f1dSLionel Sambuc DiagnosticMapping Result; 92*0a6a1f1dSLionel Sambuc Result.Severity = (unsigned)Severity; 93f4a2713aSLionel Sambuc Result.IsUser = IsUser; 94f4a2713aSLionel Sambuc Result.IsPragma = IsPragma; 95f4a2713aSLionel Sambuc Result.HasNoWarningAsError = 0; 96f4a2713aSLionel Sambuc Result.HasNoErrorAsFatal = 0; 97f4a2713aSLionel Sambuc return Result; 98f4a2713aSLionel Sambuc } 99f4a2713aSLionel Sambuc getSeverity()100*0a6a1f1dSLionel Sambuc diag::Severity getSeverity() const { return (diag::Severity)Severity; } setSeverity(diag::Severity Value)101*0a6a1f1dSLionel Sambuc void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; } 102f4a2713aSLionel Sambuc isUser()103f4a2713aSLionel Sambuc bool isUser() const { return IsUser; } isPragma()104f4a2713aSLionel Sambuc bool isPragma() const { return IsPragma; } 105f4a2713aSLionel Sambuc hasNoWarningAsError()106f4a2713aSLionel Sambuc bool hasNoWarningAsError() const { return HasNoWarningAsError; } setNoWarningAsError(bool Value)107f4a2713aSLionel Sambuc void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 108f4a2713aSLionel Sambuc hasNoErrorAsFatal()109f4a2713aSLionel Sambuc bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } setNoErrorAsFatal(bool Value)110f4a2713aSLionel Sambuc void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 111f4a2713aSLionel Sambuc }; 112f4a2713aSLionel Sambuc 113f4a2713aSLionel Sambuc /// \brief Used for handling and querying diagnostic IDs. 114f4a2713aSLionel Sambuc /// 115f4a2713aSLionel Sambuc /// Can be used and shared by multiple Diagnostics for multiple translation units. 116f4a2713aSLionel Sambuc class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 117f4a2713aSLionel Sambuc public: 118f4a2713aSLionel Sambuc /// \brief The level of the diagnostic, after it has been through mapping. 119f4a2713aSLionel Sambuc enum Level { 120*0a6a1f1dSLionel Sambuc Ignored, Note, Remark, Warning, Error, Fatal 121f4a2713aSLionel Sambuc }; 122f4a2713aSLionel Sambuc 123f4a2713aSLionel Sambuc private: 124f4a2713aSLionel Sambuc /// \brief Information for uniquing and looking up custom diags. 125f4a2713aSLionel Sambuc diag::CustomDiagInfo *CustomDiagInfo; 126f4a2713aSLionel Sambuc 127f4a2713aSLionel Sambuc public: 128f4a2713aSLionel Sambuc DiagnosticIDs(); 129f4a2713aSLionel Sambuc ~DiagnosticIDs(); 130f4a2713aSLionel Sambuc 131*0a6a1f1dSLionel Sambuc /// \brief Return an ID for a diagnostic with the specified format string and 132*0a6a1f1dSLionel Sambuc /// level. 133f4a2713aSLionel Sambuc /// 134f4a2713aSLionel Sambuc /// If this is the first request for this diagnostic, it is registered and 135f4a2713aSLionel Sambuc /// created, otherwise the existing ID is returned. 136*0a6a1f1dSLionel Sambuc 137*0a6a1f1dSLionel Sambuc // FIXME: Replace this function with a create-only facilty like 138*0a6a1f1dSLionel Sambuc // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of 139*0a6a1f1dSLionel Sambuc // writing, nearly all callers of this function were invalid. 140*0a6a1f1dSLionel Sambuc unsigned getCustomDiagID(Level L, StringRef FormatString); 141f4a2713aSLionel Sambuc 142f4a2713aSLionel Sambuc //===--------------------------------------------------------------------===// 143f4a2713aSLionel Sambuc // Diagnostic classification and reporting interfaces. 144f4a2713aSLionel Sambuc // 145f4a2713aSLionel Sambuc 146f4a2713aSLionel Sambuc /// \brief Given a diagnostic ID, return a description of the issue. 147f4a2713aSLionel Sambuc StringRef getDescription(unsigned DiagID) const; 148f4a2713aSLionel Sambuc 149f4a2713aSLionel Sambuc /// \brief Return true if the unmapped diagnostic levelof the specified 150f4a2713aSLionel Sambuc /// diagnostic ID is a Warning or Extension. 151f4a2713aSLionel Sambuc /// 152f4a2713aSLionel Sambuc /// This only works on builtin diagnostics, not custom ones, and is not 153f4a2713aSLionel Sambuc /// legal to call on NOTEs. 154f4a2713aSLionel Sambuc static bool isBuiltinWarningOrExtension(unsigned DiagID); 155f4a2713aSLionel Sambuc 156f4a2713aSLionel Sambuc /// \brief Return true if the specified diagnostic is mapped to errors by 157f4a2713aSLionel Sambuc /// default. 158f4a2713aSLionel Sambuc static bool isDefaultMappingAsError(unsigned DiagID); 159f4a2713aSLionel Sambuc 160f4a2713aSLionel Sambuc /// \brief Determine whether the given built-in diagnostic ID is a Note. 161f4a2713aSLionel Sambuc static bool isBuiltinNote(unsigned DiagID); 162f4a2713aSLionel Sambuc 163f4a2713aSLionel Sambuc /// \brief Determine whether the given built-in diagnostic ID is for an 164f4a2713aSLionel Sambuc /// extension of some sort. isBuiltinExtensionDiag(unsigned DiagID)165f4a2713aSLionel Sambuc static bool isBuiltinExtensionDiag(unsigned DiagID) { 166f4a2713aSLionel Sambuc bool ignored; 167f4a2713aSLionel Sambuc return isBuiltinExtensionDiag(DiagID, ignored); 168f4a2713aSLionel Sambuc } 169f4a2713aSLionel Sambuc 170f4a2713aSLionel Sambuc /// \brief Determine whether the given built-in diagnostic ID is for an 171f4a2713aSLionel Sambuc /// extension of some sort, and whether it is enabled by default. 172f4a2713aSLionel Sambuc /// 173f4a2713aSLionel Sambuc /// This also returns EnabledByDefault, which is set to indicate whether the 174f4a2713aSLionel Sambuc /// diagnostic is ignored by default (in which case -pedantic enables it) or 175f4a2713aSLionel Sambuc /// treated as a warning/error by default. 176f4a2713aSLionel Sambuc /// 177f4a2713aSLionel Sambuc static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); 178f4a2713aSLionel Sambuc 179f4a2713aSLionel Sambuc 180f4a2713aSLionel Sambuc /// \brief Return the lowest-level warning option that enables the specified 181f4a2713aSLionel Sambuc /// diagnostic. 182f4a2713aSLionel Sambuc /// 183f4a2713aSLionel Sambuc /// If there is no -Wfoo flag that controls the diagnostic, this returns null. 184f4a2713aSLionel Sambuc static StringRef getWarningOptionForDiag(unsigned DiagID); 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc /// \brief Return the category number that a specified \p DiagID belongs to, 187f4a2713aSLionel Sambuc /// or 0 if no category. 188f4a2713aSLionel Sambuc static unsigned getCategoryNumberForDiag(unsigned DiagID); 189f4a2713aSLionel Sambuc 190f4a2713aSLionel Sambuc /// \brief Return the number of diagnostic categories. 191f4a2713aSLionel Sambuc static unsigned getNumberOfCategories(); 192f4a2713aSLionel Sambuc 193f4a2713aSLionel Sambuc /// \brief Given a category ID, return the name of the category. 194f4a2713aSLionel Sambuc static StringRef getCategoryNameFromID(unsigned CategoryID); 195f4a2713aSLionel Sambuc 196f4a2713aSLionel Sambuc /// \brief Return true if a given diagnostic falls into an ARC diagnostic 197f4a2713aSLionel Sambuc /// category. 198f4a2713aSLionel Sambuc static bool isARCDiagnostic(unsigned DiagID); 199f4a2713aSLionel Sambuc 200f4a2713aSLionel Sambuc /// \brief Enumeration describing how the emission of a diagnostic should 201f4a2713aSLionel Sambuc /// be treated when it occurs during C++ template argument deduction. 202f4a2713aSLionel Sambuc enum SFINAEResponse { 203f4a2713aSLionel Sambuc /// \brief The diagnostic should not be reported, but it should cause 204f4a2713aSLionel Sambuc /// template argument deduction to fail. 205f4a2713aSLionel Sambuc /// 206f4a2713aSLionel Sambuc /// The vast majority of errors that occur during template argument 207f4a2713aSLionel Sambuc /// deduction fall into this category. 208f4a2713aSLionel Sambuc SFINAE_SubstitutionFailure, 209f4a2713aSLionel Sambuc 210f4a2713aSLionel Sambuc /// \brief The diagnostic should be suppressed entirely. 211f4a2713aSLionel Sambuc /// 212f4a2713aSLionel Sambuc /// Warnings generally fall into this category. 213f4a2713aSLionel Sambuc SFINAE_Suppress, 214f4a2713aSLionel Sambuc 215f4a2713aSLionel Sambuc /// \brief The diagnostic should be reported. 216f4a2713aSLionel Sambuc /// 217f4a2713aSLionel Sambuc /// The diagnostic should be reported. Various fatal errors (e.g., 218f4a2713aSLionel Sambuc /// template instantiation depth exceeded) fall into this category. 219f4a2713aSLionel Sambuc SFINAE_Report, 220f4a2713aSLionel Sambuc 221f4a2713aSLionel Sambuc /// \brief The diagnostic is an access-control diagnostic, which will be 222f4a2713aSLionel Sambuc /// substitution failures in some contexts and reported in others. 223f4a2713aSLionel Sambuc SFINAE_AccessControl 224f4a2713aSLionel Sambuc }; 225f4a2713aSLionel Sambuc 226f4a2713aSLionel Sambuc /// \brief Determines whether the given built-in diagnostic ID is 227f4a2713aSLionel Sambuc /// for an error that is suppressed if it occurs during C++ template 228f4a2713aSLionel Sambuc /// argument deduction. 229f4a2713aSLionel Sambuc /// 230f4a2713aSLionel Sambuc /// When an error is suppressed due to SFINAE, the template argument 231f4a2713aSLionel Sambuc /// deduction fails but no diagnostic is emitted. Certain classes of 232f4a2713aSLionel Sambuc /// errors, such as those errors that involve C++ access control, 233f4a2713aSLionel Sambuc /// are not SFINAE errors. 234f4a2713aSLionel Sambuc static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 235f4a2713aSLionel Sambuc 236f4a2713aSLionel Sambuc /// \brief Get the set of all diagnostic IDs in the group with the given name. 237f4a2713aSLionel Sambuc /// 238f4a2713aSLionel Sambuc /// \param[out] Diags - On return, the diagnostics in the group. 239f4a2713aSLionel Sambuc /// \returns \c true if the given group is unknown, \c false otherwise. 240*0a6a1f1dSLionel Sambuc bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, 241f4a2713aSLionel Sambuc SmallVectorImpl<diag::kind> &Diags) const; 242f4a2713aSLionel Sambuc 243f4a2713aSLionel Sambuc /// \brief Get the set of all diagnostic IDs. 244*0a6a1f1dSLionel Sambuc void getAllDiagnostics(diag::Flavor Flavor, 245*0a6a1f1dSLionel Sambuc SmallVectorImpl<diag::kind> &Diags) const; 246f4a2713aSLionel Sambuc 247*0a6a1f1dSLionel Sambuc /// \brief Get the diagnostic option with the closest edit distance to the 248*0a6a1f1dSLionel Sambuc /// given group name. 249*0a6a1f1dSLionel Sambuc static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group); 250f4a2713aSLionel Sambuc 251f4a2713aSLionel Sambuc private: 252f4a2713aSLionel Sambuc /// \brief Classify the specified diagnostic ID into a Level, consumable by 253f4a2713aSLionel Sambuc /// the DiagnosticClient. 254f4a2713aSLionel Sambuc /// 255f4a2713aSLionel Sambuc /// The classification is based on the way the client configured the 256f4a2713aSLionel Sambuc /// DiagnosticsEngine object. 257f4a2713aSLionel Sambuc /// 258f4a2713aSLionel Sambuc /// \param Loc The source location for which we are interested in finding out 259f4a2713aSLionel Sambuc /// the diagnostic state. Can be null in order to query the latest state. 260*0a6a1f1dSLionel Sambuc DiagnosticIDs::Level 261*0a6a1f1dSLionel Sambuc getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 262*0a6a1f1dSLionel Sambuc const DiagnosticsEngine &Diag) const LLVM_READONLY; 263f4a2713aSLionel Sambuc 264*0a6a1f1dSLionel Sambuc diag::Severity 265*0a6a1f1dSLionel Sambuc getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, 266*0a6a1f1dSLionel Sambuc const DiagnosticsEngine &Diag) const LLVM_READONLY; 267f4a2713aSLionel Sambuc 268f4a2713aSLionel Sambuc /// \brief Used to report a diagnostic that is finally fully formed. 269f4a2713aSLionel Sambuc /// 270f4a2713aSLionel Sambuc /// \returns \c true if the diagnostic was emitted, \c false if it was 271f4a2713aSLionel Sambuc /// suppressed. 272f4a2713aSLionel Sambuc bool ProcessDiag(DiagnosticsEngine &Diag) const; 273f4a2713aSLionel Sambuc 274f4a2713aSLionel Sambuc /// \brief Used to emit a diagnostic that is finally fully formed, 275f4a2713aSLionel Sambuc /// ignoring suppression. 276f4a2713aSLionel Sambuc void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const; 277f4a2713aSLionel Sambuc 278f4a2713aSLionel Sambuc /// \brief Whether the diagnostic may leave the AST in a state where some 279f4a2713aSLionel Sambuc /// invariants can break. 280f4a2713aSLionel Sambuc bool isUnrecoverable(unsigned DiagID) const; 281f4a2713aSLionel Sambuc 282f4a2713aSLionel Sambuc friend class DiagnosticsEngine; 283f4a2713aSLionel Sambuc }; 284f4a2713aSLionel Sambuc 285f4a2713aSLionel Sambuc } // end namespace clang 286f4a2713aSLionel Sambuc 287f4a2713aSLionel Sambuc #endif 288