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