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