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; 25218887Sdim 26218887Sdim // Import the diagnostic enums themselves. 27218887Sdim namespace diag { 28218887Sdim // Start position for diagnostics. 29218887Sdim enum { 30263508Sdim DIAG_START_COMMON = 0, 31263508Sdim DIAG_START_DRIVER = DIAG_START_COMMON + 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,\ 51263508Sdim SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 52263508Sdim#define COMMONSTART 53218887Sdim#include "clang/Basic/DiagnosticCommonKinds.inc" 54218887Sdim NUM_BUILTIN_COMMON_DIAGNOSTICS 55218887Sdim#undef DIAG 56218887Sdim }; 57218887Sdim 58218887Sdim /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 59218887Sdim /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR 60218887Sdim /// (emit as an error). It allows clients to map errors to 61218887Sdim /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this 62218887Sdim /// one). 63218887Sdim enum Mapping { 64218887Sdim // NOTE: 0 means "uncomputed". 65239462Sdim MAP_IGNORE = 1, ///< Map this diagnostic to nothing, ignore it. 66239462Sdim MAP_WARNING = 2, ///< Map this diagnostic to a warning. 67239462Sdim MAP_ERROR = 3, ///< Map this diagnostic to an error. 68239462Sdim MAP_FATAL = 4 ///< Map this diagnostic to a fatal error. 69218887Sdim }; 70218887Sdim } 71218887Sdim 72226633Sdimclass DiagnosticMappingInfo { 73226633Sdim unsigned Mapping : 3; 74226633Sdim unsigned IsUser : 1; 75226633Sdim unsigned IsPragma : 1; 76226633Sdim unsigned HasShowInSystemHeader : 1; 77226633Sdim unsigned HasNoWarningAsError : 1; 78226633Sdim unsigned HasNoErrorAsFatal : 1; 79226633Sdim 80226633Sdimpublic: 81226633Sdim static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, 82226633Sdim bool IsPragma) { 83226633Sdim DiagnosticMappingInfo Result; 84226633Sdim Result.Mapping = Mapping; 85226633Sdim Result.IsUser = IsUser; 86226633Sdim Result.IsPragma = IsPragma; 87226633Sdim Result.HasShowInSystemHeader = 0; 88226633Sdim Result.HasNoWarningAsError = 0; 89226633Sdim Result.HasNoErrorAsFatal = 0; 90226633Sdim return Result; 91226633Sdim } 92226633Sdim 93226633Sdim diag::Mapping getMapping() const { return diag::Mapping(Mapping); } 94226633Sdim void setMapping(diag::Mapping Value) { Mapping = Value; } 95226633Sdim 96226633Sdim bool isUser() const { return IsUser; } 97226633Sdim bool isPragma() const { return IsPragma; } 98226633Sdim 99226633Sdim bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } 100226633Sdim void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } 101226633Sdim 102226633Sdim bool hasNoWarningAsError() const { return HasNoWarningAsError; } 103226633Sdim void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 104226633Sdim 105226633Sdim bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } 106226633Sdim void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 107226633Sdim}; 108226633Sdim 109263508Sdim/// \brief Used for handling and querying diagnostic IDs. 110263508Sdim/// 111263508Sdim/// Can be used and shared by multiple Diagnostics for multiple translation units. 112234353Sdimclass DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 113218887Sdimpublic: 114263508Sdim /// \brief The level of the diagnostic, after it has been through mapping. 115218887Sdim enum Level { 116218887Sdim Ignored, Note, Warning, Error, Fatal 117218887Sdim }; 118218887Sdim 119218887Sdimprivate: 120239462Sdim /// \brief Information for uniquing and looking up custom diags. 121218887Sdim diag::CustomDiagInfo *CustomDiagInfo; 122218887Sdim 123218887Sdimpublic: 124218887Sdim DiagnosticIDs(); 125218887Sdim ~DiagnosticIDs(); 126218887Sdim 127239462Sdim /// \brief Return an ID for a diagnostic with the specified message and level. 128239462Sdim /// 129249423Sdim /// If this is the first request for this diagnostic, it is registered and 130239462Sdim /// created, otherwise the existing ID is returned. 131226633Sdim unsigned getCustomDiagID(Level L, StringRef Message); 132218887Sdim 133218887Sdim //===--------------------------------------------------------------------===// 134218887Sdim // Diagnostic classification and reporting interfaces. 135218887Sdim // 136218887Sdim 137239462Sdim /// \brief Given a diagnostic ID, return a description of the issue. 138226633Sdim StringRef getDescription(unsigned DiagID) const; 139218887Sdim 140239462Sdim /// \brief Return true if the unmapped diagnostic levelof the specified 141239462Sdim /// diagnostic ID is a Warning or Extension. 142239462Sdim /// 143239462Sdim /// This only works on builtin diagnostics, not custom ones, and is not 144239462Sdim /// legal to call on NOTEs. 145218887Sdim static bool isBuiltinWarningOrExtension(unsigned DiagID); 146218887Sdim 147226633Sdim /// \brief Return true if the specified diagnostic is mapped to errors by 148226633Sdim /// default. 149226633Sdim static bool isDefaultMappingAsError(unsigned DiagID); 150226633Sdim 151239462Sdim /// \brief Determine whether the given built-in diagnostic ID is a Note. 152218887Sdim static bool isBuiltinNote(unsigned DiagID); 153218887Sdim 154239462Sdim /// \brief Determine whether the given built-in diagnostic ID is for an 155239462Sdim /// extension of some sort. 156218887Sdim static bool isBuiltinExtensionDiag(unsigned DiagID) { 157218887Sdim bool ignored; 158218887Sdim return isBuiltinExtensionDiag(DiagID, ignored); 159218887Sdim } 160218887Sdim 161239462Sdim /// \brief Determine whether the given built-in diagnostic ID is for an 162239462Sdim /// extension of some sort, and whether it is enabled by default. 163218887Sdim /// 164239462Sdim /// This also returns EnabledByDefault, which is set to indicate whether the 165239462Sdim /// diagnostic is ignored by default (in which case -pedantic enables it) or 166239462Sdim /// treated as a warning/error by default. 167239462Sdim /// 168218887Sdim static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); 169218887Sdim 170218887Sdim 171239462Sdim /// \brief Return the lowest-level warning option that enables the specified 172239462Sdim /// diagnostic. 173239462Sdim /// 174239462Sdim /// If there is no -Wfoo flag that controls the diagnostic, this returns null. 175226633Sdim static StringRef getWarningOptionForDiag(unsigned DiagID); 176223017Sdim 177239462Sdim /// \brief Return the category number that a specified \p DiagID belongs to, 178239462Sdim /// or 0 if no category. 179218887Sdim static unsigned getCategoryNumberForDiag(unsigned DiagID); 180218887Sdim 181239462Sdim /// \brief Return the number of diagnostic categories. 182223017Sdim static unsigned getNumberOfCategories(); 183223017Sdim 184239462Sdim /// \brief Given a category ID, return the name of the category. 185226633Sdim static StringRef getCategoryNameFromID(unsigned CategoryID); 186218887Sdim 187239462Sdim /// \brief Return true if a given diagnostic falls into an ARC diagnostic 188239462Sdim /// category. 189234353Sdim static bool isARCDiagnostic(unsigned DiagID); 190234353Sdim 191239462Sdim /// \brief Enumeration describing how the emission of a diagnostic should 192218887Sdim /// be treated when it occurs during C++ template argument deduction. 193218887Sdim enum SFINAEResponse { 194218887Sdim /// \brief The diagnostic should not be reported, but it should cause 195218887Sdim /// template argument deduction to fail. 196218887Sdim /// 197218887Sdim /// The vast majority of errors that occur during template argument 198218887Sdim /// deduction fall into this category. 199218887Sdim SFINAE_SubstitutionFailure, 200218887Sdim 201218887Sdim /// \brief The diagnostic should be suppressed entirely. 202218887Sdim /// 203218887Sdim /// Warnings generally fall into this category. 204218887Sdim SFINAE_Suppress, 205218887Sdim 206218887Sdim /// \brief The diagnostic should be reported. 207218887Sdim /// 208218887Sdim /// The diagnostic should be reported. Various fatal errors (e.g., 209218887Sdim /// template instantiation depth exceeded) fall into this category. 210218887Sdim SFINAE_Report, 211218887Sdim 212218887Sdim /// \brief The diagnostic is an access-control diagnostic, which will be 213218887Sdim /// substitution failures in some contexts and reported in others. 214218887Sdim SFINAE_AccessControl 215218887Sdim }; 216218887Sdim 217218887Sdim /// \brief Determines whether the given built-in diagnostic ID is 218218887Sdim /// for an error that is suppressed if it occurs during C++ template 219218887Sdim /// argument deduction. 220218887Sdim /// 221218887Sdim /// When an error is suppressed due to SFINAE, the template argument 222218887Sdim /// deduction fails but no diagnostic is emitted. Certain classes of 223218887Sdim /// errors, such as those errors that involve C++ access control, 224218887Sdim /// are not SFINAE errors. 225218887Sdim static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 226218887Sdim 227226633Sdim /// \brief Get the set of all diagnostic IDs in the group with the given name. 228226633Sdim /// 229263508Sdim /// \param[out] Diags - On return, the diagnostics in the group. 230263508Sdim /// \returns \c true if the given group is unknown, \c false otherwise. 231226633Sdim bool getDiagnosticsInGroup(StringRef Group, 232249423Sdim SmallVectorImpl<diag::kind> &Diags) const; 233226633Sdim 234234353Sdim /// \brief Get the set of all diagnostic IDs. 235249423Sdim void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const; 236234353Sdim 237234353Sdim /// \brief Get the warning option with the closest edit distance to the given 238234353Sdim /// group name. 239234353Sdim static StringRef getNearestWarningOption(StringRef Group); 240234353Sdim 241218887Sdimprivate: 242263508Sdim /// \brief Classify the specified diagnostic ID into a Level, consumable by 243218887Sdim /// the DiagnosticClient. 244263508Sdim /// 245263508Sdim /// The classification is based on the way the client configured the 246263508Sdim /// DiagnosticsEngine object. 247218887Sdim /// 248263508Sdim /// \param Loc The source location for which we are interested in finding out 249263508Sdim /// the diagnostic state. Can be null in order to query the latest state. 250218887Sdim DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 251226633Sdim const DiagnosticsEngine &Diag) const; 252218887Sdim 253239462Sdim /// \brief An internal implementation helper used when \p DiagClass is 254239462Sdim /// already known. 255218887Sdim DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, 256218887Sdim unsigned DiagClass, 257218887Sdim SourceLocation Loc, 258226633Sdim const DiagnosticsEngine &Diag) const; 259218887Sdim 260239462Sdim /// \brief Used to report a diagnostic that is finally fully formed. 261218887Sdim /// 262239462Sdim /// \returns \c true if the diagnostic was emitted, \c false if it was 263218887Sdim /// suppressed. 264226633Sdim bool ProcessDiag(DiagnosticsEngine &Diag) const; 265218887Sdim 266239462Sdim /// \brief Used to emit a diagnostic that is finally fully formed, 267239462Sdim /// ignoring suppression. 268239462Sdim void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const; 269239462Sdim 270224145Sdim /// \brief Whether the diagnostic may leave the AST in a state where some 271224145Sdim /// invariants can break. 272224145Sdim bool isUnrecoverable(unsigned DiagID) const; 273224145Sdim 274226633Sdim friend class DiagnosticsEngine; 275218887Sdim}; 276218887Sdim 277218887Sdim} // end namespace clang 278218887Sdim 279218887Sdim#endif 280