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