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