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