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