clang API Documentation
00001 //===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Defines the Diagnostic IDs-related interfaces. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H 00016 #define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H 00017 00018 #include "clang/Basic/LLVM.h" 00019 #include "llvm/ADT/IntrusiveRefCntPtr.h" 00020 #include "llvm/ADT/StringRef.h" 00021 00022 namespace clang { 00023 class DiagnosticsEngine; 00024 class SourceLocation; 00025 00026 // Import the diagnostic enums themselves. 00027 namespace diag { 00028 // Start position for diagnostics. 00029 enum { 00030 DIAG_START_COMMON = 0, 00031 DIAG_START_DRIVER = DIAG_START_COMMON + 300, 00032 DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, 00033 DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + 100, 00034 DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, 00035 DIAG_START_PARSE = DIAG_START_LEX + 300, 00036 DIAG_START_AST = DIAG_START_PARSE + 500, 00037 DIAG_START_COMMENT = DIAG_START_AST + 100, 00038 DIAG_START_SEMA = DIAG_START_COMMENT + 100, 00039 DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, 00040 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 00041 }; 00042 00043 class CustomDiagInfo; 00044 00045 /// \brief All of the diagnostics that can be emitted by the frontend. 00046 typedef unsigned kind; 00047 00048 // Get typedefs for common diagnostics. 00049 enum { 00050 #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ 00051 SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM, 00052 #define COMMONSTART 00053 #include "clang/Basic/DiagnosticCommonKinds.inc" 00054 NUM_BUILTIN_COMMON_DIAGNOSTICS 00055 #undef DIAG 00056 }; 00057 00058 /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs 00059 /// to either Ignore (nothing), Remark (emit a remark), Warning 00060 /// (emit a warning) or Error (emit as an error). It allows clients to 00061 /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one). 00062 enum class Severity { 00063 // NOTE: 0 means "uncomputed". 00064 Ignored = 1, ///< Do not present this diagnostic, ignore it. 00065 Remark = 2, ///< Present this diagnostic as a remark. 00066 Warning = 3, ///< Present this diagnostic as a warning. 00067 Error = 4, ///< Present this diagnostic as an error. 00068 Fatal = 5 ///< Present this diagnostic as a fatal error. 00069 }; 00070 00071 /// Flavors of diagnostics we can emit. Used to filter for a particular 00072 /// kind of diagnostic (for instance, for -W/-R flags). 00073 enum class Flavor { 00074 WarningOrError, ///< A diagnostic that indicates a problem or potential 00075 ///< problem. Can be made fatal by -Werror. 00076 Remark ///< A diagnostic that indicates normal progress through 00077 ///< compilation. 00078 }; 00079 } 00080 00081 class DiagnosticMapping { 00082 unsigned Severity : 3; 00083 unsigned IsUser : 1; 00084 unsigned IsPragma : 1; 00085 unsigned HasNoWarningAsError : 1; 00086 unsigned HasNoErrorAsFatal : 1; 00087 00088 public: 00089 static DiagnosticMapping Make(diag::Severity Severity, bool IsUser, 00090 bool IsPragma) { 00091 DiagnosticMapping Result; 00092 Result.Severity = (unsigned)Severity; 00093 Result.IsUser = IsUser; 00094 Result.IsPragma = IsPragma; 00095 Result.HasNoWarningAsError = 0; 00096 Result.HasNoErrorAsFatal = 0; 00097 return Result; 00098 } 00099 00100 diag::Severity getSeverity() const { return (diag::Severity)Severity; } 00101 void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; } 00102 00103 bool isUser() const { return IsUser; } 00104 bool isPragma() const { return IsPragma; } 00105 00106 bool hasNoWarningAsError() const { return HasNoWarningAsError; } 00107 void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } 00108 00109 bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } 00110 void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } 00111 }; 00112 00113 /// \brief Used for handling and querying diagnostic IDs. 00114 /// 00115 /// Can be used and shared by multiple Diagnostics for multiple translation units. 00116 class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { 00117 public: 00118 /// \brief The level of the diagnostic, after it has been through mapping. 00119 enum Level { 00120 Ignored, Note, Remark, Warning, Error, Fatal 00121 }; 00122 00123 private: 00124 /// \brief Information for uniquing and looking up custom diags. 00125 diag::CustomDiagInfo *CustomDiagInfo; 00126 00127 public: 00128 DiagnosticIDs(); 00129 ~DiagnosticIDs(); 00130 00131 /// \brief Return an ID for a diagnostic with the specified format string and 00132 /// level. 00133 /// 00134 /// If this is the first request for this diagnostic, it is registered and 00135 /// created, otherwise the existing ID is returned. 00136 00137 // FIXME: Replace this function with a create-only facilty like 00138 // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of 00139 // writing, nearly all callers of this function were invalid. 00140 unsigned getCustomDiagID(Level L, StringRef FormatString); 00141 00142 //===--------------------------------------------------------------------===// 00143 // Diagnostic classification and reporting interfaces. 00144 // 00145 00146 /// \brief Given a diagnostic ID, return a description of the issue. 00147 StringRef getDescription(unsigned DiagID) const; 00148 00149 /// \brief Return true if the unmapped diagnostic levelof the specified 00150 /// diagnostic ID is a Warning or Extension. 00151 /// 00152 /// This only works on builtin diagnostics, not custom ones, and is not 00153 /// legal to call on NOTEs. 00154 static bool isBuiltinWarningOrExtension(unsigned DiagID); 00155 00156 /// \brief Return true if the specified diagnostic is mapped to errors by 00157 /// default. 00158 static bool isDefaultMappingAsError(unsigned DiagID); 00159 00160 /// \brief Determine whether the given built-in diagnostic ID is a Note. 00161 static bool isBuiltinNote(unsigned DiagID); 00162 00163 /// \brief Determine whether the given built-in diagnostic ID is for an 00164 /// extension of some sort. 00165 static bool isBuiltinExtensionDiag(unsigned DiagID) { 00166 bool ignored; 00167 return isBuiltinExtensionDiag(DiagID, ignored); 00168 } 00169 00170 /// \brief Determine whether the given built-in diagnostic ID is for an 00171 /// extension of some sort, and whether it is enabled by default. 00172 /// 00173 /// This also returns EnabledByDefault, which is set to indicate whether the 00174 /// diagnostic is ignored by default (in which case -pedantic enables it) or 00175 /// treated as a warning/error by default. 00176 /// 00177 static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); 00178 00179 00180 /// \brief Return the lowest-level warning option that enables the specified 00181 /// diagnostic. 00182 /// 00183 /// If there is no -Wfoo flag that controls the diagnostic, this returns null. 00184 static StringRef getWarningOptionForDiag(unsigned DiagID); 00185 00186 /// \brief Return the category number that a specified \p DiagID belongs to, 00187 /// or 0 if no category. 00188 static unsigned getCategoryNumberForDiag(unsigned DiagID); 00189 00190 /// \brief Return the number of diagnostic categories. 00191 static unsigned getNumberOfCategories(); 00192 00193 /// \brief Given a category ID, return the name of the category. 00194 static StringRef getCategoryNameFromID(unsigned CategoryID); 00195 00196 /// \brief Return true if a given diagnostic falls into an ARC diagnostic 00197 /// category. 00198 static bool isARCDiagnostic(unsigned DiagID); 00199 00200 /// \brief Enumeration describing how the emission of a diagnostic should 00201 /// be treated when it occurs during C++ template argument deduction. 00202 enum SFINAEResponse { 00203 /// \brief The diagnostic should not be reported, but it should cause 00204 /// template argument deduction to fail. 00205 /// 00206 /// The vast majority of errors that occur during template argument 00207 /// deduction fall into this category. 00208 SFINAE_SubstitutionFailure, 00209 00210 /// \brief The diagnostic should be suppressed entirely. 00211 /// 00212 /// Warnings generally fall into this category. 00213 SFINAE_Suppress, 00214 00215 /// \brief The diagnostic should be reported. 00216 /// 00217 /// The diagnostic should be reported. Various fatal errors (e.g., 00218 /// template instantiation depth exceeded) fall into this category. 00219 SFINAE_Report, 00220 00221 /// \brief The diagnostic is an access-control diagnostic, which will be 00222 /// substitution failures in some contexts and reported in others. 00223 SFINAE_AccessControl 00224 }; 00225 00226 /// \brief Determines whether the given built-in diagnostic ID is 00227 /// for an error that is suppressed if it occurs during C++ template 00228 /// argument deduction. 00229 /// 00230 /// When an error is suppressed due to SFINAE, the template argument 00231 /// deduction fails but no diagnostic is emitted. Certain classes of 00232 /// errors, such as those errors that involve C++ access control, 00233 /// are not SFINAE errors. 00234 static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); 00235 00236 /// \brief Get the set of all diagnostic IDs in the group with the given name. 00237 /// 00238 /// \param[out] Diags - On return, the diagnostics in the group. 00239 /// \returns \c true if the given group is unknown, \c false otherwise. 00240 bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, 00241 SmallVectorImpl<diag::kind> &Diags) const; 00242 00243 /// \brief Get the set of all diagnostic IDs. 00244 void getAllDiagnostics(diag::Flavor Flavor, 00245 SmallVectorImpl<diag::kind> &Diags) const; 00246 00247 /// \brief Get the diagnostic option with the closest edit distance to the 00248 /// given group name. 00249 static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group); 00250 00251 private: 00252 /// \brief Classify the specified diagnostic ID into a Level, consumable by 00253 /// the DiagnosticClient. 00254 /// 00255 /// The classification is based on the way the client configured the 00256 /// DiagnosticsEngine object. 00257 /// 00258 /// \param Loc The source location for which we are interested in finding out 00259 /// the diagnostic state. Can be null in order to query the latest state. 00260 DiagnosticIDs::Level 00261 getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, 00262 const DiagnosticsEngine &Diag) const LLVM_READONLY; 00263 00264 diag::Severity 00265 getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, 00266 const DiagnosticsEngine &Diag) const LLVM_READONLY; 00267 00268 /// \brief Used to report a diagnostic that is finally fully formed. 00269 /// 00270 /// \returns \c true if the diagnostic was emitted, \c false if it was 00271 /// suppressed. 00272 bool ProcessDiag(DiagnosticsEngine &Diag) const; 00273 00274 /// \brief Used to emit a diagnostic that is finally fully formed, 00275 /// ignoring suppression. 00276 void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const; 00277 00278 /// \brief Whether the diagnostic may leave the AST in a state where some 00279 /// invariants can break. 00280 bool isUnrecoverable(unsigned DiagID) const; 00281 00282 friend class DiagnosticsEngine; 00283 }; 00284 00285 } // end namespace clang 00286 00287 #endif