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