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