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