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