File indexing completed on 2026-05-10 08:36:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_H
0015 #define LLVM_CLANG_BASIC_DIAGNOSTIC_H
0016
0017 #include "clang/Basic/DiagnosticIDs.h"
0018 #include "clang/Basic/DiagnosticOptions.h"
0019 #include "clang/Basic/SourceLocation.h"
0020 #include "clang/Basic/Specifiers.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 #include "llvm/ADT/DenseMap.h"
0023 #include "llvm/ADT/FunctionExtras.h"
0024 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/ADT/iterator_range.h"
0027 #include "llvm/Support/Compiler.h"
0028 #include <cassert>
0029 #include <cstdint>
0030 #include <limits>
0031 #include <list>
0032 #include <map>
0033 #include <memory>
0034 #include <optional>
0035 #include <string>
0036 #include <type_traits>
0037 #include <utility>
0038 #include <vector>
0039
0040 namespace llvm {
0041 class Error;
0042 class raw_ostream;
0043 class MemoryBuffer;
0044 namespace vfs {
0045 class FileSystem;
0046 }
0047 }
0048
0049 namespace clang {
0050
0051 class DeclContext;
0052 class DiagnosticBuilder;
0053 class DiagnosticConsumer;
0054 class IdentifierInfo;
0055 class LangOptions;
0056 class Preprocessor;
0057 class SourceManager;
0058 class StoredDiagnostic;
0059
0060 namespace tok {
0061
0062 enum TokenKind : unsigned short;
0063
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 class FixItHint {
0076 public:
0077
0078
0079 CharSourceRange RemoveRange;
0080
0081
0082
0083 CharSourceRange InsertFromRange;
0084
0085
0086
0087 std::string CodeToInsert;
0088
0089 bool BeforePreviousInsertions = false;
0090
0091
0092
0093 FixItHint() = default;
0094
0095 bool isNull() const {
0096 return !RemoveRange.isValid();
0097 }
0098
0099
0100
0101 static FixItHint CreateInsertion(SourceLocation InsertionLoc,
0102 StringRef Code,
0103 bool BeforePreviousInsertions = false) {
0104 FixItHint Hint;
0105 Hint.RemoveRange =
0106 CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
0107 Hint.CodeToInsert = std::string(Code);
0108 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
0109 return Hint;
0110 }
0111
0112
0113
0114 static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
0115 CharSourceRange FromRange,
0116 bool BeforePreviousInsertions = false) {
0117 FixItHint Hint;
0118 Hint.RemoveRange =
0119 CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
0120 Hint.InsertFromRange = FromRange;
0121 Hint.BeforePreviousInsertions = BeforePreviousInsertions;
0122 return Hint;
0123 }
0124
0125
0126
0127 static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
0128 FixItHint Hint;
0129 Hint.RemoveRange = RemoveRange;
0130 return Hint;
0131 }
0132 static FixItHint CreateRemoval(SourceRange RemoveRange) {
0133 return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
0134 }
0135
0136
0137
0138 static FixItHint CreateReplacement(CharSourceRange RemoveRange,
0139 StringRef Code) {
0140 FixItHint Hint;
0141 Hint.RemoveRange = RemoveRange;
0142 Hint.CodeToInsert = std::string(Code);
0143 return Hint;
0144 }
0145
0146 static FixItHint CreateReplacement(SourceRange RemoveRange,
0147 StringRef Code) {
0148 return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
0149 }
0150 };
0151
0152 struct DiagnosticStorage {
0153 enum {
0154
0155
0156
0157
0158
0159 MaxArguments = 10
0160 };
0161
0162
0163 unsigned char NumDiagArgs = 0;
0164
0165
0166
0167 unsigned char DiagArgumentsKind[MaxArguments];
0168
0169
0170
0171
0172
0173
0174 uint64_t DiagArgumentsVal[MaxArguments];
0175
0176
0177
0178 std::string DiagArgumentsStr[MaxArguments];
0179
0180
0181 SmallVector<CharSourceRange, 8> DiagRanges;
0182
0183
0184
0185 SmallVector<FixItHint, 6> FixItHints;
0186
0187 DiagnosticStorage() = default;
0188 };
0189
0190
0191
0192 class DiagStorageAllocator {
0193 static const unsigned NumCached = 16;
0194 DiagnosticStorage Cached[NumCached];
0195 DiagnosticStorage *FreeList[NumCached];
0196 unsigned NumFreeListEntries;
0197
0198 public:
0199 DiagStorageAllocator();
0200 ~DiagStorageAllocator();
0201
0202
0203 DiagnosticStorage *Allocate() {
0204 if (NumFreeListEntries == 0)
0205 return new DiagnosticStorage;
0206
0207 DiagnosticStorage *Result = FreeList[--NumFreeListEntries];
0208 Result->NumDiagArgs = 0;
0209 Result->DiagRanges.clear();
0210 Result->FixItHints.clear();
0211 return Result;
0212 }
0213
0214
0215 void Deallocate(DiagnosticStorage *S) {
0216 if (S >= Cached && S <= Cached + NumCached) {
0217 FreeList[NumFreeListEntries++] = S;
0218 return;
0219 }
0220
0221 delete S;
0222 }
0223 };
0224
0225
0226
0227
0228
0229
0230
0231 class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
0232 public:
0233
0234 enum Level {
0235 Ignored = DiagnosticIDs::Ignored,
0236 Note = DiagnosticIDs::Note,
0237 Remark = DiagnosticIDs::Remark,
0238 Warning = DiagnosticIDs::Warning,
0239 Error = DiagnosticIDs::Error,
0240 Fatal = DiagnosticIDs::Fatal
0241 };
0242
0243 enum ArgumentKind {
0244
0245 ak_std_string,
0246
0247
0248 ak_c_string,
0249
0250
0251 ak_sint,
0252
0253
0254 ak_uint,
0255
0256
0257 ak_tokenkind,
0258
0259
0260 ak_identifierinfo,
0261
0262
0263 ak_addrspace,
0264
0265
0266 ak_qual,
0267
0268
0269 ak_qualtype,
0270
0271
0272 ak_declarationname,
0273
0274
0275 ak_nameddecl,
0276
0277
0278 ak_nestednamespec,
0279
0280
0281 ak_declcontext,
0282
0283
0284 ak_qualtype_pair,
0285
0286
0287 ak_attr
0288 };
0289
0290
0291
0292 using ArgumentValue = std::pair<ArgumentKind, intptr_t>;
0293
0294 private:
0295
0296 unsigned char AllExtensionsSilenced = 0;
0297
0298
0299 bool FatalsAsError = false;
0300
0301
0302 bool SuppressAllDiagnostics = false;
0303
0304
0305 bool ElideType = true;
0306
0307
0308 bool PrintTemplateTree = false;
0309
0310
0311 bool ShowColors = false;
0312
0313
0314 OverloadsShown ShowOverloads = Ovl_All;
0315
0316
0317
0318
0319
0320
0321 unsigned NumOverloadsToShow = 32;
0322
0323
0324 unsigned ErrorLimit = 0;
0325
0326
0327 unsigned TemplateBacktraceLimit = 0;
0328
0329
0330 unsigned ConstexprBacktraceLimit = 0;
0331
0332 IntrusiveRefCntPtr<DiagnosticIDs> Diags;
0333 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
0334 DiagnosticConsumer *Client = nullptr;
0335 std::unique_ptr<DiagnosticConsumer> Owner;
0336 SourceManager *SourceMgr = nullptr;
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 class DiagState {
0350 llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
0351
0352 public:
0353
0354
0355
0356 LLVM_PREFERRED_TYPE(bool)
0357 unsigned IgnoreAllWarnings : 1;
0358
0359
0360 LLVM_PREFERRED_TYPE(bool)
0361 unsigned EnableAllWarnings : 1;
0362
0363
0364 LLVM_PREFERRED_TYPE(bool)
0365 unsigned WarningsAsErrors : 1;
0366
0367
0368 LLVM_PREFERRED_TYPE(bool)
0369 unsigned ErrorsAsFatal : 1;
0370
0371
0372 LLVM_PREFERRED_TYPE(bool)
0373 unsigned SuppressSystemWarnings : 1;
0374
0375
0376 diag::Severity ExtBehavior = diag::Severity::Ignored;
0377
0378 DiagnosticIDs &DiagIDs;
0379
0380 DiagState(DiagnosticIDs &DiagIDs)
0381 : IgnoreAllWarnings(false), EnableAllWarnings(false),
0382 WarningsAsErrors(false), ErrorsAsFatal(false),
0383 SuppressSystemWarnings(false), DiagIDs(DiagIDs) {}
0384
0385 using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
0386 using const_iterator =
0387 llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator;
0388
0389 void setMapping(diag::kind Diag, DiagnosticMapping Info) {
0390 DiagMap[Diag] = Info;
0391 }
0392
0393 DiagnosticMapping lookupMapping(diag::kind Diag) const {
0394 return DiagMap.lookup(Diag);
0395 }
0396
0397 DiagnosticMapping &getOrAddMapping(diag::kind Diag);
0398
0399 const_iterator begin() const { return DiagMap.begin(); }
0400 const_iterator end() const { return DiagMap.end(); }
0401 };
0402
0403
0404 std::list<DiagState> DiagStates;
0405
0406
0407
0408 class DiagStateMap {
0409 public:
0410
0411 void appendFirst(DiagState *State);
0412
0413
0414 void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
0415
0416
0417 DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
0418
0419
0420 bool empty() const { return Files.empty(); }
0421
0422
0423 void clear() {
0424 Files.clear();
0425 FirstDiagState = CurDiagState = nullptr;
0426 CurDiagStateLoc = SourceLocation();
0427 }
0428
0429
0430 LLVM_DUMP_METHOD void dump(SourceManager &SrcMgr,
0431 StringRef DiagName = StringRef()) const;
0432
0433
0434 DiagState *getCurDiagState() const { return CurDiagState; }
0435
0436
0437 SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
0438
0439 private:
0440 friend class ASTReader;
0441 friend class ASTWriter;
0442
0443
0444
0445
0446
0447
0448 struct DiagStatePoint {
0449 DiagState *State;
0450 unsigned Offset;
0451
0452 DiagStatePoint(DiagState *State, unsigned Offset)
0453 : State(State), Offset(Offset) {}
0454 };
0455
0456
0457
0458 struct File {
0459
0460
0461
0462 File *Parent = nullptr;
0463
0464
0465 unsigned ParentOffset = 0;
0466
0467
0468
0469 bool HasLocalTransitions = false;
0470
0471
0472
0473 llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
0474
0475 DiagState *lookup(unsigned Offset) const;
0476 };
0477
0478
0479 mutable std::map<FileID, File> Files;
0480
0481
0482 DiagState *FirstDiagState;
0483
0484
0485 DiagState *CurDiagState;
0486
0487
0488 SourceLocation CurDiagStateLoc;
0489
0490
0491 File *getFile(SourceManager &SrcMgr, FileID ID) const;
0492 };
0493
0494 DiagStateMap DiagStatesByLoc;
0495
0496
0497
0498 std::vector<DiagState *> DiagStateOnPushStack;
0499
0500 DiagState *GetCurDiagState() const {
0501 return DiagStatesByLoc.getCurDiagState();
0502 }
0503
0504 void PushDiagStatePoint(DiagState *State, SourceLocation L);
0505
0506
0507
0508 DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
0509 return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
0510 : DiagStatesByLoc.getCurDiagState();
0511 }
0512
0513
0514 bool ErrorOccurred;
0515
0516
0517
0518 bool UncompilableErrorOccurred;
0519
0520
0521 bool FatalErrorOccurred;
0522
0523
0524 bool UnrecoverableErrorOccurred;
0525
0526
0527
0528 unsigned TrapNumErrorsOccurred;
0529 unsigned TrapNumUnrecoverableErrorsOccurred;
0530
0531
0532
0533
0534
0535 DiagnosticIDs::Level LastDiagLevel;
0536
0537
0538 unsigned NumWarnings;
0539
0540
0541 unsigned NumErrors;
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553 using ArgToStringFnTy = void (*)(
0554 ArgumentKind Kind, intptr_t Val,
0555 StringRef Modifier, StringRef Argument,
0556 ArrayRef<ArgumentValue> PrevArgs,
0557 SmallVectorImpl<char> &Output,
0558 void *Cookie,
0559 ArrayRef<intptr_t> QualTypeVals);
0560
0561 void *ArgToStringCookie = nullptr;
0562 ArgToStringFnTy ArgToStringFn;
0563
0564
0565 llvm::unique_function<bool(diag::kind, SourceLocation ,
0566 const SourceManager &) const>
0567 DiagSuppressionMapping;
0568
0569 public:
0570 explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
0571 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
0572 DiagnosticConsumer *client = nullptr,
0573 bool ShouldOwnClient = true);
0574 DiagnosticsEngine(const DiagnosticsEngine &) = delete;
0575 DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
0576 ~DiagnosticsEngine();
0577
0578 friend void DiagnosticsTestHelper(DiagnosticsEngine &);
0579 LLVM_DUMP_METHOD void dump() const;
0580 LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
0581
0582 const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
0583 return Diags;
0584 }
0585
0586
0587 DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
0588
0589 using diag_mapping_range = llvm::iterator_range<DiagState::const_iterator>;
0590
0591
0592 diag_mapping_range getDiagnosticMappings() const {
0593 const DiagState &DS = *GetCurDiagState();
0594 return diag_mapping_range(DS.begin(), DS.end());
0595 }
0596
0597 DiagnosticConsumer *getClient() { return Client; }
0598 const DiagnosticConsumer *getClient() const { return Client; }
0599
0600
0601 bool ownsClient() const { return Owner != nullptr; }
0602
0603
0604
0605 std::unique_ptr<DiagnosticConsumer> takeClient() { return std::move(Owner); }
0606
0607 bool hasSourceManager() const { return SourceMgr != nullptr; }
0608
0609 SourceManager &getSourceManager() const {
0610 assert(SourceMgr && "SourceManager not set!");
0611 return *SourceMgr;
0612 }
0613
0614 void setSourceManager(SourceManager *SrcMgr) {
0615 assert(DiagStatesByLoc.empty() &&
0616 "Leftover diag state from a different SourceManager.");
0617 SourceMgr = SrcMgr;
0618 }
0619
0620
0621
0622
0623
0624
0625
0626
0627 void pushMappings(SourceLocation Loc);
0628
0629
0630
0631
0632
0633
0634 bool popMappings(SourceLocation Loc);
0635
0636
0637
0638
0639
0640 void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
0641
0642
0643
0644
0645
0646 void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
0647
0648
0649
0650 void setTemplateBacktraceLimit(unsigned Limit) {
0651 TemplateBacktraceLimit = Limit;
0652 }
0653
0654
0655
0656 unsigned getTemplateBacktraceLimit() const {
0657 return TemplateBacktraceLimit;
0658 }
0659
0660
0661
0662 void setConstexprBacktraceLimit(unsigned Limit) {
0663 ConstexprBacktraceLimit = Limit;
0664 }
0665
0666
0667
0668 unsigned getConstexprBacktraceLimit() const {
0669 return ConstexprBacktraceLimit;
0670 }
0671
0672
0673
0674
0675 void setIgnoreAllWarnings(bool Val) {
0676 GetCurDiagState()->IgnoreAllWarnings = Val;
0677 }
0678 bool getIgnoreAllWarnings() const {
0679 return GetCurDiagState()->IgnoreAllWarnings;
0680 }
0681
0682
0683
0684
0685
0686 void setEnableAllWarnings(bool Val) {
0687 GetCurDiagState()->EnableAllWarnings = Val;
0688 }
0689 bool getEnableAllWarnings() const {
0690 return GetCurDiagState()->EnableAllWarnings;
0691 }
0692
0693
0694 void setWarningsAsErrors(bool Val) {
0695 GetCurDiagState()->WarningsAsErrors = Val;
0696 }
0697 bool getWarningsAsErrors() const {
0698 return GetCurDiagState()->WarningsAsErrors;
0699 }
0700
0701
0702 void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
0703 bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
0704
0705
0706
0707
0708 void setFatalsAsError(bool Val) { FatalsAsError = Val; }
0709 bool getFatalsAsError() const { return FatalsAsError; }
0710
0711
0712 void setSuppressSystemWarnings(bool Val) {
0713 GetCurDiagState()->SuppressSystemWarnings = Val;
0714 }
0715 bool getSuppressSystemWarnings() const {
0716 return GetCurDiagState()->SuppressSystemWarnings;
0717 }
0718
0719
0720
0721
0722 void setSuppressAllDiagnostics(bool Val) { SuppressAllDiagnostics = Val; }
0723 bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
0724
0725
0726
0727 void setElideType(bool Val) { ElideType = Val; }
0728 bool getElideType() { return ElideType; }
0729
0730
0731
0732 void setPrintTemplateTree(bool Val) { PrintTemplateTree = Val; }
0733 bool getPrintTemplateTree() { return PrintTemplateTree; }
0734
0735
0736
0737 void setShowColors(bool Val) { ShowColors = Val; }
0738 bool getShowColors() { return ShowColors; }
0739
0740
0741
0742
0743
0744 void setShowOverloads(OverloadsShown Val) {
0745 ShowOverloads = Val;
0746 }
0747 OverloadsShown getShowOverloads() const { return ShowOverloads; }
0748
0749
0750
0751
0752
0753
0754
0755
0756 unsigned getNumOverloadCandidatesToShow() const {
0757 switch (getShowOverloads()) {
0758 case Ovl_All:
0759
0760
0761
0762 return std::numeric_limits<int>::max();
0763 case Ovl_Best:
0764 return NumOverloadsToShow;
0765 }
0766 llvm_unreachable("invalid OverloadsShown kind");
0767 }
0768
0769
0770
0771 void overloadCandidatesShown(unsigned N) {
0772
0773
0774
0775 if (N > 4) {
0776 NumOverloadsToShow = 4;
0777 }
0778 }
0779
0780
0781
0782
0783
0784
0785
0786 void setLastDiagnosticIgnored(bool Ignored) {
0787 if (LastDiagLevel == DiagnosticIDs::Fatal)
0788 FatalErrorOccurred = true;
0789 LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
0790 }
0791
0792
0793
0794
0795 bool isLastDiagnosticIgnored() const {
0796 return LastDiagLevel == DiagnosticIDs::Ignored;
0797 }
0798
0799
0800
0801
0802
0803 void setExtensionHandlingBehavior(diag::Severity H) {
0804 GetCurDiagState()->ExtBehavior = H;
0805 }
0806 diag::Severity getExtensionHandlingBehavior() const {
0807 return GetCurDiagState()->ExtBehavior;
0808 }
0809
0810
0811
0812
0813
0814 void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
0815 void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
0816 bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826 void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839 bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
0840 diag::Severity Map,
0841 SourceLocation Loc = SourceLocation());
0842 bool setSeverityForGroup(diag::Flavor Flavor, diag::Group Group,
0843 diag::Severity Map,
0844 SourceLocation Loc = SourceLocation());
0845
0846
0847
0848
0849
0850
0851 bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
0852
0853
0854
0855
0856
0857
0858 bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
0859
0860
0861
0862
0863
0864
0865 void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
0866 SourceLocation Loc = SourceLocation());
0867
0868 bool hasErrorOccurred() const { return ErrorOccurred; }
0869
0870
0871
0872 bool hasUncompilableErrorOccurred() const {
0873 return UncompilableErrorOccurred;
0874 }
0875 bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
0876
0877
0878 bool hasUnrecoverableErrorOccurred() const {
0879 return FatalErrorOccurred || UnrecoverableErrorOccurred;
0880 }
0881
0882 unsigned getNumErrors() const { return NumErrors; }
0883 unsigned getNumWarnings() const { return NumWarnings; }
0884
0885 void setNumWarnings(unsigned NumWarnings) {
0886 this->NumWarnings = NumWarnings;
0887 }
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897 template <unsigned N>
0898
0899
0900 unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
0901 return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
0902 StringRef(FormatString, N - 1));
0903 }
0904
0905
0906
0907 void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
0908 StringRef Modifier, StringRef Argument,
0909 ArrayRef<ArgumentValue> PrevArgs,
0910 SmallVectorImpl<char> &Output,
0911 ArrayRef<intptr_t> QualTypeVals) const {
0912 ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
0913 ArgToStringCookie, QualTypeVals);
0914 }
0915
0916 void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
0917 ArgToStringFn = Fn;
0918 ArgToStringCookie = Cookie;
0919 }
0920
0921
0922
0923 void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
0924 LastDiagLevel = Other.LastDiagLevel;
0925 }
0926
0927
0928
0929 void Reset(bool soft = false);
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943 bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
0944 return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
0945 diag::Severity::Ignored;
0946 }
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958 Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
0959 return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
0960 }
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979 void setDiagSuppressionMapping(llvm::MemoryBuffer &Input);
0980 bool isSuppressedViaMapping(diag::kind DiagId, SourceLocation DiagLoc) const;
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990 inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
0991 inline DiagnosticBuilder Report(unsigned DiagID);
0992
0993 void Report(const StoredDiagnostic &storedDiag);
0994
0995 private:
0996
0997
0998
0999
1000
1001 friend class Diagnostic;
1002 friend class DiagnosticBuilder;
1003 friend class DiagnosticErrorTrap;
1004 friend class DiagnosticIDs;
1005 friend class PartialDiagnostic;
1006
1007 enum {
1008
1009
1010
1011
1012
1013 MaxArguments = DiagnosticStorage::MaxArguments,
1014 };
1015
1016 DiagStorageAllocator DiagAllocator;
1017
1018 DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
1019 bool isPragma = L.isValid();
1020 DiagnosticMapping Mapping =
1021 DiagnosticMapping::Make(Map, true, isPragma);
1022
1023
1024
1025 if (isPragma) {
1026 Mapping.setNoWarningAsError(true);
1027 Mapping.setNoErrorAsFatal(true);
1028 }
1029
1030 return Mapping;
1031 }
1032
1033
1034
1035
1036 bool ProcessDiag(const DiagnosticBuilder &DiagBuilder) {
1037 return Diags->ProcessDiag(*this, DiagBuilder);
1038 }
1039
1040
1041
1042 protected:
1043 friend class ASTReader;
1044 friend class ASTWriter;
1045
1046
1047
1048
1049
1050 friend class Sema;
1051
1052
1053
1054
1055 bool EmitDiagnostic(const DiagnosticBuilder &DB, bool Force = false);
1056
1057
1058 };
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068 class DiagnosticErrorTrap {
1069 DiagnosticsEngine &Diag;
1070 unsigned NumErrors;
1071 unsigned NumUnrecoverableErrors;
1072
1073 public:
1074 explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
1075 : Diag(Diag) { reset(); }
1076
1077
1078
1079 bool hasErrorOccurred() const {
1080 return Diag.TrapNumErrorsOccurred > NumErrors;
1081 }
1082
1083
1084
1085 bool hasUnrecoverableErrorOccurred() const {
1086 return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
1087 }
1088
1089
1090 void reset() {
1091 NumErrors = Diag.TrapNumErrorsOccurred;
1092 NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
1093 }
1094 };
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106 class StreamingDiagnostic {
1107 public:
1108 using DiagStorageAllocator = clang::DiagStorageAllocator;
1109
1110 protected:
1111 mutable DiagnosticStorage *DiagStorage = nullptr;
1112
1113
1114 DiagStorageAllocator *Allocator = nullptr;
1115
1116 public:
1117
1118 DiagnosticStorage *getStorage() const {
1119 if (DiagStorage)
1120 return DiagStorage;
1121
1122 assert(Allocator);
1123 DiagStorage = Allocator->Allocate();
1124 return DiagStorage;
1125 }
1126
1127 void freeStorage() {
1128 if (!DiagStorage)
1129 return;
1130
1131
1132
1133
1134
1135
1136
1137 freeStorageSlow();
1138 }
1139
1140 void freeStorageSlow() {
1141 if (!Allocator)
1142 return;
1143 Allocator->Deallocate(DiagStorage);
1144 DiagStorage = nullptr;
1145 }
1146
1147 void AddTaggedVal(uint64_t V, DiagnosticsEngine::ArgumentKind Kind) const {
1148 if (!DiagStorage)
1149 DiagStorage = getStorage();
1150
1151 assert(DiagStorage->NumDiagArgs < DiagnosticStorage::MaxArguments &&
1152 "Too many arguments to diagnostic!");
1153 DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
1154 DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
1155 }
1156
1157 void AddString(StringRef V) const {
1158 if (!DiagStorage)
1159 DiagStorage = getStorage();
1160
1161 assert(DiagStorage->NumDiagArgs < DiagnosticStorage::MaxArguments &&
1162 "Too many arguments to diagnostic!");
1163 DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] =
1164 DiagnosticsEngine::ak_std_string;
1165 DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = std::string(V);
1166 }
1167
1168 void AddSourceRange(const CharSourceRange &R) const {
1169 if (!DiagStorage)
1170 DiagStorage = getStorage();
1171
1172 DiagStorage->DiagRanges.push_back(R);
1173 }
1174
1175 void AddFixItHint(const FixItHint &Hint) const {
1176 if (Hint.isNull())
1177 return;
1178
1179 if (!DiagStorage)
1180 DiagStorage = getStorage();
1181
1182 DiagStorage->FixItHints.push_back(Hint);
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192 operator bool() const { return true; }
1193
1194 protected:
1195 StreamingDiagnostic() = default;
1196
1197
1198
1199 explicit StreamingDiagnostic(DiagStorageAllocator &Alloc)
1200 : Allocator(&Alloc) {}
1201
1202 StreamingDiagnostic(const StreamingDiagnostic &Diag) = default;
1203 StreamingDiagnostic(StreamingDiagnostic &&Diag) = default;
1204
1205 ~StreamingDiagnostic() { freeStorage(); }
1206 };
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224 class DiagnosticBuilder : public StreamingDiagnostic {
1225 friend class DiagnosticsEngine;
1226 friend class PartialDiagnostic;
1227 friend class Diagnostic;
1228
1229 mutable DiagnosticsEngine *DiagObj = nullptr;
1230
1231 SourceLocation DiagLoc;
1232 unsigned DiagID;
1233
1234
1235
1236
1237
1238
1239 mutable std::string FlagValue;
1240
1241
1242
1243
1244
1245
1246 mutable bool IsActive = false;
1247
1248
1249
1250 mutable bool IsForceEmit = false;
1251
1252 DiagnosticBuilder() = default;
1253
1254 DiagnosticBuilder(DiagnosticsEngine *DiagObj, SourceLocation DiagLoc,
1255 unsigned DiagID);
1256
1257 protected:
1258
1259 void Clear() const {
1260 DiagObj = nullptr;
1261 IsActive = false;
1262 IsForceEmit = false;
1263 }
1264
1265
1266 bool isActive() const { return IsActive; }
1267
1268
1269
1270
1271
1272
1273
1274
1275 bool Emit() {
1276
1277
1278 if (!isActive()) return false;
1279
1280
1281 bool Result = DiagObj->EmitDiagnostic(*this, IsForceEmit);
1282
1283
1284 Clear();
1285
1286 return Result;
1287 }
1288
1289 public:
1290
1291
1292 DiagnosticBuilder(const DiagnosticBuilder &D);
1293
1294 template <typename T> const DiagnosticBuilder &operator<<(const T &V) const {
1295 assert(isActive() && "Clients must not add to cleared diagnostic!");
1296 const StreamingDiagnostic &DB = *this;
1297 DB << V;
1298 return *this;
1299 }
1300
1301
1302
1303
1304 template <typename T,
1305 typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
1306 const DiagnosticBuilder &operator<<(T &&V) const {
1307 assert(isActive() && "Clients must not add to cleared diagnostic!");
1308 const StreamingDiagnostic &DB = *this;
1309 DB << std::move(V);
1310 return *this;
1311 }
1312
1313 DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
1314
1315
1316 ~DiagnosticBuilder() { Emit(); }
1317
1318
1319 const DiagnosticBuilder &setForceEmit() const {
1320 IsForceEmit = true;
1321 return *this;
1322 }
1323
1324 void addFlagValue(StringRef V) const { FlagValue = std::string(V); }
1325 };
1326
1327 struct AddFlagValue {
1328 StringRef Val;
1329
1330 explicit AddFlagValue(StringRef V) : Val(V) {}
1331 };
1332
1333
1334
1335
1336
1337 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
1338 const AddFlagValue V) {
1339 DB.addFlagValue(V.Val);
1340 return DB;
1341 }
1342
1343 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1344 StringRef S) {
1345 DB.AddString(S);
1346 return DB;
1347 }
1348
1349 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1350 const char *Str) {
1351 DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
1352 DiagnosticsEngine::ak_c_string);
1353 return DB;
1354 }
1355
1356 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1357 int I) {
1358 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1359 return DB;
1360 }
1361
1362 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1363 long I) {
1364 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1365 return DB;
1366 }
1367
1368 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1369 long long I) {
1370 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1371 return DB;
1372 }
1373
1374
1375
1376 template <typename T>
1377 inline std::enable_if_t<std::is_same<T, bool>::value,
1378 const StreamingDiagnostic &>
1379 operator<<(const StreamingDiagnostic &DB, T I) {
1380 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
1381 return DB;
1382 }
1383
1384 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1385 unsigned I) {
1386 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1387 return DB;
1388 }
1389
1390 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1391 unsigned long I) {
1392 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1393 return DB;
1394 }
1395
1396 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1397 unsigned long long I) {
1398 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
1399 return DB;
1400 }
1401
1402 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1403 tok::TokenKind I) {
1404 DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
1405 return DB;
1406 }
1407
1408 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1409 const IdentifierInfo *II) {
1410 DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
1411 DiagnosticsEngine::ak_identifierinfo);
1412 return DB;
1413 }
1414
1415
1416
1417
1418
1419 template <typename T>
1420 inline std::enable_if_t<
1421 std::is_same<std::remove_const_t<T>, DeclContext>::value,
1422 const StreamingDiagnostic &>
1423 operator<<(const StreamingDiagnostic &DB, T *DC) {
1424 DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
1425 DiagnosticsEngine::ak_declcontext);
1426 return DB;
1427 }
1428
1429 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1430 SourceLocation L) {
1431 DB.AddSourceRange(CharSourceRange::getTokenRange(L));
1432 return DB;
1433 }
1434
1435 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1436 SourceRange R) {
1437 DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1438 return DB;
1439 }
1440
1441 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1442 ArrayRef<SourceRange> Ranges) {
1443 for (SourceRange R : Ranges)
1444 DB.AddSourceRange(CharSourceRange::getTokenRange(R));
1445 return DB;
1446 }
1447
1448 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1449 const CharSourceRange &R) {
1450 DB.AddSourceRange(R);
1451 return DB;
1452 }
1453
1454 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1455 const FixItHint &Hint) {
1456 DB.AddFixItHint(Hint);
1457 return DB;
1458 }
1459
1460 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1461 ArrayRef<FixItHint> Hints) {
1462 for (const FixItHint &Hint : Hints)
1463 DB.AddFixItHint(Hint);
1464 return DB;
1465 }
1466
1467 inline const StreamingDiagnostic &
1468 operator<<(const StreamingDiagnostic &DB,
1469 const std::optional<SourceRange> &Opt) {
1470 if (Opt)
1471 DB << *Opt;
1472 return DB;
1473 }
1474
1475 inline const StreamingDiagnostic &
1476 operator<<(const StreamingDiagnostic &DB,
1477 const std::optional<CharSourceRange> &Opt) {
1478 if (Opt)
1479 DB << *Opt;
1480 return DB;
1481 }
1482
1483 inline const StreamingDiagnostic &
1484 operator<<(const StreamingDiagnostic &DB, const std::optional<FixItHint> &Opt) {
1485 if (Opt)
1486 DB << *Opt;
1487 return DB;
1488 }
1489
1490
1491
1492 using DiagNullabilityKind = std::pair<NullabilityKind, bool>;
1493
1494 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1495 DiagNullabilityKind nullability);
1496
1497 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
1498 unsigned DiagID) {
1499 return DiagnosticBuilder(this, Loc, DiagID);
1500 }
1501
1502 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1503 llvm::Error &&E);
1504
1505 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
1506 return Report(SourceLocation(), DiagID);
1507 }
1508
1509
1510
1511
1512
1513
1514
1515
1516 class Diagnostic {
1517 const DiagnosticsEngine *DiagObj;
1518 SourceLocation DiagLoc;
1519 unsigned DiagID;
1520 std::string FlagValue;
1521 const DiagnosticStorage &DiagStorage;
1522 std::optional<StringRef> StoredDiagMessage;
1523
1524 public:
1525 Diagnostic(const DiagnosticsEngine *DO, const DiagnosticBuilder &DiagBuilder);
1526 Diagnostic(const DiagnosticsEngine *DO, SourceLocation DiagLoc,
1527 unsigned DiagID, const DiagnosticStorage &DiagStorage,
1528 StringRef StoredDiagMessage);
1529
1530 const DiagnosticsEngine *getDiags() const { return DiagObj; }
1531 unsigned getID() const { return DiagID; }
1532 const SourceLocation &getLocation() const { return DiagLoc; }
1533 bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
1534 SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
1535
1536 unsigned getNumArgs() const { return DiagStorage.NumDiagArgs; }
1537
1538
1539
1540
1541
1542
1543
1544 DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
1545 assert(Idx < getNumArgs() && "Argument index out of range!");
1546 return (DiagnosticsEngine::ArgumentKind)DiagStorage.DiagArgumentsKind[Idx];
1547 }
1548
1549
1550
1551 const std::string &getArgStdStr(unsigned Idx) const {
1552 assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
1553 "invalid argument accessor!");
1554 return DiagStorage.DiagArgumentsStr[Idx];
1555 }
1556
1557
1558
1559 const char *getArgCStr(unsigned Idx) const {
1560 assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
1561 "invalid argument accessor!");
1562 return reinterpret_cast<const char *>(DiagStorage.DiagArgumentsVal[Idx]);
1563 }
1564
1565
1566
1567 int64_t getArgSInt(unsigned Idx) const {
1568 assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
1569 "invalid argument accessor!");
1570 return (int64_t)DiagStorage.DiagArgumentsVal[Idx];
1571 }
1572
1573
1574
1575 uint64_t getArgUInt(unsigned Idx) const {
1576 assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
1577 "invalid argument accessor!");
1578 return DiagStorage.DiagArgumentsVal[Idx];
1579 }
1580
1581
1582
1583 const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
1584 assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
1585 "invalid argument accessor!");
1586 return reinterpret_cast<IdentifierInfo *>(
1587 DiagStorage.DiagArgumentsVal[Idx]);
1588 }
1589
1590
1591
1592 uint64_t getRawArg(unsigned Idx) const {
1593 assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
1594 "invalid argument accessor!");
1595 return DiagStorage.DiagArgumentsVal[Idx];
1596 }
1597
1598
1599 unsigned getNumRanges() const { return DiagStorage.DiagRanges.size(); }
1600
1601
1602 const CharSourceRange &getRange(unsigned Idx) const {
1603 assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
1604 return DiagStorage.DiagRanges[Idx];
1605 }
1606
1607
1608 ArrayRef<CharSourceRange> getRanges() const { return DiagStorage.DiagRanges; }
1609
1610 unsigned getNumFixItHints() const { return DiagStorage.FixItHints.size(); }
1611
1612 const FixItHint &getFixItHint(unsigned Idx) const {
1613 assert(Idx < getNumFixItHints() && "Invalid index!");
1614 return DiagStorage.FixItHints[Idx];
1615 }
1616
1617 ArrayRef<FixItHint> getFixItHints() const { return DiagStorage.FixItHints; }
1618
1619
1620 StringRef getFlagValue() const { return FlagValue; }
1621
1622
1623
1624
1625
1626 void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
1627
1628
1629
1630 void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
1631 SmallVectorImpl<char> &OutStr) const;
1632 };
1633
1634
1635
1636
1637
1638 class StoredDiagnostic {
1639 unsigned ID;
1640 DiagnosticsEngine::Level Level;
1641 FullSourceLoc Loc;
1642 std::string Message;
1643 std::vector<CharSourceRange> Ranges;
1644 std::vector<FixItHint> FixIts;
1645
1646 public:
1647 StoredDiagnostic() = default;
1648 StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
1649 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1650 StringRef Message);
1651 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
1652 StringRef Message, FullSourceLoc Loc,
1653 ArrayRef<CharSourceRange> Ranges,
1654 ArrayRef<FixItHint> Fixits);
1655
1656
1657 explicit operator bool() const { return !Message.empty(); }
1658
1659 unsigned getID() const { return ID; }
1660 DiagnosticsEngine::Level getLevel() const { return Level; }
1661 const FullSourceLoc &getLocation() const { return Loc; }
1662 StringRef getMessage() const { return Message; }
1663
1664 void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
1665
1666 using range_iterator = std::vector<CharSourceRange>::const_iterator;
1667
1668 range_iterator range_begin() const { return Ranges.begin(); }
1669 range_iterator range_end() const { return Ranges.end(); }
1670 unsigned range_size() const { return Ranges.size(); }
1671
1672 ArrayRef<CharSourceRange> getRanges() const { return llvm::ArrayRef(Ranges); }
1673
1674 using fixit_iterator = std::vector<FixItHint>::const_iterator;
1675
1676 fixit_iterator fixit_begin() const { return FixIts.begin(); }
1677 fixit_iterator fixit_end() const { return FixIts.end(); }
1678 unsigned fixit_size() const { return FixIts.size(); }
1679
1680 ArrayRef<FixItHint> getFixIts() const { return llvm::ArrayRef(FixIts); }
1681 };
1682
1683
1684 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StoredDiagnostic &);
1685
1686
1687
1688 class DiagnosticConsumer {
1689 protected:
1690 unsigned NumWarnings = 0;
1691 unsigned NumErrors = 0;
1692
1693 public:
1694 DiagnosticConsumer() = default;
1695 virtual ~DiagnosticConsumer();
1696
1697 unsigned getNumErrors() const { return NumErrors; }
1698 unsigned getNumWarnings() const { return NumWarnings; }
1699 virtual void clear() { NumWarnings = NumErrors = 0; }
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 virtual void BeginSourceFile(const LangOptions &LangOpts,
1713 const Preprocessor *PP = nullptr) {}
1714
1715
1716
1717
1718
1719
1720 virtual void EndSourceFile() {}
1721
1722
1723
1724 virtual void finish() {}
1725
1726
1727
1728
1729
1730
1731 virtual bool IncludeInDiagnosticCounts() const;
1732
1733
1734
1735
1736
1737
1738 virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1739 const Diagnostic &Info);
1740 };
1741
1742
1743 class IgnoringDiagConsumer : public DiagnosticConsumer {
1744 virtual void anchor();
1745
1746 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1747 const Diagnostic &Info) override {
1748
1749 }
1750 };
1751
1752
1753
1754
1755 class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
1756 DiagnosticConsumer &Target;
1757
1758 public:
1759 ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
1760 ~ForwardingDiagnosticConsumer() override;
1761
1762 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
1763 const Diagnostic &Info) override;
1764 void clear() override;
1765
1766 bool IncludeInDiagnosticCounts() const override;
1767 };
1768
1769
1770 struct TemplateDiffTypes {
1771 intptr_t FromType;
1772 intptr_t ToType;
1773 LLVM_PREFERRED_TYPE(bool)
1774 unsigned PrintTree : 1;
1775 LLVM_PREFERRED_TYPE(bool)
1776 unsigned PrintFromType : 1;
1777 LLVM_PREFERRED_TYPE(bool)
1778 unsigned ElideType : 1;
1779 LLVM_PREFERRED_TYPE(bool)
1780 unsigned ShowColors : 1;
1781
1782
1783 LLVM_PREFERRED_TYPE(bool)
1784 unsigned TemplateDiffUsed : 1;
1785 };
1786
1787
1788
1789 const char ToggleHighlight = 127;
1790
1791
1792
1793 void ProcessWarningOptions(DiagnosticsEngine &Diags,
1794 const DiagnosticOptions &Opts,
1795 llvm::vfs::FileSystem &VFS, bool ReportDiags = true);
1796 void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl<char> &OutStr);
1797 }
1798
1799 #endif