clang API Documentation

Diagnostic.h
Go to the documentation of this file.
00001 //===--- Diagnostic.h - C Language Family Diagnostic 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-related interfaces.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_DIAGNOSTIC_H
00015 #define LLVM_CLANG_DIAGNOSTIC_H
00016 
00017 #include "clang/Basic/DiagnosticIDs.h"
00018 #include "clang/Basic/SourceLocation.h"
00019 #include "llvm/ADT/ArrayRef.h"
00020 #include "llvm/ADT/DenseMap.h"
00021 #include "llvm/ADT/IntrusiveRefCntPtr.h"
00022 #include "llvm/ADT/OwningPtr.h"
00023 #include "llvm/Support/type_traits.h"
00024 
00025 #include <vector>
00026 #include <list>
00027 
00028 namespace clang {
00029   class DiagnosticConsumer;
00030   class DiagnosticBuilder;
00031   class IdentifierInfo;
00032   class DeclContext;
00033   class LangOptions;
00034   class Preprocessor;
00035   class DiagnosticErrorTrap;
00036   class StoredDiagnostic;
00037 
00038 /// \brief Annotates a diagnostic with some code that should be
00039 /// inserted, removed, or replaced to fix the problem.
00040 ///
00041 /// This kind of hint should be used when we are certain that the
00042 /// introduction, removal, or modification of a particular (small!)
00043 /// amount of code will correct a compilation error. The compiler
00044 /// should also provide full recovery from such errors, such that
00045 /// suppressing the diagnostic output can still result in successful
00046 /// compilation.
00047 class FixItHint {
00048 public:
00049   /// \brief Code that should be replaced to correct the error. Empty for an
00050   /// insertion hint.
00051   CharSourceRange RemoveRange;
00052 
00053   /// \brief Code in the specific range that should be inserted in the insertion
00054   /// location.
00055   CharSourceRange InsertFromRange;
00056 
00057   /// \brief The actual code to insert at the insertion location, as a
00058   /// string.
00059   std::string CodeToInsert;
00060 
00061   bool BeforePreviousInsertions;
00062 
00063   /// \brief Empty code modification hint, indicating that no code
00064   /// modification is known.
00065   FixItHint() : BeforePreviousInsertions(false) { }
00066 
00067   bool isNull() const {
00068     return !RemoveRange.isValid();
00069   }
00070   
00071   /// \brief Create a code modification hint that inserts the given
00072   /// code string at a specific location.
00073   static FixItHint CreateInsertion(SourceLocation InsertionLoc,
00074                                    StringRef Code,
00075                                    bool BeforePreviousInsertions = false) {
00076     FixItHint Hint;
00077     Hint.RemoveRange =
00078       CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
00079     Hint.CodeToInsert = Code;
00080     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
00081     return Hint;
00082   }
00083   
00084   /// \brief Create a code modification hint that inserts the given
00085   /// code from \arg FromRange at a specific location.
00086   static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
00087                                             CharSourceRange FromRange,
00088                                         bool BeforePreviousInsertions = false) {
00089     FixItHint Hint;
00090     Hint.RemoveRange =
00091       CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
00092     Hint.InsertFromRange = FromRange;
00093     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
00094     return Hint;
00095   }
00096 
00097   /// \brief Create a code modification hint that removes the given
00098   /// source range.
00099   static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
00100     FixItHint Hint;
00101     Hint.RemoveRange = RemoveRange;
00102     return Hint;
00103   }
00104   static FixItHint CreateRemoval(SourceRange RemoveRange) {
00105     return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
00106   }
00107   
00108   /// \brief Create a code modification hint that replaces the given
00109   /// source range with the given code string.
00110   static FixItHint CreateReplacement(CharSourceRange RemoveRange,
00111                                      StringRef Code) {
00112     FixItHint Hint;
00113     Hint.RemoveRange = RemoveRange;
00114     Hint.CodeToInsert = Code;
00115     return Hint;
00116   }
00117   
00118   static FixItHint CreateReplacement(SourceRange RemoveRange,
00119                                      StringRef Code) {
00120     return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
00121   }
00122 };
00123 
00124 /// DiagnosticsEngine - This concrete class is used by the front-end to report
00125 /// problems and issues.  It massages the diagnostics (e.g. handling things like
00126 /// "report warnings as errors" and passes them off to the DiagnosticConsumer
00127 /// for reporting to the user. DiagnosticsEngine is tied to one translation unit
00128 /// and one SourceManager.
00129 class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
00130 public:
00131   /// Level - The level of the diagnostic, after it has been through mapping.
00132   enum Level {
00133     Ignored = DiagnosticIDs::Ignored,
00134     Note = DiagnosticIDs::Note,
00135     Warning = DiagnosticIDs::Warning,
00136     Error = DiagnosticIDs::Error,
00137     Fatal = DiagnosticIDs::Fatal
00138   };
00139 
00140   /// ExtensionHandling - How do we handle otherwise-unmapped extension?  This
00141   /// is controlled by -pedantic and -pedantic-errors.
00142   enum ExtensionHandling {
00143     Ext_Ignore, Ext_Warn, Ext_Error
00144   };
00145 
00146   enum ArgumentKind {
00147     ak_std_string,      // std::string
00148     ak_c_string,        // const char *
00149     ak_sint,            // int
00150     ak_uint,            // unsigned
00151     ak_identifierinfo,  // IdentifierInfo
00152     ak_qualtype,        // QualType
00153     ak_declarationname, // DeclarationName
00154     ak_nameddecl,       // NamedDecl *
00155     ak_nestednamespec,  // NestedNameSpecifier *
00156     ak_declcontext      // DeclContext *
00157   };
00158 
00159   /// Specifies which overload candidates to display when overload resolution
00160   /// fails.
00161   enum OverloadsShown {
00162     Ovl_All,  ///< Show all overloads.
00163     Ovl_Best  ///< Show just the "best" overload candidates.
00164   };
00165 
00166   /// ArgumentValue - This typedef represents on argument value, which is a
00167   /// union discriminated by ArgumentKind, with a value.
00168   typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
00169 
00170 private:
00171   unsigned char AllExtensionsSilenced; // Used by __extension__
00172   bool IgnoreAllWarnings;        // Ignore all warnings: -w
00173   bool WarningsAsErrors;         // Treat warnings like errors.
00174   bool EnableAllWarnings;        // Enable all warnings.
00175   bool ErrorsAsFatal;            // Treat errors like fatal errors.
00176   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
00177   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
00178   OverloadsShown ShowOverloads;  // Which overload candidates to show.
00179   unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
00180   unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
00181                                    // 0 -> no limit.
00182   unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
00183                                     // backtrace stack, 0 -> no limit.
00184   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
00185   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
00186   DiagnosticConsumer *Client;
00187   bool OwnsDiagClient;
00188   SourceManager *SourceMgr;
00189 
00190   /// \brief Mapping information for diagnostics.  Mapping info is
00191   /// packed into four bits per diagnostic.  The low three bits are the mapping
00192   /// (an instance of diag::Mapping), or zero if unset.  The high bit is set
00193   /// when the mapping was established as a user mapping.  If the high bit is
00194   /// clear, then the low bits are set to the default value, and should be
00195   /// mapped with -pedantic, -Werror, etc.
00196   ///
00197   /// A new DiagState is created and kept around when diagnostic pragmas modify
00198   /// the state so that we know what is the diagnostic state at any given
00199   /// source location.
00200   class DiagState {
00201     llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap;
00202 
00203   public:
00204     typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator
00205       iterator;
00206     typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator
00207       const_iterator;
00208 
00209     void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) {
00210       DiagMap[Diag] = Info;
00211     }
00212 
00213     DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag);
00214 
00215     const_iterator begin() const { return DiagMap.begin(); }
00216     const_iterator end() const { return DiagMap.end(); }
00217   };
00218 
00219   /// \brief Keeps and automatically disposes all DiagStates that we create.
00220   std::list<DiagState> DiagStates;
00221 
00222   /// \brief Represents a point in source where the diagnostic state was
00223   /// modified because of a pragma. 'Loc' can be null if the point represents
00224   /// the diagnostic state modifications done through the command-line.
00225   struct DiagStatePoint {
00226     DiagState *State;
00227     FullSourceLoc Loc;
00228     DiagStatePoint(DiagState *State, FullSourceLoc Loc)
00229       : State(State), Loc(Loc) { } 
00230     
00231     bool operator<(const DiagStatePoint &RHS) const {
00232       // If Loc is invalid it means it came from <command-line>, in which case
00233       // we regard it as coming before any valid source location.
00234       if (RHS.Loc.isInvalid())
00235         return false;
00236       if (Loc.isInvalid())
00237         return true;
00238       return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
00239     }
00240   };
00241 
00242   /// \brief A vector of all DiagStatePoints representing changes in diagnostic
00243   /// state due to diagnostic pragmas. The vector is always sorted according to
00244   /// the SourceLocation of the DiagStatePoint.
00245   typedef std::vector<DiagStatePoint> DiagStatePointsTy;
00246   mutable DiagStatePointsTy DiagStatePoints;
00247 
00248   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
00249   /// so we can get back at it when we 'pop'.
00250   std::vector<DiagState *> DiagStateOnPushStack;
00251 
00252   DiagState *GetCurDiagState() const {
00253     assert(!DiagStatePoints.empty());
00254     return DiagStatePoints.back().State;
00255   }
00256 
00257   void PushDiagStatePoint(DiagState *State, SourceLocation L) {
00258     FullSourceLoc Loc(L, *SourceMgr);
00259     // Make sure that DiagStatePoints is always sorted according to Loc.
00260     assert((Loc.isValid() || DiagStatePoints.empty()) &&
00261            "Adding invalid loc point after another point");
00262     assert((Loc.isInvalid() || DiagStatePoints.empty() ||
00263             DiagStatePoints.back().Loc.isInvalid() ||
00264             DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
00265            "Previous point loc comes after or is the same as new one");
00266     DiagStatePoints.push_back(DiagStatePoint(State,
00267                                              FullSourceLoc(Loc, *SourceMgr)));
00268   }
00269 
00270   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
00271   /// the given source location.
00272   DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
00273 
00274   /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
00275   /// fatal error is emitted, and is sticky.
00276   bool ErrorOccurred;
00277   bool FatalErrorOccurred;
00278 
00279   /// \brief Indicates that an unrecoverable error has occurred.
00280   bool UnrecoverableErrorOccurred;
00281   
00282   /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
00283   /// during a parsing section, e.g. during parsing a function.
00284   unsigned TrapNumErrorsOccurred;
00285   unsigned TrapNumUnrecoverableErrorsOccurred;
00286 
00287   /// LastDiagLevel - This is the level of the last diagnostic emitted.  This is
00288   /// used to emit continuation diagnostics with the same level as the
00289   /// diagnostic that they follow.
00290   DiagnosticIDs::Level LastDiagLevel;
00291 
00292   unsigned NumWarnings;       // Number of warnings reported
00293   unsigned NumErrors;         // Number of errors reported
00294   unsigned NumErrorsSuppressed; // Number of errors suppressed
00295 
00296   /// ArgToStringFn - A function pointer that converts an opaque diagnostic
00297   /// argument to a strings.  This takes the modifiers and argument that was
00298   /// present in the diagnostic.
00299   ///
00300   /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
00301   /// arguments formatted for this diagnostic.  Implementations of this function
00302   /// can use this information to avoid redundancy across arguments.
00303   ///
00304   /// This is a hack to avoid a layering violation between libbasic and libsema.
00305   typedef void (*ArgToStringFnTy)(
00306       ArgumentKind Kind, intptr_t Val,
00307       const char *Modifier, unsigned ModifierLen,
00308       const char *Argument, unsigned ArgumentLen,
00309       const ArgumentValue *PrevArgs,
00310       unsigned NumPrevArgs,
00311       SmallVectorImpl<char> &Output,
00312       void *Cookie,
00313       ArrayRef<intptr_t> QualTypeVals);
00314   void *ArgToStringCookie;
00315   ArgToStringFnTy ArgToStringFn;
00316 
00317   /// \brief ID of the "delayed" diagnostic, which is a (typically
00318   /// fatal) diagnostic that had to be delayed because it was found
00319   /// while emitting another diagnostic.
00320   unsigned DelayedDiagID;
00321 
00322   /// \brief First string argument for the delayed diagnostic.
00323   std::string DelayedDiagArg1;
00324 
00325   /// \brief Second string argument for the delayed diagnostic.
00326   std::string DelayedDiagArg2;
00327 
00328 public:
00329   explicit DiagnosticsEngine(
00330                       const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
00331                       DiagnosticConsumer *client = 0,
00332                       bool ShouldOwnClient = true);
00333   ~DiagnosticsEngine();
00334 
00335   const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
00336     return Diags;
00337   }
00338 
00339   DiagnosticConsumer *getClient() { return Client; }
00340   const DiagnosticConsumer *getClient() const { return Client; }
00341 
00342   /// \brief Determine whether this \c DiagnosticsEngine object own its client.
00343   bool ownsClient() const { return OwnsDiagClient; }
00344   
00345   /// \brief Return the current diagnostic client along with ownership of that
00346   /// client.
00347   DiagnosticConsumer *takeClient() {
00348     OwnsDiagClient = false;
00349     return Client;
00350   }
00351 
00352   bool hasSourceManager() const { return SourceMgr != 0; }
00353   SourceManager &getSourceManager() const {
00354     assert(SourceMgr && "SourceManager not set!");
00355     return *SourceMgr;
00356   }
00357   void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
00358 
00359   //===--------------------------------------------------------------------===//
00360   //  DiagnosticsEngine characterization methods, used by a client to customize
00361   //  how diagnostics are emitted.
00362   //
00363 
00364   /// pushMappings - Copies the current DiagMappings and pushes the new copy
00365   /// onto the top of the stack.
00366   void pushMappings(SourceLocation Loc);
00367 
00368   /// popMappings - Pops the current DiagMappings off the top of the stack
00369   /// causing the new top of the stack to be the active mappings. Returns
00370   /// true if the pop happens, false if there is only one DiagMapping on the
00371   /// stack.
00372   bool popMappings(SourceLocation Loc);
00373 
00374   /// \brief Set the diagnostic client associated with this diagnostic object.
00375   ///
00376   /// \param ShouldOwnClient true if the diagnostic object should take
00377   /// ownership of \c client.
00378   void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
00379 
00380   /// setErrorLimit - Specify a limit for the number of errors we should
00381   /// emit before giving up.  Zero disables the limit.
00382   void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
00383   
00384   /// \brief Specify the maximum number of template instantiation
00385   /// notes to emit along with a given diagnostic.
00386   void setTemplateBacktraceLimit(unsigned Limit) {
00387     TemplateBacktraceLimit = Limit;
00388   }
00389 
00390   /// \brief Retrieve the maximum number of template instantiation
00391   /// notes to emit along with a given diagnostic.
00392   unsigned getTemplateBacktraceLimit() const {
00393     return TemplateBacktraceLimit;
00394   }
00395 
00396   /// \brief Specify the maximum number of constexpr evaluation
00397   /// notes to emit along with a given diagnostic.
00398   void setConstexprBacktraceLimit(unsigned Limit) {
00399     ConstexprBacktraceLimit = Limit;
00400   }
00401 
00402   /// \brief Retrieve the maximum number of constexpr evaluation
00403   /// notes to emit along with a given diagnostic.
00404   unsigned getConstexprBacktraceLimit() const {
00405     return ConstexprBacktraceLimit;
00406   }
00407 
00408   /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
00409   /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
00410   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
00411   bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
00412 
00413   /// setEnableAllWarnings - When set to true, any unmapped ignored warnings
00414   /// are no longer ignored.  If this and IgnoreAllWarnings are both set,
00415   /// then that one wins.
00416   void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
00417   bool getEnableAllWarnngs() const { return EnableAllWarnings; }
00418   
00419   /// setWarningsAsErrors - When set to true, any warnings reported are issued
00420   /// as errors.
00421   void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
00422   bool getWarningsAsErrors() const { return WarningsAsErrors; }
00423 
00424   /// setErrorsAsFatal - When set to true, any error reported is made a
00425   /// fatal error.
00426   void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
00427   bool getErrorsAsFatal() const { return ErrorsAsFatal; }
00428 
00429   /// setSuppressSystemWarnings - When set to true mask warnings that
00430   /// come from system headers.
00431   void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
00432   bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
00433 
00434   /// \brief Suppress all diagnostics, to silence the front end when we 
00435   /// know that we don't want any more diagnostics to be passed along to the
00436   /// client
00437   void setSuppressAllDiagnostics(bool Val = true) { 
00438     SuppressAllDiagnostics = Val; 
00439   }
00440   bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
00441   
00442   /// \brief Specify which overload candidates to show when overload resolution
00443   /// fails.  By default, we show all candidates.
00444   void setShowOverloads(OverloadsShown Val) {
00445     ShowOverloads = Val;
00446   }
00447   OverloadsShown getShowOverloads() const { return ShowOverloads; }
00448   
00449   /// \brief Pretend that the last diagnostic issued was ignored. This can
00450   /// be used by clients who suppress diagnostics themselves.
00451   void setLastDiagnosticIgnored() {
00452     LastDiagLevel = DiagnosticIDs::Ignored;
00453   }
00454   
00455   /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
00456   /// extension diagnostics are mapped onto ignore/warning/error.  This
00457   /// corresponds to the GCC -pedantic and -pedantic-errors option.
00458   void setExtensionHandlingBehavior(ExtensionHandling H) {
00459     ExtBehavior = H;
00460   }
00461   ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
00462 
00463   /// AllExtensionsSilenced - This is a counter bumped when an __extension__
00464   /// block is encountered.  When non-zero, all extension diagnostics are
00465   /// entirely silenced, no matter how they are mapped.
00466   void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
00467   void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
00468   bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
00469 
00470   /// \brief This allows the client to specify that certain
00471   /// warnings are ignored.  Notes can never be mapped, errors can only be
00472   /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily.
00473   ///
00474   /// \param Loc The source location that this change of diagnostic state should
00475   /// take affect. It can be null if we are setting the latest state.
00476   void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
00477                             SourceLocation Loc);
00478 
00479   /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
00480   /// "unknown-pragmas" to have the specified mapping.  This returns true and
00481   /// ignores the request if "Group" was unknown, false otherwise.
00482   ///
00483   /// 'Loc' is the source location that this change of diagnostic state should
00484   /// take affect. It can be null if we are setting the state from command-line.
00485   bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
00486                                  SourceLocation Loc = SourceLocation());
00487 
00488   /// \brief Set the warning-as-error flag for the given diagnostic. This
00489   /// function always only operates on the current diagnostic state.
00490   void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled);
00491 
00492   /// \brief Set the warning-as-error flag for the given diagnostic group. This
00493   /// function always only operates on the current diagnostic state.
00494   ///
00495   /// \returns True if the given group is unknown, false otherwise.
00496   bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
00497 
00498   /// \brief Set the error-as-fatal flag for the given diagnostic. This function
00499   /// always only operates on the current diagnostic state.
00500   void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled);
00501 
00502   /// \brief Set the error-as-fatal flag for the given diagnostic group. This
00503   /// function always only operates on the current diagnostic state.
00504   ///
00505   /// \returns True if the given group is unknown, false otherwise.
00506   bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
00507 
00508   /// \brief Add the specified mapping to all diagnostics. Mainly to be used
00509   /// by -Wno-everything to disable all warnings but allow subsequent -W options
00510   /// to enable specific warnings.
00511   void setMappingToAllDiagnostics(diag::Mapping Map,
00512                                   SourceLocation Loc = SourceLocation());
00513 
00514   bool hasErrorOccurred() const { return ErrorOccurred; }
00515   bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
00516   
00517   /// \brief Determine whether any kind of unrecoverable error has occurred.
00518   bool hasUnrecoverableErrorOccurred() const {
00519     return FatalErrorOccurred || UnrecoverableErrorOccurred;
00520   }
00521   
00522   unsigned getNumWarnings() const { return NumWarnings; }
00523 
00524   void setNumWarnings(unsigned NumWarnings) {
00525     this->NumWarnings = NumWarnings;
00526   }
00527 
00528   /// getCustomDiagID - Return an ID for a diagnostic with the specified message
00529   /// and level.  If this is the first request for this diagnosic, it is
00530   /// registered and created, otherwise the existing ID is returned.
00531   unsigned getCustomDiagID(Level L, StringRef Message) {
00532     return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
00533   }
00534 
00535   /// ConvertArgToString - This method converts a diagnostic argument (as an
00536   /// intptr_t) into the string that represents it.
00537   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
00538                           const char *Modifier, unsigned ModLen,
00539                           const char *Argument, unsigned ArgLen,
00540                           const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
00541                           SmallVectorImpl<char> &Output,
00542                           SmallVectorImpl<intptr_t> &QualTypeVals) const {
00543     ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
00544                   PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
00545                   QualTypeVals);
00546   }
00547 
00548   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
00549     ArgToStringFn = Fn;
00550     ArgToStringCookie = Cookie;
00551   }
00552 
00553   /// \brief Reset the state of the diagnostic object to its initial 
00554   /// configuration.
00555   void Reset();
00556   
00557   //===--------------------------------------------------------------------===//
00558   // DiagnosticsEngine classification and reporting interfaces.
00559   //
00560 
00561   /// \brief Based on the way the client configured the DiagnosticsEngine
00562   /// object, classify the specified diagnostic ID into a Level, consumable by
00563   /// the DiagnosticConsumer.
00564   ///
00565   /// \param Loc The source location we are interested in finding out the
00566   /// diagnostic state. Can be null in order to query the latest state.
00567   Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
00568     return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
00569   }
00570 
00571   /// Report - Issue the message to the client.  @c DiagID is a member of the
00572   /// @c diag::kind enum.  This actually returns aninstance of DiagnosticBuilder
00573   /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
00574   /// @c Pos represents the source location associated with the diagnostic,
00575   /// which can be an invalid location if no position information is available.
00576   inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID);
00577   inline DiagnosticBuilder Report(unsigned DiagID);
00578 
00579   void Report(const StoredDiagnostic &storedDiag);
00580 
00581   /// \brief Determine whethere there is already a diagnostic in flight.
00582   bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
00583 
00584   /// \brief Set the "delayed" diagnostic that will be emitted once
00585   /// the current diagnostic completes.
00586   ///
00587   ///  If a diagnostic is already in-flight but the front end must
00588   ///  report a problem (e.g., with an inconsistent file system
00589   ///  state), this routine sets a "delayed" diagnostic that will be
00590   ///  emitted after the current diagnostic completes. This should
00591   ///  only be used for fatal errors detected at inconvenient
00592   ///  times. If emitting a delayed diagnostic causes a second delayed
00593   ///  diagnostic to be introduced, that second delayed diagnostic
00594   ///  will be ignored.
00595   ///
00596   /// \param DiagID The ID of the diagnostic being delayed.
00597   ///
00598   /// \param Arg1 A string argument that will be provided to the
00599   /// diagnostic. A copy of this string will be stored in the
00600   /// DiagnosticsEngine object itself.
00601   ///
00602   /// \param Arg2 A string argument that will be provided to the
00603   /// diagnostic. A copy of this string will be stored in the
00604   /// DiagnosticsEngine object itself.
00605   void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
00606                             StringRef Arg2 = "");
00607   
00608   /// \brief Clear out the current diagnostic.
00609   void Clear() { CurDiagID = ~0U; }
00610 
00611 private:
00612   /// \brief Report the delayed diagnostic.
00613   void ReportDelayed();
00614 
00615   // This is private state used by DiagnosticBuilder.  We put it here instead of
00616   // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
00617   // object.  This implementation choice means that we can only have one
00618   // diagnostic "in flight" at a time, but this seems to be a reasonable
00619   // tradeoff to keep these objects small.  Assertions verify that only one
00620   // diagnostic is in flight at a time.
00621   friend class DiagnosticIDs;
00622   friend class DiagnosticBuilder;
00623   friend class Diagnostic;
00624   friend class PartialDiagnostic;
00625   friend class DiagnosticErrorTrap;
00626   
00627   /// CurDiagLoc - This is the location of the current diagnostic that is in
00628   /// flight.
00629   SourceLocation CurDiagLoc;
00630 
00631   /// CurDiagID - This is the ID of the current diagnostic that is in flight.
00632   /// This is set to ~0U when there is no diagnostic in flight.
00633   unsigned CurDiagID;
00634 
00635   enum {
00636     /// MaxArguments - The maximum number of arguments we can hold. We currently
00637     /// only support up to 10 arguments (%0-%9).  A single diagnostic with more
00638     /// than that almost certainly has to be simplified anyway.
00639     MaxArguments = 10,
00640 
00641     /// MaxRanges - The maximum number of ranges we can hold.
00642     MaxRanges = 10,
00643 
00644     /// MaxFixItHints - The maximum number of ranges we can hold.
00645     MaxFixItHints = 10
00646   };
00647 
00648   /// NumDiagArgs - This contains the number of entries in Arguments.
00649   signed char NumDiagArgs;
00650   /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
00651   unsigned char NumDiagRanges;
00652   /// NumDiagFixItHints - This is the number of hints in the DiagFixItHints
00653   /// array.
00654   unsigned char NumDiagFixItHints;
00655 
00656   /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
00657   /// values, with one for each argument.  This specifies whether the argument
00658   /// is in DiagArgumentsStr or in DiagArguments.
00659   unsigned char DiagArgumentsKind[MaxArguments];
00660 
00661   /// DiagArgumentsStr - This holds the values of each string argument for the
00662   /// current diagnostic.  This value is only used when the corresponding
00663   /// ArgumentKind is ak_std_string.
00664   std::string DiagArgumentsStr[MaxArguments];
00665 
00666   /// DiagArgumentsVal - The values for the various substitution positions. This
00667   /// is used when the argument is not an std::string.  The specific value is
00668   /// mangled into an intptr_t and the interpretation depends on exactly what
00669   /// sort of argument kind it is.
00670   intptr_t DiagArgumentsVal[MaxArguments];
00671 
00672   /// DiagRanges - The list of ranges added to this diagnostic.
00673   CharSourceRange DiagRanges[MaxRanges];
00674 
00675   /// FixItHints - If valid, provides a hint with some code to insert, remove,
00676   /// or modify at a particular position.
00677   FixItHint DiagFixItHints[MaxFixItHints];
00678 
00679   DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
00680     bool isPragma = L.isValid();
00681     DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
00682       Map, /*IsUser=*/true, isPragma);
00683 
00684     // If this is a pragma mapping, then set the diagnostic mapping flags so
00685     // that we override command line options.
00686     if (isPragma) {
00687       MappingInfo.setNoWarningAsError(true);
00688       MappingInfo.setNoErrorAsFatal(true);
00689     }
00690 
00691     return MappingInfo;
00692   }
00693 
00694   /// ProcessDiag - This is the method used to report a diagnostic that is
00695   /// finally fully formed.
00696   ///
00697   /// \returns true if the diagnostic was emitted, false if it was
00698   /// suppressed.
00699   bool ProcessDiag() {
00700     return Diags->ProcessDiag(*this);
00701   }
00702 
00703   /// @name Diagnostic Emission
00704   /// @{
00705 protected:
00706   // Sema requires access to the following functions because the current design
00707   // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
00708   // access us directly to ensure we minimize the emitted code for the common
00709   // Sema::Diag() patterns.
00710   friend class Sema;
00711 
00712   /// \brief Emit the current diagnostic and clear the diagnostic state.
00713   bool EmitCurrentDiagnostic();
00714 
00715   unsigned getCurrentDiagID() const { return CurDiagID; }
00716 
00717   SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
00718 
00719   /// @}
00720 
00721   friend class ASTReader;
00722   friend class ASTWriter;
00723 };
00724 
00725 /// \brief RAII class that determines when any errors have occurred
00726 /// between the time the instance was created and the time it was
00727 /// queried.
00728 class DiagnosticErrorTrap {
00729   DiagnosticsEngine &Diag;
00730   unsigned NumErrors;
00731   unsigned NumUnrecoverableErrors;
00732 
00733 public:
00734   explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
00735     : Diag(Diag) { reset(); }
00736 
00737   /// \brief Determine whether any errors have occurred since this
00738   /// object instance was created.
00739   bool hasErrorOccurred() const {
00740     return Diag.TrapNumErrorsOccurred > NumErrors;
00741   }
00742 
00743   /// \brief Determine whether any unrecoverable errors have occurred since this
00744   /// object instance was created.
00745   bool hasUnrecoverableErrorOccurred() const {
00746     return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
00747   }
00748 
00749   // Set to initial state of "no errors occurred".
00750   void reset() {
00751     NumErrors = Diag.TrapNumErrorsOccurred;
00752     NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
00753   }
00754 };
00755 
00756 //===----------------------------------------------------------------------===//
00757 // DiagnosticBuilder
00758 //===----------------------------------------------------------------------===//
00759 
00760 /// DiagnosticBuilder - This is a little helper class used to produce
00761 /// diagnostics.  This is constructed by the DiagnosticsEngine::Report method,
00762 /// and allows insertion of extra information (arguments and source ranges) into
00763 /// the currently "in flight" diagnostic.  When the temporary for the builder is
00764 /// destroyed, the diagnostic is issued.
00765 ///
00766 /// Note that many of these will be created as temporary objects (many call
00767 /// sites), so we want them to be small and we never want their address taken.
00768 /// This ensures that compilers with somewhat reasonable optimizers will promote
00769 /// the common fields to registers, eliminating increments of the NumArgs field,
00770 /// for example.
00771 class DiagnosticBuilder {
00772   mutable DiagnosticsEngine *DiagObj;
00773   mutable unsigned NumArgs, NumRanges, NumFixits;
00774 
00775   /// \brief Status variable indicating if this diagnostic is still active.
00776   ///
00777   // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
00778   // but LLVM is not currently smart enough to eliminate the null check that
00779   // Emit() would end up with if we used that as our status variable.
00780   mutable bool IsActive;
00781 
00782   void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
00783   friend class DiagnosticsEngine;
00784   
00785   DiagnosticBuilder()
00786     : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false) { }
00787 
00788   explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
00789     : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true) {
00790     assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
00791   }
00792 
00793   friend class PartialDiagnostic;
00794   
00795 protected:
00796   void FlushCounts() {
00797     DiagObj->NumDiagArgs = NumArgs;
00798     DiagObj->NumDiagRanges = NumRanges;
00799     DiagObj->NumDiagFixItHints = NumFixits;
00800   }
00801 
00802   /// \brief Clear out the current diagnostic.
00803   void Clear() const {
00804     DiagObj = 0;
00805     IsActive = false;
00806   }
00807 
00808   /// isActive - Determine whether this diagnostic is still active.
00809   bool isActive() const { return IsActive; }
00810 
00811   /// \brief Force the diagnostic builder to emit the diagnostic now.
00812   ///
00813   /// Once this function has been called, the DiagnosticBuilder object
00814   /// should not be used again before it is destroyed.
00815   ///
00816   /// \returns true if a diagnostic was emitted, false if the
00817   /// diagnostic was suppressed.
00818   bool Emit() {
00819     // If this diagnostic is inactive, then its soul was stolen by the copy ctor
00820     // (or by a subclass, as in SemaDiagnosticBuilder).
00821     if (!isActive()) return false;
00822 
00823     // When emitting diagnostics, we set the final argument count into
00824     // the DiagnosticsEngine object.
00825     FlushCounts();
00826 
00827     // Process the diagnostic.
00828     bool Result = DiagObj->EmitCurrentDiagnostic();
00829 
00830     // This diagnostic is dead.
00831     Clear();
00832 
00833     return Result;
00834   }
00835   
00836 public:
00837   /// Copy constructor.  When copied, this "takes" the diagnostic info from the
00838   /// input and neuters it.
00839   DiagnosticBuilder(const DiagnosticBuilder &D) {
00840     DiagObj = D.DiagObj;
00841     IsActive = D.IsActive;
00842     D.Clear();
00843     NumArgs = D.NumArgs;
00844     NumRanges = D.NumRanges;
00845     NumFixits = D.NumFixits;
00846   }
00847 
00848   /// \brief Retrieve an empty diagnostic builder.
00849   static DiagnosticBuilder getEmpty() {
00850     return DiagnosticBuilder();
00851   }
00852 
00853   /// Destructor - The dtor emits the diagnostic.
00854   ~DiagnosticBuilder() {
00855     Emit();
00856   }
00857   
00858   /// Operator bool: conversion of DiagnosticBuilder to bool always returns
00859   /// true.  This allows is to be used in boolean error contexts like:
00860   /// return Diag(...);
00861   operator bool() const { return true; }
00862 
00863   void AddString(StringRef S) const {
00864     assert(isActive() && "Clients must not add to cleared diagnostic!");
00865     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
00866            "Too many arguments to diagnostic!");
00867     DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
00868     DiagObj->DiagArgumentsStr[NumArgs++] = S;
00869   }
00870 
00871   void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
00872     assert(isActive() && "Clients must not add to cleared diagnostic!");
00873     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
00874            "Too many arguments to diagnostic!");
00875     DiagObj->DiagArgumentsKind[NumArgs] = Kind;
00876     DiagObj->DiagArgumentsVal[NumArgs++] = V;
00877   }
00878 
00879   void AddSourceRange(const CharSourceRange &R) const {
00880     assert(isActive() && "Clients must not add to cleared diagnostic!");
00881     assert(NumRanges < DiagnosticsEngine::MaxRanges &&
00882            "Too many arguments to diagnostic!");
00883     DiagObj->DiagRanges[NumRanges++] = R;
00884   }
00885 
00886   void AddFixItHint(const FixItHint &Hint) const {
00887     assert(isActive() && "Clients must not add to cleared diagnostic!");
00888     assert(NumFixits < DiagnosticsEngine::MaxFixItHints &&
00889            "Too many arguments to diagnostic!");
00890     DiagObj->DiagFixItHints[NumFixits++] = Hint;
00891   }
00892 };
00893 
00894 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00895                                            StringRef S) {
00896   DB.AddString(S);
00897   return DB;
00898 }
00899 
00900 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00901                                            const char *Str) {
00902   DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
00903                   DiagnosticsEngine::ak_c_string);
00904   return DB;
00905 }
00906 
00907 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
00908   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
00909   return DB;
00910 }
00911 
00912 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
00913   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
00914   return DB;
00915 }
00916 
00917 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00918                                            unsigned I) {
00919   DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
00920   return DB;
00921 }
00922 
00923 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00924                                            const IdentifierInfo *II) {
00925   DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
00926                   DiagnosticsEngine::ak_identifierinfo);
00927   return DB;
00928 }
00929 
00930 // Adds a DeclContext to the diagnostic. The enable_if template magic is here
00931 // so that we only match those arguments that are (statically) DeclContexts;
00932 // other arguments that derive from DeclContext (e.g., RecordDecls) will not
00933 // match.
00934 template<typename T>
00935 inline
00936 typename llvm::enable_if<llvm::is_same<T, DeclContext>, 
00937                          const DiagnosticBuilder &>::type
00938 operator<<(const DiagnosticBuilder &DB, T *DC) {
00939   DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
00940                   DiagnosticsEngine::ak_declcontext);
00941   return DB;
00942 }
00943   
00944 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00945                                            const SourceRange &R) {
00946   DB.AddSourceRange(CharSourceRange::getTokenRange(R));
00947   return DB;
00948 }
00949 
00950 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00951                                            const CharSourceRange &R) {
00952   DB.AddSourceRange(R);
00953   return DB;
00954 }
00955   
00956 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00957                                            const FixItHint &Hint) {
00958   if (!Hint.isNull())
00959     DB.AddFixItHint(Hint);
00960   return DB;
00961 }
00962 
00963 /// Report - Issue the message to the client.  DiagID is a member of the
00964 /// diag::kind enum.  This actually returns a new instance of DiagnosticBuilder
00965 /// which emits the diagnostics (through ProcessDiag) when it is destroyed.
00966 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
00967                                             unsigned DiagID){
00968   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
00969   CurDiagLoc = Loc;
00970   CurDiagID = DiagID;
00971   return DiagnosticBuilder(this);
00972 }
00973 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
00974   return Report(SourceLocation(), DiagID);
00975 }
00976 
00977 //===----------------------------------------------------------------------===//
00978 // Diagnostic
00979 //===----------------------------------------------------------------------===//
00980 
00981 /// Diagnostic - This is a little helper class (which is basically a smart
00982 /// pointer that forward info from DiagnosticsEngine) that allows clients to
00983 /// enquire about the currently in-flight diagnostic.
00984 class Diagnostic {
00985   const DiagnosticsEngine *DiagObj;
00986   StringRef StoredDiagMessage;
00987 public:
00988   explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
00989   Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
00990     : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
00991 
00992   const DiagnosticsEngine *getDiags() const { return DiagObj; }
00993   unsigned getID() const { return DiagObj->CurDiagID; }
00994   const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
00995   bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
00996   SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
00997 
00998   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
00999 
01000   /// getArgKind - Return the kind of the specified index.  Based on the kind
01001   /// of argument, the accessors below can be used to get the value.
01002   DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
01003     assert(Idx < getNumArgs() && "Argument index out of range!");
01004     return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
01005   }
01006 
01007   /// getArgStdStr - Return the provided argument string specified by Idx.
01008   const std::string &getArgStdStr(unsigned Idx) const {
01009     assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
01010            "invalid argument accessor!");
01011     return DiagObj->DiagArgumentsStr[Idx];
01012   }
01013 
01014   /// getArgCStr - Return the specified C string argument.
01015   const char *getArgCStr(unsigned Idx) const {
01016     assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
01017            "invalid argument accessor!");
01018     return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
01019   }
01020 
01021   /// getArgSInt - Return the specified signed integer argument.
01022   int getArgSInt(unsigned Idx) const {
01023     assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
01024            "invalid argument accessor!");
01025     return (int)DiagObj->DiagArgumentsVal[Idx];
01026   }
01027 
01028   /// getArgUInt - Return the specified unsigned integer argument.
01029   unsigned getArgUInt(unsigned Idx) const {
01030     assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
01031            "invalid argument accessor!");
01032     return (unsigned)DiagObj->DiagArgumentsVal[Idx];
01033   }
01034 
01035   /// getArgIdentifier - Return the specified IdentifierInfo argument.
01036   const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
01037     assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
01038            "invalid argument accessor!");
01039     return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
01040   }
01041 
01042   /// getRawArg - Return the specified non-string argument in an opaque form.
01043   intptr_t getRawArg(unsigned Idx) const {
01044     assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
01045            "invalid argument accessor!");
01046     return DiagObj->DiagArgumentsVal[Idx];
01047   }
01048 
01049 
01050   /// getNumRanges - Return the number of source ranges associated with this
01051   /// diagnostic.
01052   unsigned getNumRanges() const {
01053     return DiagObj->NumDiagRanges;
01054   }
01055 
01056   const CharSourceRange &getRange(unsigned Idx) const {
01057     assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
01058     return DiagObj->DiagRanges[Idx];
01059   }
01060 
01061   /// \brief Return an array reference for this diagnostic's ranges.
01062   ArrayRef<CharSourceRange> getRanges() const {
01063     return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges);
01064   }
01065 
01066   unsigned getNumFixItHints() const {
01067     return DiagObj->NumDiagFixItHints;
01068   }
01069 
01070   const FixItHint &getFixItHint(unsigned Idx) const {
01071     assert(Idx < getNumFixItHints() && "Invalid index!");
01072     return DiagObj->DiagFixItHints[Idx];
01073   }
01074 
01075   const FixItHint *getFixItHints() const {
01076     return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
01077   }
01078 
01079   /// FormatDiagnostic - Format this diagnostic into a string, substituting the
01080   /// formal arguments into the %0 slots.  The result is appended onto the Str
01081   /// array.
01082   void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
01083 
01084   /// FormatDiagnostic - Format the given format-string into the
01085   /// output buffer using the arguments stored in this diagnostic.
01086   void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
01087                         SmallVectorImpl<char> &OutStr) const;
01088 };
01089 
01090 /**
01091  * \brief Represents a diagnostic in a form that can be retained until its 
01092  * corresponding source manager is destroyed. 
01093  */
01094 class StoredDiagnostic {
01095   unsigned ID;
01096   DiagnosticsEngine::Level Level;
01097   FullSourceLoc Loc;
01098   std::string Message;
01099   std::vector<CharSourceRange> Ranges;
01100   std::vector<FixItHint> FixIts;
01101 
01102 public:
01103   StoredDiagnostic();
01104   StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
01105   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
01106                    StringRef Message);
01107   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
01108                    StringRef Message, FullSourceLoc Loc,
01109                    ArrayRef<CharSourceRange> Ranges,
01110                    ArrayRef<FixItHint> Fixits);
01111   ~StoredDiagnostic();
01112 
01113   /// \brief Evaluates true when this object stores a diagnostic.
01114   operator bool() const { return Message.size() > 0; }
01115 
01116   unsigned getID() const { return ID; }
01117   DiagnosticsEngine::Level getLevel() const { return Level; }
01118   const FullSourceLoc &getLocation() const { return Loc; }
01119   StringRef getMessage() const { return Message; }
01120 
01121   void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
01122 
01123   typedef std::vector<CharSourceRange>::const_iterator range_iterator;
01124   range_iterator range_begin() const { return Ranges.begin(); }
01125   range_iterator range_end() const { return Ranges.end(); }
01126   unsigned range_size() const { return Ranges.size(); }
01127   
01128   ArrayRef<CharSourceRange> getRanges() const {
01129     return llvm::makeArrayRef(Ranges);
01130   }
01131 
01132 
01133   typedef std::vector<FixItHint>::const_iterator fixit_iterator;
01134   fixit_iterator fixit_begin() const { return FixIts.begin(); }
01135   fixit_iterator fixit_end() const { return FixIts.end(); }
01136   unsigned fixit_size() const { return FixIts.size(); }
01137   
01138   ArrayRef<FixItHint> getFixIts() const {
01139     return llvm::makeArrayRef(FixIts);
01140   }
01141 };
01142 
01143 /// DiagnosticConsumer - This is an abstract interface implemented by clients of
01144 /// the front-end, which formats and prints fully processed diagnostics.
01145 class DiagnosticConsumer {
01146 protected:
01147   unsigned NumWarnings;       // Number of warnings reported
01148   unsigned NumErrors;         // Number of errors reported
01149   
01150 public:
01151   DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
01152 
01153   unsigned getNumErrors() const { return NumErrors; }
01154   unsigned getNumWarnings() const { return NumWarnings; }
01155   virtual void clear() { NumWarnings = NumErrors = 0; }
01156 
01157   virtual ~DiagnosticConsumer();
01158 
01159   /// BeginSourceFile - Callback to inform the diagnostic client that processing
01160   /// of a source file is beginning.
01161   ///
01162   /// Note that diagnostics may be emitted outside the processing of a source
01163   /// file, for example during the parsing of command line options. However,
01164   /// diagnostics with source range information are required to only be emitted
01165   /// in between BeginSourceFile() and EndSourceFile().
01166   ///
01167   /// \arg LO - The language options for the source file being processed.
01168   /// \arg PP - The preprocessor object being used for the source; this optional
01169   /// and may not be present, for example when processing AST source files.
01170   virtual void BeginSourceFile(const LangOptions &LangOpts,
01171                                const Preprocessor *PP = 0) {}
01172 
01173   /// EndSourceFile - Callback to inform the diagnostic client that processing
01174   /// of a source file has ended. The diagnostic client should assume that any
01175   /// objects made available via \see BeginSourceFile() are inaccessible.
01176   virtual void EndSourceFile() {}
01177 
01178   /// \brief Callback to inform the diagnostic client that processing of all
01179   /// source files has ended.
01180   virtual void finish() {}
01181 
01182   /// IncludeInDiagnosticCounts - This method (whose default implementation
01183   /// returns true) indicates whether the diagnostics handled by this
01184   /// DiagnosticConsumer should be included in the number of diagnostics
01185   /// reported by DiagnosticsEngine.
01186   virtual bool IncludeInDiagnosticCounts() const;
01187 
01188   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
01189   /// capturing it to a log as needed.
01190   ///
01191   /// Default implementation just keeps track of the total number of warnings
01192   /// and errors.
01193   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
01194                                 const Diagnostic &Info);
01195   
01196   /// \brief Clone the diagnostic consumer, producing an equivalent consumer
01197   /// that can be used in a different context.
01198   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0;
01199 };
01200 
01201 /// IgnoringDiagConsumer - This is a diagnostic client that just ignores all
01202 /// diags.
01203 class IgnoringDiagConsumer : public DiagnosticConsumer {
01204   virtual void anchor();
01205   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
01206                         const Diagnostic &Info) {
01207     // Just ignore it.
01208   }
01209   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
01210     return new IgnoringDiagConsumer();
01211   }
01212 };
01213 
01214 }  // end namespace clang
01215 
01216 #endif