Thanks to visit codestin.com
Credit goes to clang.llvm.org

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