Home | History | Annotate | Download | only in Basic
      1 //===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the Diagnostic-related interfaces.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_DIAGNOSTIC_H
     15 #define LLVM_CLANG_DIAGNOSTIC_H
     16 
     17 #include "clang/Basic/DiagnosticIDs.h"
     18 #include "clang/Basic/SourceLocation.h"
     19 #include "llvm/ADT/ArrayRef.h"
     20 #include "llvm/ADT/DenseMap.h"
     21 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     22 #include "llvm/ADT/OwningPtr.h"
     23 #include "llvm/Support/type_traits.h"
     24 
     25 #include <vector>
     26 #include <list>
     27 
     28 namespace clang {
     29   class DiagnosticConsumer;
     30   class DiagnosticBuilder;
     31   class IdentifierInfo;
     32   class DeclContext;
     33   class LangOptions;
     34   class Preprocessor;
     35   class DiagnosticErrorTrap;
     36   class StoredDiagnostic;
     37 
     38 /// \brief Annotates a diagnostic with some code that should be
     39 /// inserted, removed, or replaced to fix the problem.
     40 ///
     41 /// This kind of hint should be used when we are certain that the
     42 /// introduction, removal, or modification of a particular (small!)
     43 /// amount of code will correct a compilation error. The compiler
     44 /// should also provide full recovery from such errors, such that
     45 /// suppressing the diagnostic output can still result in successful
     46 /// compilation.
     47 class FixItHint {
     48 public:
     49   /// \brief Code that should be replaced to correct the error. Empty for an
     50   /// insertion hint.
     51   CharSourceRange RemoveRange;
     52 
     53   /// \brief Code in the specific range that should be inserted in the insertion
     54   /// location.
     55   CharSourceRange InsertFromRange;
     56 
     57   /// \brief The actual code to insert at the insertion location, as a
     58   /// string.
     59   std::string CodeToInsert;
     60 
     61   bool BeforePreviousInsertions;
     62 
     63   /// \brief Empty code modification hint, indicating that no code
     64   /// modification is known.
     65   FixItHint() : BeforePreviousInsertions(false) { }
     66 
     67   bool isNull() const {
     68     return !RemoveRange.isValid();
     69   }
     70 
     71   /// \brief Create a code modification hint that inserts the given
     72   /// code string at a specific location.
     73   static FixItHint CreateInsertion(SourceLocation InsertionLoc,
     74                                    StringRef Code,
     75                                    bool BeforePreviousInsertions = false) {
     76     FixItHint Hint;
     77     Hint.RemoveRange =
     78       CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
     79     Hint.CodeToInsert = Code;
     80     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
     81     return Hint;
     82   }
     83 
     84   /// \brief Create a code modification hint that inserts the given
     85   /// code from \arg FromRange at a specific location.
     86   static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
     87                                             CharSourceRange FromRange,
     88                                         bool BeforePreviousInsertions = false) {
     89     FixItHint Hint;
     90     Hint.RemoveRange =
     91       CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
     92     Hint.InsertFromRange = FromRange;
     93     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
     94     return Hint;
     95   }
     96 
     97   /// \brief Create a code modification hint that removes the given
     98   /// source range.
     99   static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
    100     FixItHint Hint;
    101     Hint.RemoveRange = RemoveRange;
    102     return Hint;
    103   }
    104   static FixItHint CreateRemoval(SourceRange RemoveRange) {
    105     return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
    106   }
    107 
    108   /// \brief Create a code modification hint that replaces the given
    109   /// source range with the given code string.
    110   static FixItHint CreateReplacement(CharSourceRange RemoveRange,
    111                                      StringRef Code) {
    112     FixItHint Hint;
    113     Hint.RemoveRange = RemoveRange;
    114     Hint.CodeToInsert = Code;
    115     return Hint;
    116   }
    117 
    118   static FixItHint CreateReplacement(SourceRange RemoveRange,
    119                                      StringRef Code) {
    120     return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
    121   }
    122 };
    123 
    124 /// DiagnosticsEngine - This concrete class is used by the front-end to report
    125 /// problems and issues.  It massages the diagnostics (e.g. handling things like
    126 /// "report warnings as errors" and passes them off to the DiagnosticConsumer
    127 /// for reporting to the user. DiagnosticsEngine is tied to one translation unit
    128 /// and one SourceManager.
    129 class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
    130 public:
    131   /// Level - The level of the diagnostic, after it has been through mapping.
    132   enum Level {
    133     Ignored = DiagnosticIDs::Ignored,
    134     Note = DiagnosticIDs::Note,
    135     Warning = DiagnosticIDs::Warning,
    136     Error = DiagnosticIDs::Error,
    137     Fatal = DiagnosticIDs::Fatal
    138   };
    139 
    140   /// ExtensionHandling - How do we handle otherwise-unmapped extension?  This
    141   /// is controlled by -pedantic and -pedantic-errors.
    142   enum ExtensionHandling {
    143     Ext_Ignore, Ext_Warn, Ext_Error
    144   };
    145 
    146   enum ArgumentKind {
    147     ak_std_string,      // std::string
    148     ak_c_string,        // const char *
    149     ak_sint,            // int
    150     ak_uint,            // unsigned
    151     ak_identifierinfo,  // IdentifierInfo
    152     ak_qualtype,        // QualType
    153     ak_declarationname, // DeclarationName
    154     ak_nameddecl,       // NamedDecl *
    155     ak_nestednamespec,  // NestedNameSpecifier *
    156     ak_declcontext      // DeclContext *
    157   };
    158 
    159   /// Specifies which overload candidates to display when overload resolution
    160   /// fails.
    161   enum OverloadsShown {
    162     Ovl_All,  ///< Show all overloads.
    163     Ovl_Best  ///< Show just the "best" overload candidates.
    164   };
    165 
    166   /// ArgumentValue - This typedef represents on argument value, which is a
    167   /// union discriminated by ArgumentKind, with a value.
    168   typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
    169 
    170 private:
    171   unsigned char AllExtensionsSilenced; // Used by __extension__
    172   bool IgnoreAllWarnings;        // Ignore all warnings: -w
    173   bool WarningsAsErrors;         // Treat warnings like errors.
    174   bool EnableAllWarnings;        // Enable all warnings.
    175   bool ErrorsAsFatal;            // Treat errors like fatal errors.
    176   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
    177   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
    178   OverloadsShown ShowOverloads;  // Which overload candidates to show.
    179   unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
    180   unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
    181                                    // 0 -> no limit.
    182   unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
    183                                     // backtrace stack, 0 -> no limit.
    184   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
    185   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
    186   DiagnosticConsumer *Client;
    187   bool OwnsDiagClient;
    188   SourceManager *SourceMgr;
    189 
    190   /// \brief Mapping information for diagnostics.  Mapping info is
    191   /// packed into four bits per diagnostic.  The low three bits are the mapping
    192   /// (an instance of diag::Mapping), or zero if unset.  The high bit is set
    193   /// when the mapping was established as a user mapping.  If the high bit is
    194   /// clear, then the low bits are set to the default value, and should be
    195   /// mapped with -pedantic, -Werror, etc.
    196   ///
    197   /// A new DiagState is created and kept around when diagnostic pragmas modify
    198   /// the state so that we know what is the diagnostic state at any given
    199   /// source location.
    200   class DiagState {
    201     llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap;
    202 
    203   public:
    204     typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator
    205       iterator;
    206     typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator
    207       const_iterator;
    208 
    209     void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) {
    210       DiagMap[Diag] = Info;
    211     }
    212 
    213     DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag);
    214 
    215     const_iterator begin() const { return DiagMap.begin(); }
    216     const_iterator end() const { return DiagMap.end(); }
    217   };
    218 
    219   /// \brief Keeps and automatically disposes all DiagStates that we create.
    220   std::list<DiagState> DiagStates;
    221 
    222   /// \brief Represents a point in source where the diagnostic state was
    223   /// modified because of a pragma. 'Loc' can be null if the point represents
    224   /// the diagnostic state modifications done through the command-line.
    225   struct DiagStatePoint {
    226     DiagState *State;
    227     FullSourceLoc Loc;
    228     DiagStatePoint(DiagState *State, FullSourceLoc Loc)
    229       : State(State), Loc(Loc) { }
    230 
    231     bool operator<(const DiagStatePoint &RHS) const {
    232       // If Loc is invalid it means it came from <command-line>, in which case
    233       // we regard it as coming before any valid source location.
    234       if (RHS.Loc.isInvalid())
    235         return false;
    236       if (Loc.isInvalid())
    237         return true;
    238       return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
    239     }
    240   };
    241 
    242   /// \brief A vector of all DiagStatePoints representing changes in diagnostic
    243   /// state due to diagnostic pragmas. The vector is always sorted according to
    244   /// the SourceLocation of the DiagStatePoint.
    245   typedef std::vector<DiagStatePoint> DiagStatePointsTy;
    246   mutable DiagStatePointsTy DiagStatePoints;
    247 
    248   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
    249   /// so we can get back at it when we 'pop'.
    250   std::vector<DiagState *> DiagStateOnPushStack;
    251 
    252   DiagState *GetCurDiagState() const {
    253     assert(!DiagStatePoints.empty());
    254     return DiagStatePoints.back().State;
    255   }
    256 
    257   void PushDiagStatePoint(DiagState *State, SourceLocation L) {
    258     FullSourceLoc Loc(L, *SourceMgr);
    259     // Make sure that DiagStatePoints is always sorted according to Loc.
    260     assert((Loc.isValid() || DiagStatePoints.empty()) &&
    261            "Adding invalid loc point after another point");
    262     assert((Loc.isInvalid() || DiagStatePoints.empty() ||
    263             DiagStatePoints.back().Loc.isInvalid() ||
    264             DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
    265            "Previous point loc comes after or is the same as new one");
    266     DiagStatePoints.push_back(DiagStatePoint(State,
    267                                              FullSourceLoc(Loc, *SourceMgr)));
    268   }
    269 
    270   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
    271   /// the given source location.
    272   DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
    273 
    274   /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
    275   /// fatal error is emitted, and is sticky.
    276   bool ErrorOccurred;
    277   bool FatalErrorOccurred;
    278 
    279   /// \brief Indicates that an unrecoverable error has occurred.
    280   bool UnrecoverableErrorOccurred;
    281 
    282   /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
    283   /// during a parsing section, e.g. during parsing a function.
    284   unsigned TrapNumErrorsOccurred;
    285   unsigned TrapNumUnrecoverableErrorsOccurred;
    286 
    287   /// LastDiagLevel - This is the level of the last diagnostic emitted.  This is
    288   /// used to emit continuation diagnostics with the same level as the
    289   /// diagnostic that they follow.
    290   DiagnosticIDs::Level LastDiagLevel;
    291 
    292   unsigned NumWarnings;       // Number of warnings reported
    293   unsigned NumErrors;         // Number of errors reported
    294   unsigned NumErrorsSuppressed; // Number of errors suppressed
    295 
    296   /// ArgToStringFn - A function pointer that converts an opaque diagnostic
    297   /// argument to a strings.  This takes the modifiers and argument that was
    298   /// present in the diagnostic.
    299   ///
    300   /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
    301   /// arguments formatted for this diagnostic.  Implementations of this function
    302   /// can use this information to avoid redundancy across arguments.
    303   ///
    304   /// This is a hack to avoid a layering violation between libbasic and libsema.
    305   typedef void (*ArgToStringFnTy)(
    306       ArgumentKind Kind, intptr_t Val,
    307       const char *Modifier, unsigned ModifierLen,
    308       const char *Argument, unsigned ArgumentLen,
    309       const ArgumentValue *PrevArgs,
    310       unsigned NumPrevArgs,
    311       SmallVectorImpl<char> &Output,
    312       void *Cookie,
    313       ArrayRef<intptr_t> QualTypeVals);
    314   void *ArgToStringCookie;
    315   ArgToStringFnTy ArgToStringFn;
    316 
    317   /// \brief ID of the "delayed" diagnostic, which is a (typically
    318   /// fatal) diagnostic that had to be delayed because it was found
    319   /// while emitting another diagnostic.
    320   unsigned DelayedDiagID;
    321 
    322   /// \brief First string argument for the delayed diagnostic.
    323   std::string DelayedDiagArg1;
    324 
    325   /// \brief Second string argument for the delayed diagnostic.
    326   std::string DelayedDiagArg2;
    327 
    328 public:
    329   explicit DiagnosticsEngine(
    330                       const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
    331                       DiagnosticConsumer *client = 0,
    332                       bool ShouldOwnClient = true);
    333   ~DiagnosticsEngine();
    334 
    335   const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
    336     return Diags;
    337   }
    338 
    339   DiagnosticConsumer *getClient() { return Client; }
    340   const DiagnosticConsumer *getClient() const { return Client; }
    341 
    342   /// \brief Determine whether this \c DiagnosticsEngine object own its client.
    343   bool ownsClient() const { return OwnsDiagClient; }
    344 
    345   /// \brief Return the current diagnostic client along with ownership of that
    346   /// client.
    347   DiagnosticConsumer *takeClient() {
    348     OwnsDiagClient = false;
    349     return Client;
    350   }
    351 
    352   bool hasSourceManager() const { return SourceMgr != 0; }
    353   SourceManager &getSourceManager() const {
    354     assert(SourceMgr && "SourceManager not set!");
    355     return *SourceMgr;
    356   }
    357   void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
    358 
    359   //===--------------------------------------------------------------------===//
    360   //  DiagnosticsEngine characterization methods, used by a client to customize
    361   //  how diagnostics are emitted.
    362   //
    363 
    364   /// pushMappings - Copies the current DiagMappings and pushes the new copy
    365   /// onto the top of the stack.
    366   void pushMappings(SourceLocation Loc);
    367 
    368   /// popMappings - Pops the current DiagMappings off the top of the stack
    369   /// causing the new top of the stack to be the active mappings. Returns
    370   /// true if the pop happens, false if there is only one DiagMapping on the
    371   /// stack.
    372   bool popMappings(SourceLocation Loc);
    373 
    374   /// \brief Set the diagnostic client associated with this diagnostic object.
    375   ///
    376   /// \param ShouldOwnClient true if the diagnostic object should take
    377   /// ownership of \c client.
    378   void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
    379 
    380   /// setErrorLimit - Specify a limit for the number of errors we should
    381   /// emit before giving up.  Zero disables the limit.
    382   void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
    383 
    384   /// \brief Specify the maximum number of template instantiation
    385   /// notes to emit along with a given diagnostic.
    386   void setTemplateBacktraceLimit(unsigned Limit) {
    387     TemplateBacktraceLimit = Limit;
    388   }
    389 
    390   /// \brief Retrieve the maximum number of template instantiation
    391   /// notes to emit along with a given diagnostic.
    392   unsigned getTemplateBacktraceLimit() const {
    393     return TemplateBacktraceLimit;
    394   }
    395 
    396   /// \brief Specify the maximum number of constexpr evaluation
    397   /// notes to emit along with a given diagnostic.
    398   void setConstexprBacktraceLimit(unsigned Limit) {
    399     ConstexprBacktraceLimit = Limit;
    400   }
    401 
    402   /// \brief Retrieve the maximum number of constexpr evaluation
    403   /// notes to emit along with a given diagnostic.
    404   unsigned getConstexprBacktraceLimit() const {
    405     return ConstexprBacktraceLimit;
    406   }
    407 
    408   /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
    409   /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
    410   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
    411   bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
    412 
    413   /// setEnableAllWarnings - When set to true, any unmapped ignored warnings
    414   /// are no longer ignored.  If this and IgnoreAllWarnings are both set,
    415   /// then that one wins.
    416   void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
    417   bool getEnableAllWarnngs() const { return EnableAllWarnings; }
    418 
    419   /// setWarningsAsErrors - When set to true, any warnings reported are issued
    420   /// as errors.
    421   void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
    422   bool getWarningsAsErrors() const { return WarningsAsErrors; }
    423 
    424   /// setErrorsAsFatal - When set to true, any error reported is made a
    425   /// fatal error.
    426   void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
    427   bool getErrorsAsFatal() const { return ErrorsAsFatal; }
    428 
    429   /// setSuppressSystemWarnings - When set to true mask warnings that
    430   /// come from system headers.
    431   void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
    432   bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
    433 
    434   /// \brief Suppress all diagnostics, to silence the front end when we
    435   /// know that we don't want any more diagnostics to be passed along to the
    436   /// client
    437   void setSuppressAllDiagnostics(bool Val = true) {
    438     SuppressAllDiagnostics = Val;
    439   }
    440   bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
    441 
    442   /// \brief Specify which overload candidates to show when overload resolution
    443   /// fails.  By default, we show all candidates.
    444   void setShowOverloads(OverloadsShown Val) {
    445     ShowOverloads = Val;
    446   }
    447   OverloadsShown getShowOverloads() const { return ShowOverloads; }
    448 
    449   /// \brief Pretend that the last diagnostic issued was ignored. This can
    450   /// be used by clients who suppress diagnostics themselves.
    451   void setLastDiagnosticIgnored() {
    452     LastDiagLevel = DiagnosticIDs::Ignored;
    453   }
    454 
    455   /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
    456   /// extension diagnostics are mapped onto ignore/warning/error.  This
    457   /// corresponds to the GCC -pedantic and -pedantic-errors option.
    458   void setExtensionHandlingBehavior(ExtensionHandling H) {
    459     ExtBehavior = H;
    460   }
    461   ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
    462 
    463   /// AllExtensionsSilenced - This is a counter bumped when an __extension__
    464   /// block is encountered.  When non-zero, all extension diagnostics are
    465   /// entirely silenced, no matter how they are mapped.
    466   void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
    467   void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
    468   bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
    469 
    470   /// \brief This allows the client to specify that certain
    471   /// warnings are ignored.  Notes can never be mapped, errors can only be
    472   /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily.
    473   ///
    474   /// \param Loc The source location that this change of diagnostic state should
    475   /// take affect. It can be null if we are setting the latest state.
    476   void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
    477                             SourceLocation Loc);
    478 
    479   /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
    480   /// "unknown-pragmas" to have the specified mapping.  This returns true and
    481   /// ignores the request if "Group" was unknown, false otherwise.
    482   ///
    483   /// 'Loc' is the source location that this change of diagnostic state should
    484   /// take affect. It can be null if we are setting the state from command-line.
    485   bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
    486                                  SourceLocation Loc = SourceLocation());
    487 
    488   /// \brief Set the warning-as-error flag for the given diagnostic. This
    489   /// function always only operates on the current diagnostic state.
    490   void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled);
    491 
    492   /// \brief Set the warning-as-error flag for the given diagnostic group. This
    493   /// function always only operates on the current diagnostic state.
    494   ///
    495   /// \returns True if the given group is unknown, false otherwise.
    496   bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
    497 
    498   /// \brief Set the error-as-fatal flag for the given diagnostic. This function
    499   /// always only operates on the current diagnostic state.
    500   void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled);
    501 
    502   /// \brief Set the error-as-fatal flag for the given diagnostic group. This
    503   /// function always only operates on the current diagnostic state.
    504   ///
    505   /// \returns True if the given group is unknown, false otherwise.
    506   bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
    507 
    508   /// \brief Add the specified mapping to all diagnostics. Mainly to be used
    509   /// by -Wno-everything to disable all warnings but allow subsequent -W options
    510   /// to enable specific warnings.
    511   void setMappingToAllDiagnostics(diag::Mapping Map,
    512                                   SourceLocation Loc = SourceLocation());
    513 
    514   bool hasErrorOccurred() const { return ErrorOccurred; }
    515   bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
    516 
    517   /// \brief Determine whether any kind of unrecoverable error has occurred.
    518   bool hasUnrecoverableErrorOccurred() const {
    519     return FatalErrorOccurred || UnrecoverableErrorOccurred;
    520   }
    521 
    522   unsigned getNumWarnings() const { return NumWarnings; }
    523 
    524   void setNumWarnings(unsigned NumWarnings) {
    525     this->NumWarnings = NumWarnings;
    526   }
    527 
    528   /// getCustomDiagID - Return an ID for a diagnostic with the specified message
    529   /// and level.  If this is the first request for this diagnosic, it is
    530   /// registered and created, otherwise the existing ID is returned.
    531   unsigned getCustomDiagID(Level L, StringRef Message) {
    532     return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
    533   }
    534 
    535   /// ConvertArgToString - This method converts a diagnostic argument (as an
    536   /// intptr_t) into the string that represents it.
    537   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
    538                           const char *Modifier, unsigned ModLen,
    539                           const char *Argument, unsigned ArgLen,
    540                           const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
    541                           SmallVectorImpl<char> &Output,
    542                           SmallVectorImpl<intptr_t> &QualTypeVals) const {
    543     ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
    544                   PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
    545                   QualTypeVals);
    546   }
    547 
    548   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
    549     ArgToStringFn = Fn;
    550     ArgToStringCookie = Cookie;
    551   }
    552 
    553   /// \brief Reset the state of the diagnostic object to its initial
    554   /// configuration.
    555   void Reset();
    556 
    557   //===--------------------------------------------------------------------===//
    558   // DiagnosticsEngine classification and reporting interfaces.
    559   //
    560 
    561   /// \brief Based on the way the client configured the DiagnosticsEngine
    562   /// object, classify the specified diagnostic ID into a Level, consumable by
    563   /// the DiagnosticConsumer.
    564   ///
    565   /// \param Loc The source location we are interested in finding out the
    566   /// diagnostic state. Can be null in order to query the latest state.
    567   Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
    568     return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
    569   }
    570 
    571   /// Report - Issue the message to the client.  @c DiagID is a member of the
    572   /// @c diag::kind enum.  This actually returns aninstance of DiagnosticBuilder
    573   /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
    574   /// @c Pos represents the source location associated with the diagnostic,
    575   /// which can be an invalid location if no position information is available.
    576   inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID);
    577   inline DiagnosticBuilder Report(unsigned DiagID);
    578 
    579   void Report(const StoredDiagnostic &storedDiag);
    580 
    581   /// \brief Determine whethere there is already a diagnostic in flight.
    582   bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
    583 
    584   /// \brief Set the "delayed" diagnostic that will be emitted once
    585   /// the current diagnostic completes.
    586   ///
    587   ///  If a diagnostic is already in-flight but the front end must
    588   ///  report a problem (e.g., with an inconsistent file system
    589   ///  state), this routine sets a "delayed" diagnostic that will be
    590   ///  emitted after the current diagnostic completes. This should
    591   ///  only be used for fatal errors detected at inconvenient
    592   ///  times. If emitting a delayed diagnostic causes a second delayed
    593   ///  diagnostic to be introduced, that second delayed diagnostic
    594   ///  will be ignored.
    595   ///
    596   /// \param DiagID The ID of the diagnostic being delayed.
    597   ///
    598   /// \param Arg1 A string argument that will be provided to the
    599   /// diagnostic. A copy of this string will be stored in the
    600   /// DiagnosticsEngine object itself.
    601   ///
    602   /// \param Arg2 A string argument that will be provided to the
    603   /// diagnostic. A copy of this string will be stored in the
    604   /// DiagnosticsEngine object itself.
    605   void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
    606                             StringRef Arg2 = "");
    607 
    608   /// \brief Clear out the current diagnostic.
    609   void Clear() { CurDiagID = ~0U; }
    610 
    611 private:
    612   /// \brief Report the delayed diagnostic.
    613   void ReportDelayed();
    614 
    615   // This is private state used by DiagnosticBuilder.  We put it here instead of
    616   // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
    617   // object.  This implementation choice means that we can only have one
    618   // diagnostic "in flight" at a time, but this seems to be a reasonable
    619   // tradeoff to keep these objects small.  Assertions verify that only one
    620   // diagnostic is in flight at a time.
    621   friend class DiagnosticIDs;
    622   friend class DiagnosticBuilder;
    623   friend class Diagnostic;
    624   friend class PartialDiagnostic;
    625   friend class DiagnosticErrorTrap;
    626 
    627   /// CurDiagLoc - This is the location of the current diagnostic that is in
    628   /// flight.
    629   SourceLocation CurDiagLoc;
    630 
    631   /// CurDiagID - This is the ID of the current diagnostic that is in flight.
    632   /// This is set to ~0U when there is no diagnostic in flight.
    633   unsigned CurDiagID;
    634 
    635   enum {
    636     /// MaxArguments - The maximum number of arguments we can hold. We currently
    637     /// only support up to 10 arguments (%0-%9).  A single diagnostic with more
    638     /// than that almost certainly has to be simplified anyway.
    639     MaxArguments = 10,
    640 
    641     /// MaxRanges - The maximum number of ranges we can hold.
    642     MaxRanges = 10,
    643 
    644     /// MaxFixItHints - The maximum number of ranges we can hold.
    645     MaxFixItHints = 10
    646   };
    647 
    648   /// NumDiagArgs - This contains the number of entries in Arguments.
    649   signed char NumDiagArgs;
    650   /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
    651   unsigned char NumDiagRanges;
    652   /// NumDiagFixItHints - This is the number of hints in the DiagFixItHints
    653   /// array.
    654   unsigned char NumDiagFixItHints;
    655 
    656   /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
    657   /// values, with one for each argument.  This specifies whether the argument
    658   /// is in DiagArgumentsStr or in DiagArguments.
    659   unsigned char DiagArgumentsKind[MaxArguments];
    660 
    661   /// DiagArgumentsStr - This holds the values of each string argument for the
    662   /// current diagnostic.  This value is only used when the corresponding
    663   /// ArgumentKind is ak_std_string.
    664   std::string DiagArgumentsStr[MaxArguments];
    665 
    666   /// DiagArgumentsVal - The values for the various substitution positions. This
    667   /// is used when the argument is not an std::string.  The specific value is
    668   /// mangled into an intptr_t and the interpretation depends on exactly what
    669   /// sort of argument kind it is.
    670   intptr_t DiagArgumentsVal[MaxArguments];
    671 
    672   /// DiagRanges - The list of ranges added to this diagnostic.
    673   CharSourceRange DiagRanges[MaxRanges];
    674 
    675   /// FixItHints - If valid, provides a hint with some code to insert, remove,
    676   /// or modify at a particular position.
    677   FixItHint DiagFixItHints[MaxFixItHints];
    678 
    679   DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
    680     bool isPragma = L.isValid();
    681     DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
    682       Map, /*IsUser=*/true, isPragma);
    683 
    684     // If this is a pragma mapping, then set the diagnostic mapping flags so
    685     // that we override command line options.
    686     if (isPragma) {
    687       MappingInfo.setNoWarningAsError(true);
    688       MappingInfo.setNoErrorAsFatal(true);
    689     }
    690 
    691     return MappingInfo;
    692   }
    693 
    694   /// ProcessDiag - This is the method used to report a diagnostic that is
    695   /// finally fully formed.
    696   ///
    697   /// \returns true if the diagnostic was emitted, false if it was
    698   /// suppressed.
    699   bool ProcessDiag() {
    700     return Diags->ProcessDiag(*this);
    701   }
    702 
    703   /// @name Diagnostic Emission
    704   /// @{
    705 protected:
    706   // Sema requires access to the following functions because the current design
    707   // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
    708   // access us directly to ensure we minimize the emitted code for the common
    709   // Sema::Diag() patterns.
    710   friend class Sema;
    711 
    712   /// \brief Emit the current diagnostic and clear the diagnostic state.
    713   bool EmitCurrentDiagnostic();
    714 
    715   unsigned getCurrentDiagID() const { return CurDiagID; }
    716 
    717   SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
    718 
    719   /// @}
    720 
    721   friend class ASTReader;
    722   friend class ASTWriter;
    723 };
    724 
    725 /// \brief RAII class that determines when any errors have occurred
    726 /// between the time the instance was created and the time it was
    727 /// queried.
    728 class DiagnosticErrorTrap {
    729   DiagnosticsEngine &Diag;
    730   unsigned NumErrors;
    731   unsigned NumUnrecoverableErrors;
    732 
    733 public:
    734   explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
    735     : Diag(Diag) { reset(); }
    736 
    737   /// \brief Determine whether any errors have occurred since this
    738   /// object instance was created.
    739   bool hasErrorOccurred() const {
    740     return Diag.TrapNumErrorsOccurred > NumErrors;
    741   }
    742 
    743   /// \brief Determine whether any unrecoverable errors have occurred since this
    744   /// object instance was created.
    745   bool hasUnrecoverableErrorOccurred() const {
    746     return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
    747   }
    748 
    749   // Set to initial state of "no errors occurred".
    750   void reset() {
    751     NumErrors = Diag.TrapNumErrorsOccurred;
    752     NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
    753   }
    754 };
    755 
    756 //===----------------------------------------------------------------------===//
    757 // DiagnosticBuilder
    758 //===----------------------------------------------------------------------===//
    759 
    760 /// DiagnosticBuilder - This is a little helper class used to produce
    761 /// diagnostics.  This is constructed by the DiagnosticsEngine::Report method,
    762 /// and allows insertion of extra information (arguments and source ranges) into
    763 /// the currently "in flight" diagnostic.  When the temporary for the builder is
    764 /// destroyed, the diagnostic is issued.
    765 ///
    766 /// Note that many of these will be created as temporary objects (many call
    767 /// sites), so we want them to be small and we never want their address taken.
    768 /// This ensures that compilers with somewhat reasonable optimizers will promote
    769 /// the common fields to registers, eliminating increments of the NumArgs field,
    770 /// for example.
    771 class DiagnosticBuilder {
    772   mutable DiagnosticsEngine *DiagObj;
    773   mutable unsigned NumArgs, NumRanges, NumFixits;
    774 
    775   /// \brief Status variable indicating if this diagnostic is still active.
    776   ///
    777   // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
    778   // but LLVM is not currently smart enough to eliminate the null check that
    779   // Emit() would end up with if we used that as our status variable.
    780   mutable bool IsActive;
    781 
    782   void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
    783   friend class DiagnosticsEngine;
    784   explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
    785     : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true) {
    786     assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
    787   }
    788 
    789   friend class PartialDiagnostic;
    790 
    791 protected:
    792   void FlushCounts() {
    793     DiagObj->NumDiagArgs = NumArgs;
    794     DiagObj->NumDiagRanges = NumRanges;
    795     DiagObj->NumDiagFixItHints = NumFixits;
    796   }
    797 
    798   /// \brief Clear out the current diagnostic.
    799   void Clear() const {
    800     DiagObj = 0;
    801     IsActive = false;
    802   }
    803 
    804   /// isActive - Determine whether this diagnostic is still active.
    805   bool isActive() const { return IsActive; }
    806 
    807   /// \brief Force the diagnostic builder to emit the diagnostic now.
    808   ///
    809   /// Once this function has been called, the DiagnosticBuilder object
    810   /// should not be used again before it is destroyed.
    811   ///
    812   /// \returns true if a diagnostic was emitted, false if the
    813   /// diagnostic was suppressed.
    814   bool Emit() {
    815     // If this diagnostic is inactive, then its soul was stolen by the copy ctor
    816     // (or by a subclass, as in SemaDiagnosticBuilder).
    817     if (!isActive()) return false;
    818 
    819     // When emitting diagnostics, we set the final argument count into
    820     // the DiagnosticsEngine object.
    821     FlushCounts();
    822 
    823     // Process the diagnostic.
    824     bool Result = DiagObj->EmitCurrentDiagnostic();
    825 
    826     // This diagnostic is dead.
    827     Clear();
    828 
    829     return Result;
    830   }
    831 
    832 public:
    833   /// Copy constructor.  When copied, this "takes" the diagnostic info from the
    834   /// input and neuters it.
    835   DiagnosticBuilder(const DiagnosticBuilder &D) {
    836     DiagObj = D.DiagObj;
    837     IsActive = D.IsActive;
    838     D.Clear();
    839     NumArgs = D.NumArgs;
    840     NumRanges = D.NumRanges;
    841     NumFixits = D.NumFixits;
    842   }
    843 
    844   /// Destructor - The dtor emits the diagnostic.
    845   ~DiagnosticBuilder() {
    846     Emit();
    847   }
    848 
    849   /// Operator bool: conversion of DiagnosticBuilder to bool always returns
    850   /// true.  This allows is to be used in boolean error contexts like:
    851   /// return Diag(...);
    852   operator bool() const { return true; }
    853 
    854   void AddString(StringRef S) const {
    855     assert(isActive() && "Clients must not add to cleared diagnostic!");
    856     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
    857            "Too many arguments to diagnostic!");
    858     DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
    859     DiagObj->DiagArgumentsStr[NumArgs++] = S;
    860   }
    861 
    862   void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
    863     assert(isActive() && "Clients must not add to cleared diagnostic!");
    864     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
    865            "Too many arguments to diagnostic!");
    866     DiagObj->DiagArgumentsKind[NumArgs] = Kind;
    867     DiagObj->DiagArgumentsVal[NumArgs++] = V;
    868   }
    869 
    870   void AddSourceRange(const CharSourceRange &R) const {
    871     assert(isActive() && "Clients must not add to cleared diagnostic!");
    872     assert(NumRanges < DiagnosticsEngine::MaxRanges &&
    873            "Too many arguments to diagnostic!");
    874     DiagObj->DiagRanges[NumRanges++] = R;
    875   }
    876 
    877   void AddFixItHint(const FixItHint &Hint) const {
    878     assert(isActive() && "Clients must not add to cleared diagnostic!");
    879     assert(NumFixits < DiagnosticsEngine::MaxFixItHints &&
    880            "Too many arguments to diagnostic!");
    881     DiagObj->DiagFixItHints[NumFixits++] = Hint;
    882   }
    883 };
    884 
    885 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    886                                            StringRef S) {
    887   DB.AddString(S);
    888   return DB;
    889 }
    890 
    891 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    892                                            const char *Str) {
    893   DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
    894                   DiagnosticsEngine::ak_c_string);
    895   return DB;
    896 }
    897 
    898 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
    899   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
    900   return DB;
    901 }
    902 
    903 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
    904   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
    905   return DB;
    906 }
    907 
    908 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    909                                            unsigned I) {
    910   DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
    911   return DB;
    912 }
    913 
    914 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    915                                            const IdentifierInfo *II) {
    916   DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
    917                   DiagnosticsEngine::ak_identifierinfo);
    918   return DB;
    919 }
    920 
    921 // Adds a DeclContext to the diagnostic. The enable_if template magic is here
    922 // so that we only match those arguments that are (statically) DeclContexts;
    923 // other arguments that derive from DeclContext (e.g., RecordDecls) will not
    924 // match.
    925 template<typename T>
    926 inline
    927 typename llvm::enable_if<llvm::is_same<T, DeclContext>,
    928                          const DiagnosticBuilder &>::type
    929 operator<<(const DiagnosticBuilder &DB, T *DC) {
    930   DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
    931                   DiagnosticsEngine::ak_declcontext);
    932   return DB;
    933 }
    934 
    935 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    936                                            const SourceRange &R) {
    937   DB.AddSourceRange(CharSourceRange::getTokenRange(R));
    938   return DB;
    939 }
    940 
    941 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    942                                            const CharSourceRange &R) {
    943   DB.AddSourceRange(R);
    944   return DB;
    945 }
    946 
    947 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    948                                            const FixItHint &Hint) {
    949   if (!Hint.isNull())
    950     DB.AddFixItHint(Hint);
    951   return DB;
    952 }
    953 
    954 /// Report - Issue the message to the client.  DiagID is a member of the
    955 /// diag::kind enum.  This actually returns a new instance of DiagnosticBuilder
    956 /// which emits the diagnostics (through ProcessDiag) when it is destroyed.
    957 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
    958                                             unsigned DiagID){
    959   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
    960   CurDiagLoc = Loc;
    961   CurDiagID = DiagID;
    962   return DiagnosticBuilder(this);
    963 }
    964 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
    965   return Report(SourceLocation(), DiagID);
    966 }
    967 
    968 //===----------------------------------------------------------------------===//
    969 // Diagnostic
    970 //===----------------------------------------------------------------------===//
    971 
    972 /// Diagnostic - This is a little helper class (which is basically a smart
    973 /// pointer that forward info from DiagnosticsEngine) that allows clients to
    974 /// enquire about the currently in-flight diagnostic.
    975 class Diagnostic {
    976   const DiagnosticsEngine *DiagObj;
    977   StringRef StoredDiagMessage;
    978 public:
    979   explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
    980   Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
    981     : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
    982 
    983   const DiagnosticsEngine *getDiags() const { return DiagObj; }
    984   unsigned getID() const { return DiagObj->CurDiagID; }
    985   const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
    986   bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
    987   SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
    988 
    989   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
    990 
    991   /// getArgKind - Return the kind of the specified index.  Based on the kind
    992   /// of argument, the accessors below can be used to get the value.
    993   DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
    994     assert(Idx < getNumArgs() && "Argument index out of range!");
    995     return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
    996   }
    997 
    998   /// getArgStdStr - Return the provided argument string specified by Idx.
    999   const std::string &getArgStdStr(unsigned Idx) const {
   1000     assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
   1001            "invalid argument accessor!");
   1002     return DiagObj->DiagArgumentsStr[Idx];
   1003   }
   1004 
   1005   /// getArgCStr - Return the specified C string argument.
   1006   const char *getArgCStr(unsigned Idx) const {
   1007     assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
   1008            "invalid argument accessor!");
   1009     return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
   1010   }
   1011 
   1012   /// getArgSInt - Return the specified signed integer argument.
   1013   int getArgSInt(unsigned Idx) const {
   1014     assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
   1015            "invalid argument accessor!");
   1016     return (int)DiagObj->DiagArgumentsVal[Idx];
   1017   }
   1018 
   1019   /// getArgUInt - Return the specified unsigned integer argument.
   1020   unsigned getArgUInt(unsigned Idx) const {
   1021     assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
   1022            "invalid argument accessor!");
   1023     return (unsigned)DiagObj->DiagArgumentsVal[Idx];
   1024   }
   1025 
   1026   /// getArgIdentifier - Return the specified IdentifierInfo argument.
   1027   const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
   1028     assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
   1029            "invalid argument accessor!");
   1030     return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
   1031   }
   1032 
   1033   /// getRawArg - Return the specified non-string argument in an opaque form.
   1034   intptr_t getRawArg(unsigned Idx) const {
   1035     assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
   1036            "invalid argument accessor!");
   1037     return DiagObj->DiagArgumentsVal[Idx];
   1038   }
   1039 
   1040 
   1041   /// getNumRanges - Return the number of source ranges associated with this
   1042   /// diagnostic.
   1043   unsigned getNumRanges() const {
   1044     return DiagObj->NumDiagRanges;
   1045   }
   1046 
   1047   const CharSourceRange &getRange(unsigned Idx) const {
   1048     assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
   1049     return DiagObj->DiagRanges[Idx];
   1050   }
   1051 
   1052   /// \brief Return an array reference for this diagnostic's ranges.
   1053   ArrayRef<CharSourceRange> getRanges() const {
   1054     return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges);
   1055   }
   1056 
   1057   unsigned getNumFixItHints() const {
   1058     return DiagObj->NumDiagFixItHints;
   1059   }
   1060 
   1061   const FixItHint &getFixItHint(unsigned Idx) const {
   1062     assert(Idx < getNumFixItHints() && "Invalid index!");
   1063     return DiagObj->DiagFixItHints[Idx];
   1064   }
   1065 
   1066   const FixItHint *getFixItHints() const {
   1067     return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
   1068   }
   1069 
   1070   /// FormatDiagnostic - Format this diagnostic into a string, substituting the
   1071   /// formal arguments into the %0 slots.  The result is appended onto the Str
   1072   /// array.
   1073   void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
   1074 
   1075   /// FormatDiagnostic - Format the given format-string into the
   1076   /// output buffer using the arguments stored in this diagnostic.
   1077   void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
   1078                         SmallVectorImpl<char> &OutStr) const;
   1079 };
   1080 
   1081 /**
   1082  * \brief Represents a diagnostic in a form that can be retained until its
   1083  * corresponding source manager is destroyed.
   1084  */
   1085 class StoredDiagnostic {
   1086   unsigned ID;
   1087   DiagnosticsEngine::Level Level;
   1088   FullSourceLoc Loc;
   1089   std::string Message;
   1090   std::vector<CharSourceRange> Ranges;
   1091   std::vector<FixItHint> FixIts;
   1092 
   1093 public:
   1094   StoredDiagnostic();
   1095   StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
   1096   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
   1097                    StringRef Message);
   1098   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
   1099                    StringRef Message, FullSourceLoc Loc,
   1100                    ArrayRef<CharSourceRange> Ranges,
   1101                    ArrayRef<FixItHint> Fixits);
   1102   ~StoredDiagnostic();
   1103 
   1104   /// \brief Evaluates true when this object stores a diagnostic.
   1105   operator bool() const { return Message.size() > 0; }
   1106 
   1107   unsigned getID() const { return ID; }
   1108   DiagnosticsEngine::Level getLevel() const { return Level; }
   1109   const FullSourceLoc &getLocation() const { return Loc; }
   1110   StringRef getMessage() const { return Message; }
   1111 
   1112   void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
   1113 
   1114   typedef std::vector<CharSourceRange>::const_iterator range_iterator;
   1115   range_iterator range_begin() const { return Ranges.begin(); }
   1116   range_iterator range_end() const { return Ranges.end(); }
   1117   unsigned range_size() const { return Ranges.size(); }
   1118 
   1119   ArrayRef<CharSourceRange> getRanges() const {
   1120     return llvm::makeArrayRef(Ranges);
   1121   }
   1122 
   1123 
   1124   typedef std::vector<FixItHint>::const_iterator fixit_iterator;
   1125   fixit_iterator fixit_begin() const { return FixIts.begin(); }
   1126   fixit_iterator fixit_end() const { return FixIts.end(); }
   1127   unsigned fixit_size() const { return FixIts.size(); }
   1128 
   1129   ArrayRef<FixItHint> getFixIts() const {
   1130     return llvm::makeArrayRef(FixIts);
   1131   }
   1132 };
   1133 
   1134 /// DiagnosticConsumer - This is an abstract interface implemented by clients of
   1135 /// the front-end, which formats and prints fully processed diagnostics.
   1136 class DiagnosticConsumer {
   1137 protected:
   1138   unsigned NumWarnings;       // Number of warnings reported
   1139   unsigned NumErrors;         // Number of errors reported
   1140 
   1141 public:
   1142   DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
   1143 
   1144   unsigned getNumErrors() const { return NumErrors; }
   1145   unsigned getNumWarnings() const { return NumWarnings; }
   1146   virtual void clear() { NumWarnings = NumErrors = 0; }
   1147 
   1148   virtual ~DiagnosticConsumer();
   1149 
   1150   /// BeginSourceFile - Callback to inform the diagnostic client that processing
   1151   /// of a source file is beginning.
   1152   ///
   1153   /// Note that diagnostics may be emitted outside the processing of a source
   1154   /// file, for example during the parsing of command line options. However,
   1155   /// diagnostics with source range information are required to only be emitted
   1156   /// in between BeginSourceFile() and EndSourceFile().
   1157   ///
   1158   /// \arg LO - The language options for the source file being processed.
   1159   /// \arg PP - The preprocessor object being used for the source; this optional
   1160   /// and may not be present, for example when processing AST source files.
   1161   virtual void BeginSourceFile(const LangOptions &LangOpts,
   1162                                const Preprocessor *PP = 0) {}
   1163 
   1164   /// EndSourceFile - Callback to inform the diagnostic client that processing
   1165   /// of a source file has ended. The diagnostic client should assume that any
   1166   /// objects made available via \see BeginSourceFile() are inaccessible.
   1167   virtual void EndSourceFile() {}
   1168 
   1169   /// \brief Callback to inform the diagnostic client that processing of all
   1170   /// source files has ended.
   1171   virtual void finish() {}
   1172 
   1173   /// IncludeInDiagnosticCounts - This method (whose default implementation
   1174   /// returns true) indicates whether the diagnostics handled by this
   1175   /// DiagnosticConsumer should be included in the number of diagnostics
   1176   /// reported by DiagnosticsEngine.
   1177   virtual bool IncludeInDiagnosticCounts() const;
   1178 
   1179   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
   1180   /// capturing it to a log as needed.
   1181   ///
   1182   /// Default implementation just keeps track of the total number of warnings
   1183   /// and errors.
   1184   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
   1185                                 const Diagnostic &Info);
   1186 
   1187   /// \brief Clone the diagnostic consumer, producing an equivalent consumer
   1188   /// that can be used in a different context.
   1189   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0;
   1190 };
   1191 
   1192 /// IgnoringDiagConsumer - This is a diagnostic client that just ignores all
   1193 /// diags.
   1194 class IgnoringDiagConsumer : public DiagnosticConsumer {
   1195   virtual void anchor();
   1196   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
   1197                         const Diagnostic &Info) {
   1198     // Just ignore it.
   1199   }
   1200   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
   1201     return new IgnoringDiagConsumer();
   1202   }
   1203 };
   1204 
   1205 }  // end namespace clang
   1206 
   1207 #endif
   1208