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