clang API Documentation

DiagnosticIDs.h
Go to the documentation of this file.
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