1218887Sdim//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9239462Sdim/// 10239462Sdim/// \file 11239462Sdim/// \brief Defines the Diagnostic IDs-related interfaces. 12239462Sdim/// 13218887Sdim//===----------------------------------------------------------------------===// 14218887Sdim 15218887Sdim#ifndef LLVM_CLANG_DIAGNOSTICIDS_H 16218887Sdim#define LLVM_CLANG_DIAGNOSTICIDS_H 17218887Sdim 18249423Sdim#include "clang/Basic/LLVM.h" 19218887Sdim#include "llvm/ADT/IntrusiveRefCntPtr.h" 20218887Sdim#include "llvm/ADT/StringRef.h" 21218887Sdim 22218887Sdimnamespace clang { 23226633Sdim class DiagnosticsEngine; 24218887Sdim class SourceLocation; 25226633Sdim struct WarningOption; 26218887Sdim 27218887Sdim // Import the diagnostic enums themselves. 28218887Sdim namespace diag { 29218887Sdim // Start position for diagnostics. 30218887Sdim enum { 31234353Sdim DIAG_START_DRIVER = 300, 32234353Sdim DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, 33234353Sdim DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, 34234353Sdim DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 35234353Sdim DIAG_START_PARSE = DIAG_START_LEX + 300, 36234353Sdim DIAG_START_AST = DIAG_START_PARSE + 400, 37239462Sdim DIAG_START_COMMENT = DIAG_START_AST + 100, 38239462Sdim DIAG_START_SEMA = DIAG_START_COMMENT + 100, 39234353Sdim DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 40234353Sdim DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 41218887Sdim }; 42218887Sdim 43218887Sdim class CustomDiagInfo; 44218887Sdim 45239462Sdim /// \brief All of the diagnostics that can be emitted by the frontend. 46218887Sdim typedef unsigned kind; 47218887Sdim 48218887Sdim // Get typedefs for common diagnostics. 49218887Sdim enum { 50221345Sdim#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 51234353Sdim SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 52218887Sdim#include "clang/Basic/DiagnosticCommonKinds.inc" 53218887Sdim NUM_BUILTIN_COMMON_DIAGNOSTICS 54218887Sdim#undef DIAG 55218887Sdim }; 56218887Sdim 57218887Sdim /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 58218887Sdim /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR 59218887Sdim /// (emit as an error). It allows clients to map errors to 60218887Sdim /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this 61218887Sdim /// one). 62218887Sdim enum Mapping { 63218887Sdim // NOTE: 0 means "uncomputed". 64239462Sdim MAP_IGNORE = 1, ///< Map this diagnostic to nothing, ignore it. 65239462Sdim MAP_WARNING = 2, ///< Map this diagnostic to a warning. 66239462Sdim MAP_ERROR = 3, ///< Map this diagnostic to an error. 67239462Sdim MAP_FATAL = 4 ///< Map this diagnostic to a fatal error. 68218887Sdim }; 69218887Sdim } 70218887Sdim 71226633Sdimclass DiagnosticMappingInfo { 72226633Sdim unsigned Mapping : 3; 73226633Sdim unsigned IsUser : 1; 74226633Sdim unsigned IsPragma : 1; 75226633Sdim unsigned HasShowInSystemHeader : 1; 76226633Sdim unsigned HasNoWarningAsError : 1; 77226633Sdim unsigned HasNoErrorAsFatal : 1; 78226633Sdim 79226633Sdimpublic: 80226633Sdim static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, 81226633Sdim bool IsPragma) { 82226633Sdim DiagnosticMappingInfo Result; 83226633Sdim Result.Mapping = Mapping; 84226633Sdim Result.IsUser = IsUser; 85226633Sdim Result.IsPragma = IsPragma; 86226633Sdim Result.HasShowInSystemHeader = 0; 87226633Sdim Result.HasNoWarningAsError = 0; 88226633Sdim Result.HasNoErrorAsFatal = 0; 89226633Sdim return Result; 90226633Sdim } 91226633Sdim 92226633Sdim diag::Mapping getMapping() const { return diag::Mapping(Mapping); } 93226633Sdim void setMapping(diag::Mapping Value) { Mapping = Value; } 94226633Sdim 95226633Sdim bool isUser() const { return IsUser; } 96226633Sdim bool isPragma() const { return IsPragma; } 97226633Sdim 98226633Sdim bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } 99226633Sdim void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } 100226633Sdim 101226633Sdim bool hasNoWarningAsError() const { return HasNoWarningAsError; } 102226633Sdim void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 103226633Sdim 104226633Sdim bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } 105226633Sdim void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 106226633Sdim}; 107226633Sdim 108218887Sdim/// \brief Used for handling and querying diagnostic IDs. Can be used and shared 109218887Sdim/// by multiple Diagnostics for multiple translation units. 110234353Sdimclass DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 111218887Sdimpublic: 112239462Sdim /// Level The level of the diagnostic, after it has been through mapping. 113218887Sdim enum Level { 114218887Sdim Ignored, Note, Warning, Error, Fatal 115218887Sdim }; 116218887Sdim 117218887Sdimprivate: 118239462Sdim /// \brief Information for uniquing and looking up custom diags. 119218887Sdim diag::CustomDiagInfo *CustomDiagInfo; 120218887Sdim 121218887Sdimpublic: 122218887Sdim DiagnosticIDs(); 123218887Sdim ~DiagnosticIDs(); 124218887Sdim 125239462Sdim /// \brief Return an ID for a diagnostic with the specified message and level. 126239462Sdim /// 127249423Sdim /// If this is the first request for this diagnostic, it is registered and 128239462Sdim /// created, otherwise the existing ID is returned. 129226633Sdim unsigned getCustomDiagID(Level L, StringRef Message); 130218887Sdim 131218887Sdim //===--------------------------------------------------------------------===// 132218887Sdim // Diagnostic classification and reporting interfaces. 133218887Sdim // 134218887Sdim 135239462Sdim /// \brief Given a diagnostic ID, return a description of the issue. 136226633Sdim StringRef getDescription(unsigned DiagID) const; 137218887Sdim 138239462Sdim /// \brief Return true if the unmapped diagnostic levelof the specified 139239462Sdim /// diagnostic ID is a Warning or Extension. 140239462Sdim /// 141239462Sdim /// This only works on builtin diagnostics, not custom ones, and is not 142239462Sdim /// legal to call on NOTEs. 143218887Sdim static bool isBuiltinWarningOrExtension(unsigned DiagID); 144218887Sdim 145226633Sdim /// \brief Return true if the specified diagnostic is mapped to errors by 146226633Sdim /// default. 147226633Sdim static bool isDefaultMappingAsError(unsigned DiagID); 148226633Sdim 149239462Sdim /// \brief Determine whether the given built-in diagnostic ID is a Note. 150218887Sdim static bool isBuiltinNote(unsigned DiagID); 151218887Sdim 152239462Sdim /// \brief Determine whether the given built-in diagnostic ID is for an 153239462Sdim /// extension of some sort. 154218887Sdim static bool isBuiltinExtensionDiag(unsigned DiagID) { 155218887Sdim bool ignored; 156218887Sdim return isBuiltinExtensionDiag(DiagID, ignored); 157218887Sdim } 158218887Sdim 159239462Sdim /// \brief Determine whether the given built-in diagnostic ID is for an 160239462Sdim /// extension of some sort, and whether it is enabled by default. 161218887Sdim /// 162239462Sdim /// This also returns EnabledByDefault, which is set to indicate whether the 163239462Sdim /// diagnostic is ignored by default (in which case -pedantic enables it) or 164239462Sdim /// treated as a warning/error by default. 165239462Sdim /// 166218887Sdim static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); 167218887Sdim 168218887Sdim 169239462Sdim /// \brief Return the lowest-level warning option that enables the specified 170239462Sdim /// diagnostic. 171239462Sdim /// 172239462Sdim /// If there is no -Wfoo flag that controls the diagnostic, this returns null. 173226633Sdim static StringRef getWarningOptionForDiag(unsigned DiagID); 174223017Sdim 175239462Sdim /// \brief Return the category number that a specified \p DiagID belongs to, 176239462Sdim /// or 0 if no category. 177218887Sdim static unsigned getCategoryNumberForDiag(unsigned DiagID); 178218887Sdim 179239462Sdim /// \brief Return the number of diagnostic categories. 180223017Sdim static unsigned getNumberOfCategories(); 181223017Sdim 182239462Sdim /// \brief Given a category ID, return the name of the category. 183226633Sdim static StringRef getCategoryNameFromID(unsigned CategoryID); 184218887Sdim 185239462Sdim /// \brief Return true if a given diagnostic falls into an ARC diagnostic 186239462Sdim /// category. 187234353Sdim static bool isARCDiagnostic(unsigned DiagID); 188234353Sdim 189239462Sdim /// \brief Enumeration describing how the emission of a diagnostic should 190218887Sdim /// be treated when it occurs during C++ template argument deduction. 191218887Sdim enum SFINAEResponse { 192218887Sdim /// \brief The diagnostic should not be reported, but it should cause 193218887Sdim /// template argument deduction to fail. 194218887Sdim /// 195218887Sdim /// The vast majority of errors that occur during template argument 196218887Sdim /// deduction fall into this category. 197218887Sdim SFINAE_SubstitutionFailure, 198218887Sdim 199218887Sdim /// \brief The diagnostic should be suppressed entirely. 200218887Sdim /// 201218887Sdim /// Warnings generally fall into this category. 202218887Sdim SFINAE_Suppress, 203218887Sdim 204218887Sdim /// \brief The diagnostic should be reported. 205218887Sdim /// 206218887Sdim /// The diagnostic should be reported. Various fatal errors (e.g., 207218887Sdim /// template instantiation depth exceeded) fall into this category. 208218887Sdim SFINAE_Report, 209218887Sdim 210218887Sdim /// \brief The diagnostic is an access-control diagnostic, which will be 211218887Sdim /// substitution failures in some contexts and reported in others. 212218887Sdim SFINAE_AccessControl 213218887Sdim }; 214218887Sdim 215218887Sdim /// \brief Determines whether the given built-in diagnostic ID is 216218887Sdim /// for an error that is suppressed if it occurs during C++ template 217218887Sdim /// argument deduction. 218218887Sdim /// 219218887Sdim /// When an error is suppressed due to SFINAE, the template argument 220218887Sdim /// deduction fails but no diagnostic is emitted. Certain classes of 221218887Sdim /// errors, such as those errors that involve C++ access control, 222218887Sdim /// are not SFINAE errors. 223218887Sdim static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 224218887Sdim 225226633Sdim /// \brief Get the set of all diagnostic IDs in the group with the given name. 226226633Sdim /// 227226633Sdim /// \param Diags [out] - On return, the diagnostics in the group. 228226633Sdim /// \returns True if the given group is unknown, false otherwise. 229226633Sdim bool getDiagnosticsInGroup(StringRef Group, 230249423Sdim SmallVectorImpl<diag::kind> &Diags) const; 231226633Sdim 232234353Sdim /// \brief Get the set of all diagnostic IDs. 233249423Sdim void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const; 234234353Sdim 235234353Sdim /// \brief Get the warning option with the closest edit distance to the given 236234353Sdim /// group name. 237234353Sdim static StringRef getNearestWarningOption(StringRef Group); 238234353Sdim 239218887Sdimprivate: 240226633Sdim /// \brief Get the set of all diagnostic IDs in the given group. 241226633Sdim /// 242226633Sdim /// \param Diags [out] - On return, the diagnostics in the group. 243226633Sdim void getDiagnosticsInGroup(const WarningOption *Group, 244249423Sdim SmallVectorImpl<diag::kind> &Diags) const; 245226633Sdim 246226633Sdim /// \brief Based on the way the client configured the DiagnosticsEngine 247218887Sdim /// object, classify the specified diagnostic ID into a Level, consumable by 248218887Sdim /// the DiagnosticClient. 249218887Sdim /// 250218887Sdim /// \param Loc The source location we are interested in finding out the 251218887Sdim /// diagnostic state. Can be null in order to query the latest state. 252218887Sdim DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 253226633Sdim const DiagnosticsEngine &Diag) const; 254218887Sdim 255239462Sdim /// \brief An internal implementation helper used when \p DiagClass is 256239462Sdim /// already known. 257218887Sdim DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, 258218887Sdim unsigned DiagClass, 259218887Sdim SourceLocation Loc, 260226633Sdim const DiagnosticsEngine &Diag) const; 261218887Sdim 262239462Sdim /// \brief Used to report a diagnostic that is finally fully formed. 263218887Sdim /// 264239462Sdim /// \returns \c true if the diagnostic was emitted, \c false if it was 265218887Sdim /// suppressed. 266226633Sdim bool ProcessDiag(DiagnosticsEngine &Diag) const; 267218887Sdim 268239462Sdim /// \brief Used to emit a diagnostic that is finally fully formed, 269239462Sdim /// ignoring suppression. 270239462Sdim void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const; 271239462Sdim 272224145Sdim /// \brief Whether the diagnostic may leave the AST in a state where some 273224145Sdim /// invariants can break. 274224145Sdim bool isUnrecoverable(unsigned DiagID) const; 275224145Sdim 276226633Sdim friend class DiagnosticsEngine; 277218887Sdim}; 278218887Sdim 279218887Sdim} // end namespace clang 280218887Sdim 281218887Sdim#endif 282