]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h
Merge clang trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Basic / Diagnostic.h
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 /// \file
11 /// \brief Defines the Diagnostic-related interfaces.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
16 #define LLVM_CLANG_BASIC_DIAGNOSTIC_H
17
18 #include "clang/Basic/DiagnosticIDs.h"
19 #include "clang/Basic/DiagnosticOptions.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "clang/Basic/Specifiers.h"
22 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/IntrusiveRefCntPtr.h"
25 #include "llvm/ADT/iterator_range.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/ADT/StringRef.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <cstdint>
31 #include <list>
32 #include <map>
33 #include <memory>
34 #include <string>
35 #include <type_traits>
36 #include <utility>
37 #include <vector>
38
39 namespace clang {
40
41 class DeclContext;
42 class DiagnosticBuilder;
43 class DiagnosticConsumer;
44 class IdentifierInfo;
45 class LangOptions;
46 class Preprocessor;
47 class StoredDiagnostic;
48
49 namespace tok {
50
51   enum TokenKind : unsigned short;
52
53 } // end namespace tok
54
55 /// \brief Annotates a diagnostic with some code that should be
56 /// inserted, removed, or replaced to fix the problem.
57 ///
58 /// This kind of hint should be used when we are certain that the
59 /// introduction, removal, or modification of a particular (small!)
60 /// amount of code will correct a compilation error. The compiler
61 /// should also provide full recovery from such errors, such that
62 /// suppressing the diagnostic output can still result in successful
63 /// compilation.
64 class FixItHint {
65 public:
66   /// \brief Code that should be replaced to correct the error. Empty for an
67   /// insertion hint.
68   CharSourceRange RemoveRange;
69
70   /// \brief Code in the specific range that should be inserted in the insertion
71   /// location.
72   CharSourceRange InsertFromRange;
73
74   /// \brief The actual code to insert at the insertion location, as a
75   /// string.
76   std::string CodeToInsert;
77
78   bool BeforePreviousInsertions;
79
80   /// \brief Empty code modification hint, indicating that no code
81   /// modification is known.
82   FixItHint() : BeforePreviousInsertions(false) { }
83
84   bool isNull() const {
85     return !RemoveRange.isValid();
86   }
87   
88   /// \brief Create a code modification hint that inserts the given
89   /// code string at a specific location.
90   static FixItHint CreateInsertion(SourceLocation InsertionLoc,
91                                    StringRef Code,
92                                    bool BeforePreviousInsertions = false) {
93     FixItHint Hint;
94     Hint.RemoveRange =
95       CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
96     Hint.CodeToInsert = Code;
97     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
98     return Hint;
99   }
100   
101   /// \brief Create a code modification hint that inserts the given
102   /// code from \p FromRange at a specific location.
103   static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
104                                             CharSourceRange FromRange,
105                                         bool BeforePreviousInsertions = false) {
106     FixItHint Hint;
107     Hint.RemoveRange =
108       CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
109     Hint.InsertFromRange = FromRange;
110     Hint.BeforePreviousInsertions = BeforePreviousInsertions;
111     return Hint;
112   }
113
114   /// \brief Create a code modification hint that removes the given
115   /// source range.
116   static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
117     FixItHint Hint;
118     Hint.RemoveRange = RemoveRange;
119     return Hint;
120   }
121   static FixItHint CreateRemoval(SourceRange RemoveRange) {
122     return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
123   }
124   
125   /// \brief Create a code modification hint that replaces the given
126   /// source range with the given code string.
127   static FixItHint CreateReplacement(CharSourceRange RemoveRange,
128                                      StringRef Code) {
129     FixItHint Hint;
130     Hint.RemoveRange = RemoveRange;
131     Hint.CodeToInsert = Code;
132     return Hint;
133   }
134   
135   static FixItHint CreateReplacement(SourceRange RemoveRange,
136                                      StringRef Code) {
137     return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
138   }
139 };
140
141 /// \brief Concrete class used by the front-end to report problems and issues.
142 ///
143 /// This massages the diagnostics (e.g. handling things like "report warnings
144 /// as errors" and passes them off to the DiagnosticConsumer for reporting to
145 /// the user. DiagnosticsEngine is tied to one translation unit and one
146 /// SourceManager.
147 class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
148 public:
149   /// \brief The level of the diagnostic, after it has been through mapping.
150   enum Level {
151     Ignored = DiagnosticIDs::Ignored,
152     Note = DiagnosticIDs::Note,
153     Remark = DiagnosticIDs::Remark,
154     Warning = DiagnosticIDs::Warning,
155     Error = DiagnosticIDs::Error,
156     Fatal = DiagnosticIDs::Fatal
157   };
158
159   enum ArgumentKind {
160     ak_std_string,      ///< std::string
161     ak_c_string,        ///< const char *
162     ak_sint,            ///< int
163     ak_uint,            ///< unsigned
164     ak_tokenkind,       ///< enum TokenKind : unsigned
165     ak_identifierinfo,  ///< IdentifierInfo
166     ak_qualtype,        ///< QualType
167     ak_declarationname, ///< DeclarationName
168     ak_nameddecl,       ///< NamedDecl *
169     ak_nestednamespec,  ///< NestedNameSpecifier *
170     ak_declcontext,     ///< DeclContext *
171     ak_qualtype_pair,   ///< pair<QualType, QualType>
172     ak_attr             ///< Attr *
173   };
174
175   /// \brief Represents on argument value, which is a union discriminated
176   /// by ArgumentKind, with a value.
177   typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
178
179 private:
180   unsigned char AllExtensionsSilenced; // Used by __extension__
181   bool IgnoreAllWarnings;        // Ignore all warnings: -w
182   bool WarningsAsErrors;         // Treat warnings like errors.
183   bool EnableAllWarnings;        // Enable all warnings.
184   bool ErrorsAsFatal;            // Treat errors like fatal errors.
185   bool FatalsAsError;             // Treat fatal errors like errors.
186   bool SuppressSystemWarnings;   // Suppress warnings in system headers.
187   bool SuppressAllDiagnostics;   // Suppress all diagnostics.
188   bool ElideType;                // Elide common types of templates.
189   bool PrintTemplateTree;        // Print a tree when comparing templates.
190   bool ShowColors;               // Color printing is enabled.
191   OverloadsShown ShowOverloads;  // Which overload candidates to show.
192   unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
193   unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
194                                    // 0 -> no limit.
195   unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
196                                     // backtrace stack, 0 -> no limit.
197   diag::Severity ExtBehavior;       // Map extensions to warnings or errors?
198   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
199   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
200   DiagnosticConsumer *Client;
201   std::unique_ptr<DiagnosticConsumer> Owner;
202   SourceManager *SourceMgr;
203
204   /// \brief Mapping information for diagnostics.
205   ///
206   /// Mapping info is packed into four bits per diagnostic.  The low three
207   /// bits are the mapping (an instance of diag::Severity), or zero if unset.
208   /// The high bit is set when the mapping was established as a user mapping.
209   /// If the high bit is clear, then the low bits are set to the default
210   /// value, and should be mapped with -pedantic, -Werror, etc.
211   ///
212   /// A new DiagState is created and kept around when diagnostic pragmas modify
213   /// the state so that we know what is the diagnostic state at any given
214   /// source location.
215   class DiagState {
216     llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
217
218   public:
219     typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
220     typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
221     const_iterator;
222
223     void setMapping(diag::kind Diag, DiagnosticMapping Info) {
224       DiagMap[Diag] = Info;
225     }
226     DiagnosticMapping lookupMapping(diag::kind Diag) const {
227       return DiagMap.lookup(Diag);
228     }
229
230     DiagnosticMapping &getOrAddMapping(diag::kind Diag);
231
232     const_iterator begin() const { return DiagMap.begin(); }
233     const_iterator end() const { return DiagMap.end(); }
234   };
235
236   /// \brief Keeps and automatically disposes all DiagStates that we create.
237   std::list<DiagState> DiagStates;
238
239   /// A mapping from files to the diagnostic states for those files. Lazily
240   /// built on demand for files in which the diagnostic state has not changed.
241   class DiagStateMap {
242   public:
243     /// Add an initial diagnostic state.
244     void appendFirst(DiagState *State);
245     /// Add a new latest state point.
246     void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
247     /// Look up the diagnostic state at a given source location.
248     DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
249     /// Determine whether this map is empty.
250     bool empty() const { return Files.empty(); }
251     /// Clear out this map.
252     void clear() {
253       Files.clear();
254       FirstDiagState = CurDiagState = nullptr;
255       CurDiagStateLoc = SourceLocation();
256     }
257
258     /// Grab the most-recently-added state point.
259     DiagState *getCurDiagState() const { return CurDiagState; }
260     /// Get the location at which a diagnostic state was last added.
261     SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
262
263   private:
264     /// \brief Represents a point in source where the diagnostic state was
265     /// modified because of a pragma.
266     ///
267     /// 'Loc' can be null if the point represents the diagnostic state
268     /// modifications done through the command-line.
269     struct DiagStatePoint {
270       DiagState *State;
271       unsigned Offset;
272       DiagStatePoint(DiagState *State, unsigned Offset)
273         : State(State), Offset(Offset) { } 
274     };
275
276     /// Description of the diagnostic states and state transitions for a
277     /// particular FileID.
278     struct File {
279       /// The diagnostic state for the parent file. This is strictly redundant,
280       /// as looking up the DecomposedIncludedLoc for the FileID in the Files
281       /// map would give us this, but we cache it here for performance.
282       File *Parent = nullptr;
283       /// The offset of this file within its parent.
284       unsigned ParentOffset = 0;
285       /// Whether this file has any local (not imported from an AST file)
286       /// diagnostic state transitions.
287       bool HasLocalTransitions = false;
288       /// The points within the file where the state changes. There will always
289       /// be at least one of these (the state on entry to the file).
290       llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
291
292       DiagState *lookup(unsigned Offset) const;
293     };
294
295     /// The diagnostic states for each file.
296     mutable std::map<FileID, File> Files;
297
298     /// The initial diagnostic state.
299     DiagState *FirstDiagState;
300     /// The current diagnostic state.
301     DiagState *CurDiagState;
302     /// The location at which the current diagnostic state was established.
303     SourceLocation CurDiagStateLoc;
304
305     /// Get the diagnostic state information for a file.
306     File *getFile(SourceManager &SrcMgr, FileID ID) const;
307
308     friend class ASTReader;
309     friend class ASTWriter;
310   };
311
312   DiagStateMap DiagStatesByLoc;
313
314   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
315   /// so we can get back at it when we 'pop'.
316   std::vector<DiagState *> DiagStateOnPushStack;
317
318   DiagState *GetCurDiagState() const {
319     return DiagStatesByLoc.getCurDiagState();
320   }
321
322   void PushDiagStatePoint(DiagState *State, SourceLocation L);
323
324   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
325   /// the given source location.
326   DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
327     return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
328                      : DiagStatesByLoc.getCurDiagState();
329   }
330
331   /// \brief Sticky flag set to \c true when an error is emitted.
332   bool ErrorOccurred;
333
334   /// \brief Sticky flag set to \c true when an "uncompilable error" occurs.
335   /// I.e. an error that was not upgraded from a warning by -Werror.
336   bool UncompilableErrorOccurred;
337
338   /// \brief Sticky flag set to \c true when a fatal error is emitted.
339   bool FatalErrorOccurred;
340
341   /// \brief Indicates that an unrecoverable error has occurred.
342   bool UnrecoverableErrorOccurred;
343   
344   /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
345   /// during a parsing section, e.g. during parsing a function.
346   unsigned TrapNumErrorsOccurred;
347   unsigned TrapNumUnrecoverableErrorsOccurred;
348
349   /// \brief The level of the last diagnostic emitted.
350   ///
351   /// This is used to emit continuation diagnostics with the same level as the
352   /// diagnostic that they follow.
353   DiagnosticIDs::Level LastDiagLevel;
354
355   unsigned NumWarnings;         ///< Number of warnings reported
356   unsigned NumErrors;           ///< Number of errors reported
357
358   /// \brief A function pointer that converts an opaque diagnostic
359   /// argument to a strings.
360   ///
361   /// This takes the modifiers and argument that was present in the diagnostic.
362   ///
363   /// The PrevArgs array indicates the previous arguments formatted for this
364   /// diagnostic.  Implementations of this function can use this information to
365   /// avoid redundancy across arguments.
366   ///
367   /// This is a hack to avoid a layering violation between libbasic and libsema.
368   typedef void (*ArgToStringFnTy)(
369       ArgumentKind Kind, intptr_t Val,
370       StringRef Modifier, StringRef Argument,
371       ArrayRef<ArgumentValue> PrevArgs,
372       SmallVectorImpl<char> &Output,
373       void *Cookie,
374       ArrayRef<intptr_t> QualTypeVals);
375   void *ArgToStringCookie;
376   ArgToStringFnTy ArgToStringFn;
377
378   /// \brief ID of the "delayed" diagnostic, which is a (typically
379   /// fatal) diagnostic that had to be delayed because it was found
380   /// while emitting another diagnostic.
381   unsigned DelayedDiagID;
382
383   /// \brief First string argument for the delayed diagnostic.
384   std::string DelayedDiagArg1;
385
386   /// \brief Second string argument for the delayed diagnostic.
387   std::string DelayedDiagArg2;
388
389   /// \brief Optional flag value.
390   ///
391   /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
392   /// -Rpass=<value>. The content of this string is emitted after the flag name
393   /// and '='.
394   std::string FlagValue;
395
396 public:
397   explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
398                              DiagnosticOptions *DiagOpts,
399                              DiagnosticConsumer *client = nullptr,
400                              bool ShouldOwnClient = true);
401   DiagnosticsEngine(const DiagnosticsEngine &) = delete;
402   DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
403   ~DiagnosticsEngine();
404
405   const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
406     return Diags;
407   }
408
409   /// \brief Retrieve the diagnostic options.
410   DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
411
412   typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
413
414   /// \brief Get the current set of diagnostic mappings.
415   diag_mapping_range getDiagnosticMappings() const {
416     const DiagState &DS = *GetCurDiagState();
417     return diag_mapping_range(DS.begin(), DS.end());
418   }
419
420   DiagnosticConsumer *getClient() { return Client; }
421   const DiagnosticConsumer *getClient() const { return Client; }
422
423   /// \brief Determine whether this \c DiagnosticsEngine object own its client.
424   bool ownsClient() const { return Owner != nullptr; }
425
426   /// \brief Return the current diagnostic client along with ownership of that
427   /// client.
428   std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
429
430   bool hasSourceManager() const { return SourceMgr != nullptr; }
431   SourceManager &getSourceManager() const {
432     assert(SourceMgr && "SourceManager not set!");
433     return *SourceMgr;
434   }
435   void setSourceManager(SourceManager *SrcMgr) {
436     assert(DiagStatesByLoc.empty() &&
437            "Leftover diag state from a different SourceManager.");
438     SourceMgr = SrcMgr;
439   }
440
441   //===--------------------------------------------------------------------===//
442   //  DiagnosticsEngine characterization methods, used by a client to customize
443   //  how diagnostics are emitted.
444   //
445
446   /// \brief Copies the current DiagMappings and pushes the new copy
447   /// onto the top of the stack.
448   void pushMappings(SourceLocation Loc);
449
450   /// \brief Pops the current DiagMappings off the top of the stack,
451   /// causing the new top of the stack to be the active mappings.
452   ///
453   /// \returns \c true if the pop happens, \c false if there is only one
454   /// DiagMapping on the stack.
455   bool popMappings(SourceLocation Loc);
456
457   /// \brief Set the diagnostic client associated with this diagnostic object.
458   ///
459   /// \param ShouldOwnClient true if the diagnostic object should take
460   /// ownership of \c client.
461   void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
462
463   /// \brief Specify a limit for the number of errors we should
464   /// emit before giving up.
465   ///
466   /// Zero disables the limit.
467   void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
468   
469   /// \brief Specify the maximum number of template instantiation
470   /// notes to emit along with a given diagnostic.
471   void setTemplateBacktraceLimit(unsigned Limit) {
472     TemplateBacktraceLimit = Limit;
473   }
474
475   /// \brief Retrieve the maximum number of template instantiation
476   /// notes to emit along with a given diagnostic.
477   unsigned getTemplateBacktraceLimit() const {
478     return TemplateBacktraceLimit;
479   }
480
481   /// \brief Specify the maximum number of constexpr evaluation
482   /// notes to emit along with a given diagnostic.
483   void setConstexprBacktraceLimit(unsigned Limit) {
484     ConstexprBacktraceLimit = Limit;
485   }
486
487   /// \brief Retrieve the maximum number of constexpr evaluation
488   /// notes to emit along with a given diagnostic.
489   unsigned getConstexprBacktraceLimit() const {
490     return ConstexprBacktraceLimit;
491   }
492
493   /// \brief When set to true, any unmapped warnings are ignored.
494   ///
495   /// If this and WarningsAsErrors are both set, then this one wins.
496   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
497   bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
498
499   /// \brief When set to true, any unmapped ignored warnings are no longer
500   /// ignored.
501   ///
502   /// If this and IgnoreAllWarnings are both set, then that one wins.
503   void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
504   bool getEnableAllWarnings() const { return EnableAllWarnings; }
505
506   /// \brief When set to true, any warnings reported are issued as errors.
507   void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
508   bool getWarningsAsErrors() const { return WarningsAsErrors; }
509
510   /// \brief When set to true, any error reported is made a fatal error.
511   void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
512   bool getErrorsAsFatal() const { return ErrorsAsFatal; }
513
514   /// \brief When set to true, any fatal error reported is made an error.
515   ///
516   /// This setting takes precedence over the setErrorsAsFatal setting above.
517   void setFatalsAsError(bool Val) { FatalsAsError = Val; }
518   bool getFatalsAsError() const { return FatalsAsError; }
519
520   /// \brief When set to true mask warnings that come from system headers.
521   void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
522   bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
523
524   /// \brief Suppress all diagnostics, to silence the front end when we 
525   /// know that we don't want any more diagnostics to be passed along to the
526   /// client
527   void setSuppressAllDiagnostics(bool Val = true) { 
528     SuppressAllDiagnostics = Val; 
529   }
530   bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
531
532   /// \brief Set type eliding, to skip outputting same types occurring in
533   /// template types.
534   void setElideType(bool Val = true) { ElideType = Val; }
535   bool getElideType() { return ElideType; }
536  
537   /// \brief Set tree printing, to outputting the template difference in a
538   /// tree format.
539   void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
540   bool getPrintTemplateTree() { return PrintTemplateTree; }
541  
542   /// \brief Set color printing, so the type diffing will inject color markers
543   /// into the output.
544   void setShowColors(bool Val = false) { ShowColors = Val; }
545   bool getShowColors() { return ShowColors; }
546
547   /// \brief Specify which overload candidates to show when overload resolution
548   /// fails.
549   ///
550   /// By default, we show all candidates.
551   void setShowOverloads(OverloadsShown Val) {
552     ShowOverloads = Val;
553   }
554   OverloadsShown getShowOverloads() const { return ShowOverloads; }
555   
556   /// \brief Pretend that the last diagnostic issued was ignored, so any
557   /// subsequent notes will be suppressed.
558   ///
559   /// This can be used by clients who suppress diagnostics themselves.
560   void setLastDiagnosticIgnored() {
561     if (LastDiagLevel == DiagnosticIDs::Fatal)
562       FatalErrorOccurred = true;
563     LastDiagLevel = DiagnosticIDs::Ignored;
564   }
565
566   /// \brief Determine whether the previous diagnostic was ignored. This can
567   /// be used by clients that want to determine whether notes attached to a
568   /// diagnostic will be suppressed.
569   bool isLastDiagnosticIgnored() const {
570     return LastDiagLevel == DiagnosticIDs::Ignored;
571   }
572
573   /// \brief Controls whether otherwise-unmapped extension diagnostics are
574   /// mapped onto ignore/warning/error. 
575   ///
576   /// This corresponds to the GCC -pedantic and -pedantic-errors option.
577   void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; }
578   diag::Severity getExtensionHandlingBehavior() const { return ExtBehavior; }
579
580   /// \brief Counter bumped when an __extension__  block is/ encountered.
581   ///
582   /// When non-zero, all extension diagnostics are entirely silenced, no
583   /// matter how they are mapped.
584   void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
585   void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
586   bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
587
588   /// \brief This allows the client to specify that certain warnings are
589   /// ignored.
590   ///
591   /// Notes can never be mapped, errors can only be mapped to fatal, and
592   /// WARNINGs and EXTENSIONs can be mapped arbitrarily.
593   ///
594   /// \param Loc The source location that this change of diagnostic state should
595   /// take affect. It can be null if we are setting the latest state.
596   void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
597
598   /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
599   /// have the specified mapping.
600   ///
601   /// \returns true (and ignores the request) if "Group" was unknown, false
602   /// otherwise.
603   ///
604   /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
605   /// state of the -Wfoo group and vice versa.
606   ///
607   /// \param Loc The source location that this change of diagnostic state should
608   /// take affect. It can be null if we are setting the state from command-line.
609   bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
610                            diag::Severity Map,
611                            SourceLocation Loc = SourceLocation());
612
613   /// \brief Set the warning-as-error flag for the given diagnostic group.
614   ///
615   /// This function always only operates on the current diagnostic state.
616   ///
617   /// \returns True if the given group is unknown, false otherwise.
618   bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
619
620   /// \brief Set the error-as-fatal flag for the given diagnostic group.
621   ///
622   /// This function always only operates on the current diagnostic state.
623   ///
624   /// \returns True if the given group is unknown, false otherwise.
625   bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
626
627   /// \brief Add the specified mapping to all diagnostics of the specified
628   /// flavor.
629   ///
630   /// Mainly to be used by -Wno-everything to disable all warnings but allow
631   /// subsequent -W options to enable specific warnings.
632   void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
633                          SourceLocation Loc = SourceLocation());
634
635   bool hasErrorOccurred() const { return ErrorOccurred; }
636
637   /// \brief Errors that actually prevent compilation, not those that are
638   /// upgraded from a warning by -Werror.
639   bool hasUncompilableErrorOccurred() const {
640     return UncompilableErrorOccurred;
641   }
642   bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
643   
644   /// \brief Determine whether any kind of unrecoverable error has occurred.
645   bool hasUnrecoverableErrorOccurred() const {
646     return FatalErrorOccurred || UnrecoverableErrorOccurred;
647   }
648   
649   unsigned getNumWarnings() const { return NumWarnings; }
650
651   void setNumWarnings(unsigned NumWarnings) {
652     this->NumWarnings = NumWarnings;
653   }
654
655   /// \brief Return an ID for a diagnostic with the specified format string and
656   /// level.
657   ///
658   /// If this is the first request for this diagnostic, it is registered and
659   /// created, otherwise the existing ID is returned.
660   ///
661   /// \param FormatString A fixed diagnostic format string that will be hashed
662   /// and mapped to a unique DiagID.
663   template <unsigned N>
664   unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
665     return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
666                                   StringRef(FormatString, N - 1));
667   }
668
669   /// \brief Converts a diagnostic argument (as an intptr_t) into the string
670   /// that represents it.
671   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
672                           StringRef Modifier, StringRef Argument,
673                           ArrayRef<ArgumentValue> PrevArgs,
674                           SmallVectorImpl<char> &Output,
675                           ArrayRef<intptr_t> QualTypeVals) const {
676     ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
677                   ArgToStringCookie, QualTypeVals);
678   }
679
680   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
681     ArgToStringFn = Fn;
682     ArgToStringCookie = Cookie;
683   }
684
685   /// \brief Note that the prior diagnostic was emitted by some other
686   /// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
687   void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
688     LastDiagLevel = Other.LastDiagLevel;
689   }
690
691   /// \brief Reset the state of the diagnostic object to its initial 
692   /// configuration.
693   void Reset();
694   
695   //===--------------------------------------------------------------------===//
696   // DiagnosticsEngine classification and reporting interfaces.
697   //
698
699   /// \brief Determine whether the diagnostic is known to be ignored.
700   ///
701   /// This can be used to opportunistically avoid expensive checks when it's
702   /// known for certain that the diagnostic has been suppressed at the
703   /// specified location \p Loc.
704   ///
705   /// \param Loc The source location we are interested in finding out the
706   /// diagnostic state. Can be null in order to query the latest state.
707   bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
708     return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
709            diag::Severity::Ignored;
710   }
711
712   /// \brief Based on the way the client configured the DiagnosticsEngine
713   /// object, classify the specified diagnostic ID into a Level, consumable by
714   /// the DiagnosticConsumer.
715   ///
716   /// To preserve invariant assumptions, this function should not be used to
717   /// influence parse or semantic analysis actions. Instead consider using
718   /// \c isIgnored().
719   ///
720   /// \param Loc The source location we are interested in finding out the
721   /// diagnostic state. Can be null in order to query the latest state.
722   Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
723     return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
724   }
725
726   /// \brief Issue the message to the client.
727   ///
728   /// This actually returns an instance of DiagnosticBuilder which emits the
729   /// diagnostics (through @c ProcessDiag) when it is destroyed.
730   ///
731   /// \param DiagID A member of the @c diag::kind enum.
732   /// \param Loc Represents the source location associated with the diagnostic,
733   /// which can be an invalid location if no position information is available.
734   inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
735   inline DiagnosticBuilder Report(unsigned DiagID);
736
737   void Report(const StoredDiagnostic &storedDiag);
738
739   /// \brief Determine whethere there is already a diagnostic in flight.
740   bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
741
742   /// \brief Set the "delayed" diagnostic that will be emitted once
743   /// the current diagnostic completes.
744   ///
745   ///  If a diagnostic is already in-flight but the front end must
746   ///  report a problem (e.g., with an inconsistent file system
747   ///  state), this routine sets a "delayed" diagnostic that will be
748   ///  emitted after the current diagnostic completes. This should
749   ///  only be used for fatal errors detected at inconvenient
750   ///  times. If emitting a delayed diagnostic causes a second delayed
751   ///  diagnostic to be introduced, that second delayed diagnostic
752   ///  will be ignored.
753   ///
754   /// \param DiagID The ID of the diagnostic being delayed.
755   ///
756   /// \param Arg1 A string argument that will be provided to the
757   /// diagnostic. A copy of this string will be stored in the
758   /// DiagnosticsEngine object itself.
759   ///
760   /// \param Arg2 A string argument that will be provided to the
761   /// diagnostic. A copy of this string will be stored in the
762   /// DiagnosticsEngine object itself.
763   void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
764                             StringRef Arg2 = "");
765   
766   /// \brief Clear out the current diagnostic.
767   void Clear() { CurDiagID = ~0U; }
768
769   /// \brief Return the value associated with this diagnostic flag.
770   StringRef getFlagValue() const { return FlagValue; }
771
772 private:
773   /// \brief Report the delayed diagnostic.
774   void ReportDelayed();
775
776   // This is private state used by DiagnosticBuilder.  We put it here instead of
777   // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
778   // object.  This implementation choice means that we can only have one
779   // diagnostic "in flight" at a time, but this seems to be a reasonable
780   // tradeoff to keep these objects small.  Assertions verify that only one
781   // diagnostic is in flight at a time.
782   friend class DiagnosticIDs;
783   friend class DiagnosticBuilder;
784   friend class Diagnostic;
785   friend class PartialDiagnostic;
786   friend class DiagnosticErrorTrap;
787   
788   /// \brief The location of the current diagnostic that is in flight.
789   SourceLocation CurDiagLoc;
790
791   /// \brief The ID of the current diagnostic that is in flight.
792   ///
793   /// This is set to ~0U when there is no diagnostic in flight.
794   unsigned CurDiagID;
795
796   enum {
797     /// \brief The maximum number of arguments we can hold.
798     ///
799     /// We currently only support up to 10 arguments (%0-%9).  A single
800     /// diagnostic with more than that almost certainly has to be simplified
801     /// anyway.
802     MaxArguments = 10,
803   };
804
805   /// \brief The number of entries in Arguments.
806   signed char NumDiagArgs;
807
808   /// \brief Specifies whether an argument is in DiagArgumentsStr or
809   /// in DiagArguments.
810   ///
811   /// This is an array of ArgumentKind::ArgumentKind enum values, one for each
812   /// argument.
813   unsigned char DiagArgumentsKind[MaxArguments];
814
815   /// \brief Holds the values of each string argument for the current
816   /// diagnostic.
817   ///
818   /// This is only used when the corresponding ArgumentKind is ak_std_string.
819   std::string DiagArgumentsStr[MaxArguments];
820
821   /// \brief The values for the various substitution positions.
822   ///
823   /// This is used when the argument is not an std::string.  The specific
824   /// value is mangled into an intptr_t and the interpretation depends on
825   /// exactly what sort of argument kind it is.
826   intptr_t DiagArgumentsVal[MaxArguments];
827
828   /// \brief The list of ranges added to this diagnostic.
829   SmallVector<CharSourceRange, 8> DiagRanges;
830
831   /// \brief If valid, provides a hint with some code to insert, remove,
832   /// or modify at a particular position.
833   SmallVector<FixItHint, 8> DiagFixItHints;
834
835   DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
836     bool isPragma = L.isValid();
837     DiagnosticMapping Mapping =
838         DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
839
840     // If this is a pragma mapping, then set the diagnostic mapping flags so
841     // that we override command line options.
842     if (isPragma) {
843       Mapping.setNoWarningAsError(true);
844       Mapping.setNoErrorAsFatal(true);
845     }
846
847     return Mapping;
848   }
849
850   /// \brief Used to report a diagnostic that is finally fully formed.
851   ///
852   /// \returns true if the diagnostic was emitted, false if it was suppressed.
853   bool ProcessDiag() {
854     return Diags->ProcessDiag(*this);
855   }
856
857   /// @name Diagnostic Emission
858   /// @{
859 protected:
860   // Sema requires access to the following functions because the current design
861   // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
862   // access us directly to ensure we minimize the emitted code for the common
863   // Sema::Diag() patterns.
864   friend class Sema;
865
866   /// \brief Emit the current diagnostic and clear the diagnostic state.
867   ///
868   /// \param Force Emit the diagnostic regardless of suppression settings.
869   bool EmitCurrentDiagnostic(bool Force = false);
870
871   unsigned getCurrentDiagID() const { return CurDiagID; }
872
873   SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
874
875   /// @}
876
877   friend class ASTReader;
878   friend class ASTWriter;
879 };
880
881 /// \brief RAII class that determines when any errors have occurred
882 /// between the time the instance was created and the time it was
883 /// queried.
884 class DiagnosticErrorTrap {
885   DiagnosticsEngine &Diag;
886   unsigned NumErrors;
887   unsigned NumUnrecoverableErrors;
888
889 public:
890   explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
891     : Diag(Diag) { reset(); }
892
893   /// \brief Determine whether any errors have occurred since this
894   /// object instance was created.
895   bool hasErrorOccurred() const {
896     return Diag.TrapNumErrorsOccurred > NumErrors;
897   }
898
899   /// \brief Determine whether any unrecoverable errors have occurred since this
900   /// object instance was created.
901   bool hasUnrecoverableErrorOccurred() const {
902     return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
903   }
904
905   /// \brief Set to initial state of "no errors occurred".
906   void reset() {
907     NumErrors = Diag.TrapNumErrorsOccurred;
908     NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
909   }
910 };
911
912 //===----------------------------------------------------------------------===//
913 // DiagnosticBuilder
914 //===----------------------------------------------------------------------===//
915
916 /// \brief A little helper class used to produce diagnostics.
917 ///
918 /// This is constructed by the DiagnosticsEngine::Report method, and
919 /// allows insertion of extra information (arguments and source ranges) into
920 /// the currently "in flight" diagnostic.  When the temporary for the builder
921 /// is destroyed, the diagnostic is issued.
922 ///
923 /// Note that many of these will be created as temporary objects (many call
924 /// sites), so we want them to be small and we never want their address taken.
925 /// This ensures that compilers with somewhat reasonable optimizers will promote
926 /// the common fields to registers, eliminating increments of the NumArgs field,
927 /// for example.
928 class DiagnosticBuilder {
929   mutable DiagnosticsEngine *DiagObj = nullptr;
930   mutable unsigned NumArgs = 0;
931
932   /// \brief Status variable indicating if this diagnostic is still active.
933   ///
934   // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
935   // but LLVM is not currently smart enough to eliminate the null check that
936   // Emit() would end up with if we used that as our status variable.
937   mutable bool IsActive = false;
938
939   /// \brief Flag indicating that this diagnostic is being emitted via a
940   /// call to ForceEmit.
941   mutable bool IsForceEmit = false;
942
943   friend class DiagnosticsEngine;
944
945   DiagnosticBuilder() = default;
946
947   explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
948       : DiagObj(diagObj), IsActive(true) {
949     assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
950     diagObj->DiagRanges.clear();
951     diagObj->DiagFixItHints.clear();
952   }
953
954   friend class PartialDiagnostic;
955   
956 protected:
957   void FlushCounts() {
958     DiagObj->NumDiagArgs = NumArgs;
959   }
960
961   /// \brief Clear out the current diagnostic.
962   void Clear() const {
963     DiagObj = nullptr;
964     IsActive = false;
965     IsForceEmit = false;
966   }
967
968   /// \brief Determine whether this diagnostic is still active.
969   bool isActive() const { return IsActive; }
970
971   /// \brief Force the diagnostic builder to emit the diagnostic now.
972   ///
973   /// Once this function has been called, the DiagnosticBuilder object
974   /// should not be used again before it is destroyed.
975   ///
976   /// \returns true if a diagnostic was emitted, false if the
977   /// diagnostic was suppressed.
978   bool Emit() {
979     // If this diagnostic is inactive, then its soul was stolen by the copy ctor
980     // (or by a subclass, as in SemaDiagnosticBuilder).
981     if (!isActive()) return false;
982
983     // When emitting diagnostics, we set the final argument count into
984     // the DiagnosticsEngine object.
985     FlushCounts();
986
987     // Process the diagnostic.
988     bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
989
990     // This diagnostic is dead.
991     Clear();
992
993     return Result;
994   }
995   
996 public:
997   /// Copy constructor.  When copied, this "takes" the diagnostic info from the
998   /// input and neuters it.
999   DiagnosticBuilder(const DiagnosticBuilder &D) {
1000     DiagObj = D.DiagObj;
1001     IsActive = D.IsActive;
1002     IsForceEmit = D.IsForceEmit;
1003     D.Clear();
1004     NumArgs = D.NumArgs;
1005   }
1006
1007   DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
1008
1009   /// \brief Emits the diagnostic.
1010   ~DiagnosticBuilder() {
1011     Emit();
1012   }
1013
1014   /// \brief Retrieve an empty diagnostic builder.
1015   static DiagnosticBuilder getEmpty() {
1016     return DiagnosticBuilder();
1017   }
1018
1019   /// \brief Forces the diagnostic to be emitted.
1020   const DiagnosticBuilder &setForceEmit() const {
1021     IsForceEmit = true;
1022     return *this;
1023   }
1024
1025   /// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
1026   ///
1027   /// This allows is to be used in boolean error contexts (where \c true is
1028   /// used to indicate that an error has occurred), like:
1029   /// \code
1030   /// return Diag(...);
1031   /// \endcode
1032   operator bool() const { return true; }
1033
1034   void AddString(StringRef S) const {
1035     assert(isActive() && "Clients must not add to cleared diagnostic!");
1036     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
1037            "Too many arguments to diagnostic!");
1038     DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
1039     DiagObj->DiagArgumentsStr[NumArgs++] = S;
1040   }
1041
1042   void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
1043     assert(isActive() && "Clients must not add to cleared diagnostic!");
1044     assert(NumArgs < DiagnosticsEngine::MaxArguments &&
1045            "Too many arguments to diagnostic!");
1046     DiagObj->DiagArgumentsKind[NumArgs] = Kind;
1047     DiagObj->DiagArgumentsVal[NumArgs++] = V;
1048   }
1049
1050   void AddSourceRange(const CharSourceRange &R) const {
1051     assert(isActive() && "Clients must not add to cleared diagnostic!");
1052     DiagObj->DiagRanges.push_back(R);
1053   }
1054
1055   void AddFixItHint(const FixItHint &Hint) const {
1056     assert(isActive() && "Clients must not add to cleared diagnostic!");
1057     if (!Hint.isNull())
1058       DiagObj->DiagFixItHints.push_back(Hint);
1059   }
1060
1061   void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
1062 };
1063
1064 struct AddFlagValue {
1065   explicit AddFlagValue(StringRef V) : Val(V) {}
1066   StringRef Val;
1067 };
1068
1069 /// \brief Register a value for the flag in the current diagnostic. This
1070 /// value will be shown as the suffix "=value" after the flag name. It is
1071 /// useful in cases where the diagnostic flag accepts values (e.g.,
1072 /// -Rpass or -Wframe-larger-than).
1073 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1074                                            const AddFlagValue V) {
1075   DB.addFlagValue(V.Val);
1076   return DB;
1077 }
1078
1079 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1080                                            StringRef S) {
1081   DB.AddString(S);
1082   return DB;
1083 }
1084
1085 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1086                                            const char *Str) {
1087   DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
1088                   DiagnosticsEngine::ak_c_string);
1089   return DB;
1090 }
1091
1092 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
1093   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1094   return DB;
1095 }
1096
1097 // We use enable_if here to prevent that this overload is selected for
1098 // pointers or other arguments that are implicitly convertible to bool.
1099 template <typename T>
1100 inline
1101 typename std::enable_if<std::is_same<T, bool>::value,
1102                         const DiagnosticBuilder &>::type
1103 operator<<(const DiagnosticBuilder &DB, T I) {
1104   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1105   return DB;
1106 }
1107
1108 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1109                                            unsigned I) {
1110   DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1111   return DB;
1112 }
1113
1114 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1115                                            tok::TokenKind I) {
1116   DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
1117   return DB;
1118 }
1119
1120 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1121                                            const IdentifierInfo *II) {
1122   DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
1123                   DiagnosticsEngine::ak_identifierinfo);
1124   return DB;
1125 }
1126
1127 // Adds a DeclContext to the diagnostic. The enable_if template magic is here
1128 // so that we only match those arguments that are (statically) DeclContexts;
1129 // other arguments that derive from DeclContext (e.g., RecordDecls) will not
1130 // match.
1131 template <typename T>
1132 inline typename std::enable_if<
1133     std::is_same<typename std::remove_const<T>::type, DeclContext>::value,
1134     const DiagnosticBuilder &>::type
1135 operator<<(const DiagnosticBuilder &DB, T *DC) {
1136   DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1137                   DiagnosticsEngine::ak_declcontext);
1138   return DB;
1139 }
1140
1141 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1142                                            SourceRange R) {
1143   DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1144   return DB;
1145 }
1146
1147 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1148                                            ArrayRef<SourceRange> Ranges) {
1149   for (SourceRange R : Ranges)
1150     DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1151   return DB;
1152 }
1153
1154 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1155                                            const CharSourceRange &R) {
1156   DB.AddSourceRange(R);
1157   return DB;
1158 }
1159
1160 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1161                                            const FixItHint &Hint) {
1162   DB.AddFixItHint(Hint);
1163   return DB;
1164 }
1165
1166 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1167                                            ArrayRef<FixItHint> Hints) {
1168   for (const FixItHint &Hint : Hints)
1169     DB.AddFixItHint(Hint);
1170   return DB;
1171 }
1172
1173 /// A nullability kind paired with a bit indicating whether it used a
1174 /// context-sensitive keyword.
1175 typedef std::pair<NullabilityKind, bool> DiagNullabilityKind;
1176
1177 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1178                                     DiagNullabilityKind nullability);
1179
1180 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
1181                                                    unsigned DiagID) {
1182   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
1183   CurDiagLoc = Loc;
1184   CurDiagID = DiagID;
1185   FlagValue.clear();
1186   return DiagnosticBuilder(this);
1187 }
1188
1189 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
1190   return Report(SourceLocation(), DiagID);
1191 }
1192
1193 //===----------------------------------------------------------------------===//
1194 // Diagnostic
1195 //===----------------------------------------------------------------------===//
1196
1197 /// A little helper class (which is basically a smart pointer that forwards
1198 /// info from DiagnosticsEngine) that allows clients to enquire about the
1199 /// currently in-flight diagnostic.
1200 class Diagnostic {
1201   const DiagnosticsEngine *DiagObj;
1202   StringRef StoredDiagMessage;
1203
1204 public:
1205   explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
1206   Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
1207     : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
1208
1209   const DiagnosticsEngine *getDiags() const { return DiagObj; }
1210   unsigned getID() const { return DiagObj->CurDiagID; }
1211   const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
1212   bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
1213   SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
1214
1215   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
1216
1217   /// \brief Return the kind of the specified index.
1218   ///
1219   /// Based on the kind of argument, the accessors below can be used to get
1220   /// the value.
1221   ///
1222   /// \pre Idx < getNumArgs()
1223   DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
1224     assert(Idx < getNumArgs() && "Argument index out of range!");
1225     return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
1226   }
1227
1228   /// \brief Return the provided argument string specified by \p Idx.
1229   /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
1230   const std::string &getArgStdStr(unsigned Idx) const {
1231     assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
1232            "invalid argument accessor!");
1233     return DiagObj->DiagArgumentsStr[Idx];
1234   }
1235
1236   /// \brief Return the specified C string argument.
1237   /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
1238   const char *getArgCStr(unsigned Idx) const {
1239     assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
1240            "invalid argument accessor!");
1241     return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
1242   }
1243
1244   /// \brief Return the specified signed integer argument.
1245   /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
1246   int getArgSInt(unsigned Idx) const {
1247     assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
1248            "invalid argument accessor!");
1249     return (int)DiagObj->DiagArgumentsVal[Idx];
1250   }
1251
1252   /// \brief Return the specified unsigned integer argument.
1253   /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
1254   unsigned getArgUInt(unsigned Idx) const {
1255     assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
1256            "invalid argument accessor!");
1257     return (unsigned)DiagObj->DiagArgumentsVal[Idx];
1258   }
1259
1260   /// \brief Return the specified IdentifierInfo argument.
1261   /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
1262   const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
1263     assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
1264            "invalid argument accessor!");
1265     return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
1266   }
1267
1268   /// \brief Return the specified non-string argument in an opaque form.
1269   /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
1270   intptr_t getRawArg(unsigned Idx) const {
1271     assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
1272            "invalid argument accessor!");
1273     return DiagObj->DiagArgumentsVal[Idx];
1274   }
1275
1276   /// \brief Return the number of source ranges associated with this diagnostic.
1277   unsigned getNumRanges() const {
1278     return DiagObj->DiagRanges.size();
1279   }
1280
1281   /// \pre Idx < getNumRanges()
1282   const CharSourceRange &getRange(unsigned Idx) const {
1283     assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
1284     return DiagObj->DiagRanges[Idx];
1285   }
1286
1287   /// \brief Return an array reference for this diagnostic's ranges.
1288   ArrayRef<CharSourceRange> getRanges() const {
1289     return DiagObj->DiagRanges;
1290   }
1291
1292   unsigned getNumFixItHints() const {
1293     return DiagObj->DiagFixItHints.size();
1294   }
1295
1296   const FixItHint &getFixItHint(unsigned Idx) const {
1297     assert(Idx < getNumFixItHints() && "Invalid index!");
1298     return DiagObj->DiagFixItHints[Idx];
1299   }
1300
1301   ArrayRef<FixItHint> getFixItHints() const {
1302     return DiagObj->DiagFixItHints;
1303   }
1304
1305   /// \brief Format this diagnostic into a string, substituting the
1306   /// formal arguments into the %0 slots.
1307   ///
1308   /// The result is appended onto the \p OutStr array.
1309   void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
1310
1311   /// \brief Format the given format-string into the output buffer using the
1312   /// arguments stored in this diagnostic.
1313   void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
1314                         SmallVectorImpl<char> &OutStr) const;
1315 };
1316
1317 /**
1318  * \brief Represents a diagnostic in a form that can be retained until its 
1319  * corresponding source manager is destroyed. 
1320  */
1321 class StoredDiagnostic {
1322   unsigned ID;
1323   DiagnosticsEngine::Level Level;
1324   FullSourceLoc Loc;
1325   std::string Message;
1326   std::vector<CharSourceRange> Ranges;
1327   std::vector<FixItHint> FixIts;
1328
1329 public:
1330   StoredDiagnostic() = default;
1331   StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
1332   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
1333                    StringRef Message);
1334   StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
1335                    StringRef Message, FullSourceLoc Loc,
1336                    ArrayRef<CharSourceRange> Ranges,
1337                    ArrayRef<FixItHint> Fixits);
1338
1339   /// \brief Evaluates true when this object stores a diagnostic.
1340   explicit operator bool() const { return !Message.empty(); }
1341
1342   unsigned getID() const { return ID; }
1343   DiagnosticsEngine::Level getLevel() const { return Level; }
1344   const FullSourceLoc &getLocation() const { return Loc; }
1345   StringRef getMessage() const { return Message; }
1346
1347   void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
1348
1349   typedef std::vector<CharSourceRange>::const_iterator range_iterator;
1350   range_iterator range_begin() const { return Ranges.begin(); }
1351   range_iterator range_end() const { return Ranges.end(); }
1352   unsigned range_size() const { return Ranges.size(); }
1353   
1354   ArrayRef<CharSourceRange> getRanges() const {
1355     return llvm::makeArrayRef(Ranges);
1356   }
1357
1358   typedef std::vector<FixItHint>::const_iterator fixit_iterator;
1359   fixit_iterator fixit_begin() const { return FixIts.begin(); }
1360   fixit_iterator fixit_end() const { return FixIts.end(); }
1361   unsigned fixit_size() const { return FixIts.size(); }
1362   
1363   ArrayRef<FixItHint> getFixIts() const {
1364     return llvm::makeArrayRef(FixIts);
1365   }
1366 };
1367
1368 /// \brief Abstract interface, implemented by clients of the front-end, which
1369 /// formats and prints fully processed diagnostics.
1370 class DiagnosticConsumer {
1371 protected:
1372   unsigned NumWarnings = 0;       ///< Number of warnings reported
1373   unsigned NumErrors = 0;         ///< Number of errors reported
1374   
1375 public:
1376   DiagnosticConsumer() = default;
1377
1378   virtual ~DiagnosticConsumer();
1379
1380   unsigned getNumErrors() const { return NumErrors; }
1381   unsigned getNumWarnings() const { return NumWarnings; }
1382   virtual void clear() { NumWarnings = NumErrors = 0; }
1383
1384   /// \brief Callback to inform the diagnostic client that processing
1385   /// of a source file is beginning.
1386   ///
1387   /// Note that diagnostics may be emitted outside the processing of a source
1388   /// file, for example during the parsing of command line options. However,
1389   /// diagnostics with source range information are required to only be emitted
1390   /// in between BeginSourceFile() and EndSourceFile().
1391   ///
1392   /// \param LangOpts The language options for the source file being processed.
1393   /// \param PP The preprocessor object being used for the source; this is 
1394   /// optional, e.g., it may not be present when processing AST source files.
1395   virtual void BeginSourceFile(const LangOptions &LangOpts,
1396                                const Preprocessor *PP = nullptr) {}
1397
1398   /// \brief Callback to inform the diagnostic client that processing
1399   /// of a source file has ended.
1400   ///
1401   /// The diagnostic client should assume that any objects made available via
1402   /// BeginSourceFile() are inaccessible.
1403   virtual void EndSourceFile() {}
1404
1405   /// \brief Callback to inform the diagnostic client that processing of all
1406   /// source files has ended.
1407   virtual void finish() {}
1408
1409   /// \brief Indicates whether the diagnostics handled by this
1410   /// DiagnosticConsumer should be included in the number of diagnostics
1411   /// reported by DiagnosticsEngine.
1412   ///
1413   /// The default implementation returns true.
1414   virtual bool IncludeInDiagnosticCounts() const;
1415
1416   /// \brief Handle this diagnostic, reporting it to the user or
1417   /// capturing it to a log as needed.
1418   ///
1419   /// The default implementation just keeps track of the total number of
1420   /// warnings and errors.
1421   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1422                                 const Diagnostic &Info);
1423 };
1424
1425 /// \brief A diagnostic client that ignores all diagnostics.
1426 class IgnoringDiagConsumer : public DiagnosticConsumer {
1427   virtual void anchor();
1428
1429   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1430                         const Diagnostic &Info) override {
1431     // Just ignore it.
1432   }
1433 };
1434
1435 /// \brief Diagnostic consumer that forwards diagnostics along to an
1436 /// existing, already-initialized diagnostic consumer.
1437 ///
1438 class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
1439   DiagnosticConsumer &Target;
1440
1441 public:
1442   ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
1443
1444   ~ForwardingDiagnosticConsumer() override;
1445
1446   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1447                         const Diagnostic &Info) override;
1448   void clear() override;
1449
1450   bool IncludeInDiagnosticCounts() const override;
1451 };
1452
1453 // Struct used for sending info about how a type should be printed.
1454 struct TemplateDiffTypes {
1455   intptr_t FromType;
1456   intptr_t ToType;
1457   unsigned PrintTree : 1;
1458   unsigned PrintFromType : 1;
1459   unsigned ElideType : 1;
1460   unsigned ShowColors : 1;
1461   // The printer sets this variable to true if the template diff was used.
1462   unsigned TemplateDiffUsed : 1;
1463 };
1464
1465 /// Special character that the diagnostic printer will use to toggle the bold
1466 /// attribute.  The character itself will be not be printed.
1467 const char ToggleHighlight = 127;
1468
1469
1470 /// ProcessWarningOptions - Initialize the diagnostic client and process the
1471 /// warning options specified on the command line.
1472 void ProcessWarningOptions(DiagnosticsEngine &Diags,
1473                            const DiagnosticOptions &Opts,
1474                            bool ReportDiags = true);
1475
1476 } // end namespace clang
1477
1478 #endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H