Diagnostic.h revision 2f7f5b1f5ff023cb8c4008ae53a12b09e3ea2622
1//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief Defines the Diagnostic-related interfaces. 12/// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_DIAGNOSTIC_H 16#define LLVM_CLANG_DIAGNOSTIC_H 17 18#include "clang/Basic/DiagnosticIDs.h" 19#include "clang/Basic/SourceLocation.h" 20#include "llvm/ADT/ArrayRef.h" 21#include "llvm/ADT/DenseMap.h" 22#include "llvm/ADT/IntrusiveRefCntPtr.h" 23#include "llvm/ADT/OwningPtr.h" 24#include "llvm/Support/type_traits.h" 25 26#include <vector> 27#include <list> 28 29namespace clang { 30 class DiagnosticConsumer; 31 class DiagnosticBuilder; 32 class IdentifierInfo; 33 class DeclContext; 34 class LangOptions; 35 class Preprocessor; 36 class DiagnosticErrorTrap; 37 class StoredDiagnostic; 38 39/// \brief Annotates a diagnostic with some code that should be 40/// inserted, removed, or replaced to fix the problem. 41/// 42/// This kind of hint should be used when we are certain that the 43/// introduction, removal, or modification of a particular (small!) 44/// amount of code will correct a compilation error. The compiler 45/// should also provide full recovery from such errors, such that 46/// suppressing the diagnostic output can still result in successful 47/// compilation. 48class FixItHint { 49public: 50 /// \brief Code that should be replaced to correct the error. Empty for an 51 /// insertion hint. 52 CharSourceRange RemoveRange; 53 54 /// \brief Code in the specific range that should be inserted in the insertion 55 /// location. 56 CharSourceRange InsertFromRange; 57 58 /// \brief The actual code to insert at the insertion location, as a 59 /// string. 60 std::string CodeToInsert; 61 62 bool BeforePreviousInsertions; 63 64 /// \brief Empty code modification hint, indicating that no code 65 /// modification is known. 66 FixItHint() : BeforePreviousInsertions(false) { } 67 68 bool isNull() const { 69 return !RemoveRange.isValid(); 70 } 71 72 /// \brief Create a code modification hint that inserts the given 73 /// code string at a specific location. 74 static FixItHint CreateInsertion(SourceLocation InsertionLoc, 75 StringRef Code, 76 bool BeforePreviousInsertions = false) { 77 FixItHint Hint; 78 Hint.RemoveRange = 79 CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false); 80 Hint.CodeToInsert = Code; 81 Hint.BeforePreviousInsertions = BeforePreviousInsertions; 82 return Hint; 83 } 84 85 /// \brief Create a code modification hint that inserts the given 86 /// code from \arg FromRange at a specific location. 87 static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, 88 CharSourceRange FromRange, 89 bool BeforePreviousInsertions = false) { 90 FixItHint Hint; 91 Hint.RemoveRange = 92 CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false); 93 Hint.InsertFromRange = FromRange; 94 Hint.BeforePreviousInsertions = BeforePreviousInsertions; 95 return Hint; 96 } 97 98 /// \brief Create a code modification hint that removes the given 99 /// source range. 100 static FixItHint CreateRemoval(CharSourceRange RemoveRange) { 101 FixItHint Hint; 102 Hint.RemoveRange = RemoveRange; 103 return Hint; 104 } 105 static FixItHint CreateRemoval(SourceRange RemoveRange) { 106 return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange)); 107 } 108 109 /// \brief Create a code modification hint that replaces the given 110 /// source range with the given code string. 111 static FixItHint CreateReplacement(CharSourceRange RemoveRange, 112 StringRef Code) { 113 FixItHint Hint; 114 Hint.RemoveRange = RemoveRange; 115 Hint.CodeToInsert = Code; 116 return Hint; 117 } 118 119 static FixItHint CreateReplacement(SourceRange RemoveRange, 120 StringRef Code) { 121 return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code); 122 } 123}; 124 125/// DiagnosticsEngine - This concrete class is used by the front-end to report 126/// problems and issues. It massages the diagnostics (e.g. handling things like 127/// "report warnings as errors" and passes them off to the DiagnosticConsumer 128/// for reporting to the user. DiagnosticsEngine is tied to one translation unit 129/// and one SourceManager. 130class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> { 131public: 132 /// Level - The level of the diagnostic, after it has been through mapping. 133 enum Level { 134 Ignored = DiagnosticIDs::Ignored, 135 Note = DiagnosticIDs::Note, 136 Warning = DiagnosticIDs::Warning, 137 Error = DiagnosticIDs::Error, 138 Fatal = DiagnosticIDs::Fatal 139 }; 140 141 /// ExtensionHandling - How do we handle otherwise-unmapped extension? This 142 /// is controlled by -pedantic and -pedantic-errors. 143 enum ExtensionHandling { 144 Ext_Ignore, Ext_Warn, Ext_Error 145 }; 146 147 enum ArgumentKind { 148 ak_std_string, // std::string 149 ak_c_string, // const char * 150 ak_sint, // int 151 ak_uint, // unsigned 152 ak_identifierinfo, // IdentifierInfo 153 ak_qualtype, // QualType 154 ak_declarationname, // DeclarationName 155 ak_nameddecl, // NamedDecl * 156 ak_nestednamespec, // NestedNameSpecifier * 157 ak_declcontext, // DeclContext * 158 ak_qualtype_pair // pair<QualType, QualType> 159 }; 160 161 /// Specifies which overload candidates to display when overload resolution 162 /// fails. 163 enum OverloadsShown { 164 Ovl_All, ///< Show all overloads. 165 Ovl_Best ///< Show just the "best" overload candidates. 166 }; 167 168 /// ArgumentValue - This typedef represents on argument value, which is a 169 /// union discriminated by ArgumentKind, with a value. 170 typedef std::pair<ArgumentKind, intptr_t> ArgumentValue; 171 172private: 173 unsigned char AllExtensionsSilenced; // Used by __extension__ 174 bool IgnoreAllWarnings; // Ignore all warnings: -w 175 bool WarningsAsErrors; // Treat warnings like errors. 176 bool EnableAllWarnings; // Enable all warnings. 177 bool ErrorsAsFatal; // Treat errors like fatal errors. 178 bool SuppressSystemWarnings; // Suppress warnings in system headers. 179 bool SuppressAllDiagnostics; // Suppress all diagnostics. 180 bool ElideType; // Elide common types of templates. 181 bool PrintTemplateTree; // Print a tree when comparing templates. 182 bool ShowColors; // Color printing is enabled. 183 OverloadsShown ShowOverloads; // Which overload candidates to show. 184 unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit. 185 unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack, 186 // 0 -> no limit. 187 unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation 188 // backtrace stack, 0 -> no limit. 189 ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors? 190 IntrusiveRefCntPtr<DiagnosticIDs> Diags; 191 DiagnosticConsumer *Client; 192 bool OwnsDiagClient; 193 SourceManager *SourceMgr; 194 195 /// \brief Mapping information for diagnostics. Mapping info is 196 /// packed into four bits per diagnostic. The low three bits are the mapping 197 /// (an instance of diag::Mapping), or zero if unset. The high bit is set 198 /// when the mapping was established as a user mapping. If the high bit is 199 /// clear, then the low bits are set to the default value, and should be 200 /// mapped with -pedantic, -Werror, etc. 201 /// 202 /// A new DiagState is created and kept around when diagnostic pragmas modify 203 /// the state so that we know what is the diagnostic state at any given 204 /// source location. 205 class DiagState { 206 llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap; 207 208 public: 209 typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator 210 iterator; 211 typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator 212 const_iterator; 213 214 void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) { 215 DiagMap[Diag] = Info; 216 } 217 218 DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag); 219 220 const_iterator begin() const { return DiagMap.begin(); } 221 const_iterator end() const { return DiagMap.end(); } 222 }; 223 224 /// \brief Keeps and automatically disposes all DiagStates that we create. 225 std::list<DiagState> DiagStates; 226 227 /// \brief Represents a point in source where the diagnostic state was 228 /// modified because of a pragma. 'Loc' can be null if the point represents 229 /// the diagnostic state modifications done through the command-line. 230 struct DiagStatePoint { 231 DiagState *State; 232 FullSourceLoc Loc; 233 DiagStatePoint(DiagState *State, FullSourceLoc Loc) 234 : State(State), Loc(Loc) { } 235 236 bool operator<(const DiagStatePoint &RHS) const { 237 // If Loc is invalid it means it came from <command-line>, in which case 238 // we regard it as coming before any valid source location. 239 if (RHS.Loc.isInvalid()) 240 return false; 241 if (Loc.isInvalid()) 242 return true; 243 return Loc.isBeforeInTranslationUnitThan(RHS.Loc); 244 } 245 }; 246 247 /// \brief A vector of all DiagStatePoints representing changes in diagnostic 248 /// state due to diagnostic pragmas. The vector is always sorted according to 249 /// the SourceLocation of the DiagStatePoint. 250 typedef std::vector<DiagStatePoint> DiagStatePointsTy; 251 mutable DiagStatePointsTy DiagStatePoints; 252 253 /// \brief Keeps the DiagState that was active during each diagnostic 'push' 254 /// so we can get back at it when we 'pop'. 255 std::vector<DiagState *> DiagStateOnPushStack; 256 257 DiagState *GetCurDiagState() const { 258 assert(!DiagStatePoints.empty()); 259 return DiagStatePoints.back().State; 260 } 261 262 void PushDiagStatePoint(DiagState *State, SourceLocation L) { 263 FullSourceLoc Loc(L, *SourceMgr); 264 // Make sure that DiagStatePoints is always sorted according to Loc. 265 assert((Loc.isValid() || DiagStatePoints.empty()) && 266 "Adding invalid loc point after another point"); 267 assert((Loc.isInvalid() || DiagStatePoints.empty() || 268 DiagStatePoints.back().Loc.isInvalid() || 269 DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) && 270 "Previous point loc comes after or is the same as new one"); 271 DiagStatePoints.push_back(DiagStatePoint(State, 272 FullSourceLoc(Loc, *SourceMgr))); 273 } 274 275 /// \brief Finds the DiagStatePoint that contains the diagnostic state of 276 /// the given source location. 277 DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const; 278 279 /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or 280 /// fatal error is emitted, and is sticky. 281 bool ErrorOccurred; 282 bool FatalErrorOccurred; 283 284 /// \brief Indicates that an unrecoverable error has occurred. 285 bool UnrecoverableErrorOccurred; 286 287 /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred 288 /// during a parsing section, e.g. during parsing a function. 289 unsigned TrapNumErrorsOccurred; 290 unsigned TrapNumUnrecoverableErrorsOccurred; 291 292 /// LastDiagLevel - This is the level of the last diagnostic emitted. This is 293 /// used to emit continuation diagnostics with the same level as the 294 /// diagnostic that they follow. 295 DiagnosticIDs::Level LastDiagLevel; 296 297 unsigned NumWarnings; // Number of warnings reported 298 unsigned NumErrors; // Number of errors reported 299 unsigned NumErrorsSuppressed; // Number of errors suppressed 300 301 /// ArgToStringFn - A function pointer that converts an opaque diagnostic 302 /// argument to a strings. This takes the modifiers and argument that was 303 /// present in the diagnostic. 304 /// 305 /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous 306 /// arguments formatted for this diagnostic. Implementations of this function 307 /// can use this information to avoid redundancy across arguments. 308 /// 309 /// This is a hack to avoid a layering violation between libbasic and libsema. 310 typedef void (*ArgToStringFnTy)( 311 ArgumentKind Kind, intptr_t Val, 312 const char *Modifier, unsigned ModifierLen, 313 const char *Argument, unsigned ArgumentLen, 314 const ArgumentValue *PrevArgs, 315 unsigned NumPrevArgs, 316 SmallVectorImpl<char> &Output, 317 void *Cookie, 318 ArrayRef<intptr_t> QualTypeVals); 319 void *ArgToStringCookie; 320 ArgToStringFnTy ArgToStringFn; 321 322 /// \brief ID of the "delayed" diagnostic, which is a (typically 323 /// fatal) diagnostic that had to be delayed because it was found 324 /// while emitting another diagnostic. 325 unsigned DelayedDiagID; 326 327 /// \brief First string argument for the delayed diagnostic. 328 std::string DelayedDiagArg1; 329 330 /// \brief Second string argument for the delayed diagnostic. 331 std::string DelayedDiagArg2; 332 333public: 334 explicit DiagnosticsEngine( 335 const IntrusiveRefCntPtr<DiagnosticIDs> &Diags, 336 DiagnosticConsumer *client = 0, 337 bool ShouldOwnClient = true); 338 ~DiagnosticsEngine(); 339 340 const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const { 341 return Diags; 342 } 343 344 DiagnosticConsumer *getClient() { return Client; } 345 const DiagnosticConsumer *getClient() const { return Client; } 346 347 /// \brief Determine whether this \c DiagnosticsEngine object own its client. 348 bool ownsClient() const { return OwnsDiagClient; } 349 350 /// \brief Return the current diagnostic client along with ownership of that 351 /// client. 352 DiagnosticConsumer *takeClient() { 353 OwnsDiagClient = false; 354 return Client; 355 } 356 357 bool hasSourceManager() const { return SourceMgr != 0; } 358 SourceManager &getSourceManager() const { 359 assert(SourceMgr && "SourceManager not set!"); 360 return *SourceMgr; 361 } 362 void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; } 363 364 //===--------------------------------------------------------------------===// 365 // DiagnosticsEngine characterization methods, used by a client to customize 366 // how diagnostics are emitted. 367 // 368 369 /// pushMappings - Copies the current DiagMappings and pushes the new copy 370 /// onto the top of the stack. 371 void pushMappings(SourceLocation Loc); 372 373 /// popMappings - Pops the current DiagMappings off the top of the stack 374 /// causing the new top of the stack to be the active mappings. Returns 375 /// true if the pop happens, false if there is only one DiagMapping on the 376 /// stack. 377 bool popMappings(SourceLocation Loc); 378 379 /// \brief Set the diagnostic client associated with this diagnostic object. 380 /// 381 /// \param ShouldOwnClient true if the diagnostic object should take 382 /// ownership of \c client. 383 void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true); 384 385 /// setErrorLimit - Specify a limit for the number of errors we should 386 /// emit before giving up. Zero disables the limit. 387 void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; } 388 389 /// \brief Specify the maximum number of template instantiation 390 /// notes to emit along with a given diagnostic. 391 void setTemplateBacktraceLimit(unsigned Limit) { 392 TemplateBacktraceLimit = Limit; 393 } 394 395 /// \brief Retrieve the maximum number of template instantiation 396 /// notes to emit along with a given diagnostic. 397 unsigned getTemplateBacktraceLimit() const { 398 return TemplateBacktraceLimit; 399 } 400 401 /// \brief Specify the maximum number of constexpr evaluation 402 /// notes to emit along with a given diagnostic. 403 void setConstexprBacktraceLimit(unsigned Limit) { 404 ConstexprBacktraceLimit = Limit; 405 } 406 407 /// \brief Retrieve the maximum number of constexpr evaluation 408 /// notes to emit along with a given diagnostic. 409 unsigned getConstexprBacktraceLimit() const { 410 return ConstexprBacktraceLimit; 411 } 412 413 /// setIgnoreAllWarnings - When set to true, any unmapped warnings are 414 /// ignored. If this and WarningsAsErrors are both set, then this one wins. 415 void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } 416 bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } 417 418 /// setEnableAllWarnings - When set to true, any unmapped ignored warnings 419 /// are no longer ignored. If this and IgnoreAllWarnings are both set, 420 /// then that one wins. 421 void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; } 422 bool getEnableAllWarnngs() const { return EnableAllWarnings; } 423 424 /// setWarningsAsErrors - When set to true, any warnings reported are issued 425 /// as errors. 426 void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } 427 bool getWarningsAsErrors() const { return WarningsAsErrors; } 428 429 /// setErrorsAsFatal - When set to true, any error reported is made a 430 /// fatal error. 431 void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; } 432 bool getErrorsAsFatal() const { return ErrorsAsFatal; } 433 434 /// setSuppressSystemWarnings - When set to true mask warnings that 435 /// come from system headers. 436 void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; } 437 bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; } 438 439 /// \brief Suppress all diagnostics, to silence the front end when we 440 /// know that we don't want any more diagnostics to be passed along to the 441 /// client 442 void setSuppressAllDiagnostics(bool Val = true) { 443 SuppressAllDiagnostics = Val; 444 } 445 bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; } 446 447 /// \brief Set type eliding, to skip outputting same types occurring in 448 /// template types. 449 void setElideType(bool Val = true) { ElideType = Val; } 450 bool getElideType() { return ElideType; } 451 452 /// \brief Set tree printing, to outputting the template difference in a 453 /// tree format. 454 void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; } 455 bool getPrintTemplateTree() { return PrintTemplateTree; } 456 457 /// \brief Set color printing, so the type diffing will inject color markers 458 /// into the output. 459 void setShowColors(bool Val = false) { ShowColors = Val; } 460 bool getShowColors() { return ShowColors; } 461 462 /// \brief Specify which overload candidates to show when overload resolution 463 /// fails. By default, we show all candidates. 464 void setShowOverloads(OverloadsShown Val) { 465 ShowOverloads = Val; 466 } 467 OverloadsShown getShowOverloads() const { return ShowOverloads; } 468 469 /// \brief Pretend that the last diagnostic issued was ignored. This can 470 /// be used by clients who suppress diagnostics themselves. 471 void setLastDiagnosticIgnored() { 472 LastDiagLevel = DiagnosticIDs::Ignored; 473 } 474 475 /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped 476 /// extension diagnostics are mapped onto ignore/warning/error. This 477 /// corresponds to the GCC -pedantic and -pedantic-errors option. 478 void setExtensionHandlingBehavior(ExtensionHandling H) { 479 ExtBehavior = H; 480 } 481 ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; } 482 483 /// AllExtensionsSilenced - This is a counter bumped when an __extension__ 484 /// block is encountered. When non-zero, all extension diagnostics are 485 /// entirely silenced, no matter how they are mapped. 486 void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; } 487 void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; } 488 bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; } 489 490 /// \brief This allows the client to specify that certain warnings are 491 /// ignored. 492 /// 493 /// Notes can never be mapped, errors can only be mapped to fatal, and 494 /// WARNINGs and EXTENSIONs can be mapped arbitrarily. 495 /// 496 /// \param Loc The source location that this change of diagnostic state should 497 /// take affect. It can be null if we are setting the latest state. 498 void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map, 499 SourceLocation Loc); 500 501 /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to 502 /// have the specified mapping. 503 /// 504 /// \returns true (and ignores the request) if "Group" was unknown, false 505 /// otherwise. 506 /// 507 /// \param Loc The source location that this change of diagnostic state should 508 /// take affect. It can be null if we are setting the state from command-line. 509 bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map, 510 SourceLocation Loc = SourceLocation()); 511 512 /// \brief Set the warning-as-error flag for the given diagnostic. 513 /// 514 /// This function always only operates on the current diagnostic state. 515 void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled); 516 517 /// \brief Set the warning-as-error flag for the given diagnostic group. 518 /// 519 /// This function always only operates on the current diagnostic state. 520 /// 521 /// \returns True if the given group is unknown, false otherwise. 522 bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled); 523 524 /// \brief Set the error-as-fatal flag for the given diagnostic. 525 /// 526 /// This function always only operates on the current diagnostic state. 527 void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled); 528 529 /// \brief Set the error-as-fatal flag for the given diagnostic group. 530 /// 531 /// This function always only operates on the current diagnostic state. 532 /// 533 /// \returns True if the given group is unknown, false otherwise. 534 bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled); 535 536 /// \brief Add the specified mapping to all diagnostics. 537 /// 538 /// Mainly to be used by -Wno-everything to disable all warnings but allow 539 /// subsequent -W options to enable specific warnings. 540 void setMappingToAllDiagnostics(diag::Mapping Map, 541 SourceLocation Loc = SourceLocation()); 542 543 bool hasErrorOccurred() const { return ErrorOccurred; } 544 bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } 545 546 /// \brief Determine whether any kind of unrecoverable error has occurred. 547 bool hasUnrecoverableErrorOccurred() const { 548 return FatalErrorOccurred || UnrecoverableErrorOccurred; 549 } 550 551 unsigned getNumWarnings() const { return NumWarnings; } 552 553 void setNumWarnings(unsigned NumWarnings) { 554 this->NumWarnings = NumWarnings; 555 } 556 557 /// \brief Return an ID for a diagnostic with the specified message and level. 558 /// 559 /// If this is the first request for this diagnosic, it is registered and 560 /// created, otherwise the existing ID is returned. 561 unsigned getCustomDiagID(Level L, StringRef Message) { 562 return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message); 563 } 564 565 /// \brief Converts a diagnostic argument (as an intptr_t) into the string 566 /// that represents it. 567 void ConvertArgToString(ArgumentKind Kind, intptr_t Val, 568 const char *Modifier, unsigned ModLen, 569 const char *Argument, unsigned ArgLen, 570 const ArgumentValue *PrevArgs, unsigned NumPrevArgs, 571 SmallVectorImpl<char> &Output, 572 SmallVectorImpl<intptr_t> &QualTypeVals) const { 573 ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, 574 PrevArgs, NumPrevArgs, Output, ArgToStringCookie, 575 QualTypeVals); 576 } 577 578 void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) { 579 ArgToStringFn = Fn; 580 ArgToStringCookie = Cookie; 581 } 582 583 /// \brief Reset the state of the diagnostic object to its initial 584 /// configuration. 585 void Reset(); 586 587 //===--------------------------------------------------------------------===// 588 // DiagnosticsEngine classification and reporting interfaces. 589 // 590 591 /// \brief Based on the way the client configured the DiagnosticsEngine 592 /// object, classify the specified diagnostic ID into a Level, consumable by 593 /// the DiagnosticConsumer. 594 /// 595 /// \param Loc The source location we are interested in finding out the 596 /// diagnostic state. Can be null in order to query the latest state. 597 Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const { 598 return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this); 599 } 600 601 /// \brief Issue the message to the client. 602 /// 603 /// This actually returns an instance of DiagnosticBuilder which emits the 604 /// diagnostics (through @c ProcessDiag) when it is destroyed. 605 /// 606 /// \param DiagID A member of the @c diag::kind enum. 607 /// \param Loc Represents the source location associated with the diagnostic, 608 /// which can be an invalid location if no position information is available. 609 inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID); 610 inline DiagnosticBuilder Report(unsigned DiagID); 611 612 void Report(const StoredDiagnostic &storedDiag); 613 614 /// \brief Determine whethere there is already a diagnostic in flight. 615 bool isDiagnosticInFlight() const { return CurDiagID != ~0U; } 616 617 /// \brief Set the "delayed" diagnostic that will be emitted once 618 /// the current diagnostic completes. 619 /// 620 /// If a diagnostic is already in-flight but the front end must 621 /// report a problem (e.g., with an inconsistent file system 622 /// state), this routine sets a "delayed" diagnostic that will be 623 /// emitted after the current diagnostic completes. This should 624 /// only be used for fatal errors detected at inconvenient 625 /// times. If emitting a delayed diagnostic causes a second delayed 626 /// diagnostic to be introduced, that second delayed diagnostic 627 /// will be ignored. 628 /// 629 /// \param DiagID The ID of the diagnostic being delayed. 630 /// 631 /// \param Arg1 A string argument that will be provided to the 632 /// diagnostic. A copy of this string will be stored in the 633 /// DiagnosticsEngine object itself. 634 /// 635 /// \param Arg2 A string argument that will be provided to the 636 /// diagnostic. A copy of this string will be stored in the 637 /// DiagnosticsEngine object itself. 638 void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "", 639 StringRef Arg2 = ""); 640 641 /// \brief Clear out the current diagnostic. 642 void Clear() { CurDiagID = ~0U; } 643 644private: 645 /// \brief Report the delayed diagnostic. 646 void ReportDelayed(); 647 648 // This is private state used by DiagnosticBuilder. We put it here instead of 649 // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight 650 // object. This implementation choice means that we can only have one 651 // diagnostic "in flight" at a time, but this seems to be a reasonable 652 // tradeoff to keep these objects small. Assertions verify that only one 653 // diagnostic is in flight at a time. 654 friend class DiagnosticIDs; 655 friend class DiagnosticBuilder; 656 friend class Diagnostic; 657 friend class PartialDiagnostic; 658 friend class DiagnosticErrorTrap; 659 660 /// \brief The location of the current diagnostic that is in flight. 661 SourceLocation CurDiagLoc; 662 663 /// \brief The ID of the current diagnostic that is in flight. 664 /// 665 /// This is set to ~0U when there is no diagnostic in flight. 666 unsigned CurDiagID; 667 668 enum { 669 /// \brief The maximum number of arguments we can hold. 670 /// 671 /// We currently 672 /// only support up to 10 arguments (%0-%9). A single diagnostic with more 673 /// than that almost certainly has to be simplified anyway. 674 MaxArguments = 10, 675 676 /// \brief The maximum number of ranges we can hold. 677 MaxRanges = 10, 678 679 /// \brief The maximum number of ranges we can hold. 680 MaxFixItHints = 10 681 }; 682 683 /// \brief The number of entries in Arguments. 684 signed char NumDiagArgs; 685 /// \brief The number of ranges in the DiagRanges array. 686 unsigned char NumDiagRanges; 687 /// \brief The number of hints in the DiagFixItHints array. 688 unsigned char NumDiagFixItHints; 689 690 /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum 691 /// values, with one for each argument. This specifies whether the argument 692 /// is in DiagArgumentsStr or in DiagArguments. 693 unsigned char DiagArgumentsKind[MaxArguments]; 694 695 /// \brief holds the values of each string argument for the current 696 /// diagnostic. 697 /// 698 /// This is only used when the corresponding ArgumentKind is ak_std_string. 699 std::string DiagArgumentsStr[MaxArguments]; 700 701 /// \brief The values for the various substitution positions. 702 /// 703 /// This is used when the argument is not an std::string. The specific 704 /// value is mangled into an intptr_t and the interpretation depends on 705 /// exactly what sort of argument kind it is. 706 intptr_t DiagArgumentsVal[MaxArguments]; 707 708 /// \brief The list of ranges added to this diagnostic. 709 CharSourceRange DiagRanges[MaxRanges]; 710 711 /// \brief If valid, provides a hint with some code to insert, remove, 712 /// or modify at a particular position. 713 FixItHint DiagFixItHints[MaxFixItHints]; 714 715 DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) { 716 bool isPragma = L.isValid(); 717 DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make( 718 Map, /*IsUser=*/true, isPragma); 719 720 // If this is a pragma mapping, then set the diagnostic mapping flags so 721 // that we override command line options. 722 if (isPragma) { 723 MappingInfo.setNoWarningAsError(true); 724 MappingInfo.setNoErrorAsFatal(true); 725 } 726 727 return MappingInfo; 728 } 729 730 /// \brief Used to report a diagnostic that is finally fully formed. 731 /// 732 /// \returns true if the diagnostic was emitted, false if it was suppressed. 733 bool ProcessDiag() { 734 return Diags->ProcessDiag(*this); 735 } 736 737 /// @name Diagnostic Emission 738 /// @{ 739protected: 740 // Sema requires access to the following functions because the current design 741 // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to 742 // access us directly to ensure we minimize the emitted code for the common 743 // Sema::Diag() patterns. 744 friend class Sema; 745 746 /// \brief Emit the current diagnostic and clear the diagnostic state. 747 bool EmitCurrentDiagnostic(); 748 749 unsigned getCurrentDiagID() const { return CurDiagID; } 750 751 SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; } 752 753 /// @} 754 755 friend class ASTReader; 756 friend class ASTWriter; 757}; 758 759/// \brief RAII class that determines when any errors have occurred 760/// between the time the instance was created and the time it was 761/// queried. 762class DiagnosticErrorTrap { 763 DiagnosticsEngine &Diag; 764 unsigned NumErrors; 765 unsigned NumUnrecoverableErrors; 766 767public: 768 explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag) 769 : Diag(Diag) { reset(); } 770 771 /// \brief Determine whether any errors have occurred since this 772 /// object instance was created. 773 bool hasErrorOccurred() const { 774 return Diag.TrapNumErrorsOccurred > NumErrors; 775 } 776 777 /// \brief Determine whether any unrecoverable errors have occurred since this 778 /// object instance was created. 779 bool hasUnrecoverableErrorOccurred() const { 780 return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors; 781 } 782 783 // Set to initial state of "no errors occurred". 784 void reset() { 785 NumErrors = Diag.TrapNumErrorsOccurred; 786 NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred; 787 } 788}; 789 790//===----------------------------------------------------------------------===// 791// DiagnosticBuilder 792//===----------------------------------------------------------------------===// 793 794/// \brief A little helper class used to produce diagnostics. 795/// 796/// This is constructed by the DiagnosticsEngine::Report method, and 797/// allows insertion of extra information (arguments and source ranges) into 798/// the currently "in flight" diagnostic. When the temporary for the builder 799/// is destroyed, the diagnostic is issued. 800/// 801/// Note that many of these will be created as temporary objects (many call 802/// sites), so we want them to be small and we never want their address taken. 803/// This ensures that compilers with somewhat reasonable optimizers will promote 804/// the common fields to registers, eliminating increments of the NumArgs field, 805/// for example. 806class DiagnosticBuilder { 807 mutable DiagnosticsEngine *DiagObj; 808 mutable unsigned NumArgs, NumRanges, NumFixits; 809 810 /// \brief Status variable indicating if this diagnostic is still active. 811 /// 812 // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)), 813 // but LLVM is not currently smart enough to eliminate the null check that 814 // Emit() would end up with if we used that as our status variable. 815 mutable bool IsActive; 816 817 void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT 818 friend class DiagnosticsEngine; 819 820 DiagnosticBuilder() 821 : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false) { } 822 823 explicit DiagnosticBuilder(DiagnosticsEngine *diagObj) 824 : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true) { 825 assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!"); 826 } 827 828 friend class PartialDiagnostic; 829 830protected: 831 void FlushCounts() { 832 DiagObj->NumDiagArgs = NumArgs; 833 DiagObj->NumDiagRanges = NumRanges; 834 DiagObj->NumDiagFixItHints = NumFixits; 835 } 836 837 /// \brief Clear out the current diagnostic. 838 void Clear() const { 839 DiagObj = 0; 840 IsActive = false; 841 } 842 843 /// \brief Determine whether this diagnostic is still active. 844 bool isActive() const { return IsActive; } 845 846 /// \brief Force the diagnostic builder to emit the diagnostic now. 847 /// 848 /// Once this function has been called, the DiagnosticBuilder object 849 /// should not be used again before it is destroyed. 850 /// 851 /// \returns true if a diagnostic was emitted, false if the 852 /// diagnostic was suppressed. 853 bool Emit() { 854 // If this diagnostic is inactive, then its soul was stolen by the copy ctor 855 // (or by a subclass, as in SemaDiagnosticBuilder). 856 if (!isActive()) return false; 857 858 // When emitting diagnostics, we set the final argument count into 859 // the DiagnosticsEngine object. 860 FlushCounts(); 861 862 // Process the diagnostic. 863 bool Result = DiagObj->EmitCurrentDiagnostic(); 864 865 // This diagnostic is dead. 866 Clear(); 867 868 return Result; 869 } 870 871public: 872 /// Copy constructor. When copied, this "takes" the diagnostic info from the 873 /// input and neuters it. 874 DiagnosticBuilder(const DiagnosticBuilder &D) { 875 DiagObj = D.DiagObj; 876 IsActive = D.IsActive; 877 D.Clear(); 878 NumArgs = D.NumArgs; 879 NumRanges = D.NumRanges; 880 NumFixits = D.NumFixits; 881 } 882 883 /// \brief Retrieve an empty diagnostic builder. 884 static DiagnosticBuilder getEmpty() { 885 return DiagnosticBuilder(); 886 } 887 888 /// \brief Emits the diagnostic. 889 ~DiagnosticBuilder() { 890 Emit(); 891 } 892 893 /// Operator bool: conversion of DiagnosticBuilder to bool always returns 894 /// true. This allows is to be used in boolean error contexts like: 895 /// return Diag(...); 896 operator bool() const { return true; } 897 898 void AddString(StringRef S) const { 899 assert(isActive() && "Clients must not add to cleared diagnostic!"); 900 assert(NumArgs < DiagnosticsEngine::MaxArguments && 901 "Too many arguments to diagnostic!"); 902 DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string; 903 DiagObj->DiagArgumentsStr[NumArgs++] = S; 904 } 905 906 void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { 907 assert(isActive() && "Clients must not add to cleared diagnostic!"); 908 assert(NumArgs < DiagnosticsEngine::MaxArguments && 909 "Too many arguments to diagnostic!"); 910 DiagObj->DiagArgumentsKind[NumArgs] = Kind; 911 DiagObj->DiagArgumentsVal[NumArgs++] = V; 912 } 913 914 void AddSourceRange(const CharSourceRange &R) const { 915 assert(isActive() && "Clients must not add to cleared diagnostic!"); 916 assert(NumRanges < DiagnosticsEngine::MaxRanges && 917 "Too many arguments to diagnostic!"); 918 DiagObj->DiagRanges[NumRanges++] = R; 919 } 920 921 void AddFixItHint(const FixItHint &Hint) const { 922 assert(isActive() && "Clients must not add to cleared diagnostic!"); 923 assert(NumFixits < DiagnosticsEngine::MaxFixItHints && 924 "Too many arguments to diagnostic!"); 925 DiagObj->DiagFixItHints[NumFixits++] = Hint; 926 } 927}; 928 929inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 930 StringRef S) { 931 DB.AddString(S); 932 return DB; 933} 934 935inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 936 const char *Str) { 937 DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str), 938 DiagnosticsEngine::ak_c_string); 939 return DB; 940} 941 942inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { 943 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); 944 return DB; 945} 946 947inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) { 948 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); 949 return DB; 950} 951 952inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 953 unsigned I) { 954 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint); 955 return DB; 956} 957 958inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 959 const IdentifierInfo *II) { 960 DB.AddTaggedVal(reinterpret_cast<intptr_t>(II), 961 DiagnosticsEngine::ak_identifierinfo); 962 return DB; 963} 964 965// Adds a DeclContext to the diagnostic. The enable_if template magic is here 966// so that we only match those arguments that are (statically) DeclContexts; 967// other arguments that derive from DeclContext (e.g., RecordDecls) will not 968// match. 969template<typename T> 970inline 971typename llvm::enable_if<llvm::is_same<T, DeclContext>, 972 const DiagnosticBuilder &>::type 973operator<<(const DiagnosticBuilder &DB, T *DC) { 974 DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC), 975 DiagnosticsEngine::ak_declcontext); 976 return DB; 977} 978 979inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 980 const SourceRange &R) { 981 DB.AddSourceRange(CharSourceRange::getTokenRange(R)); 982 return DB; 983} 984 985inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 986 const CharSourceRange &R) { 987 DB.AddSourceRange(R); 988 return DB; 989} 990 991inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 992 const FixItHint &Hint) { 993 if (!Hint.isNull()) 994 DB.AddFixItHint(Hint); 995 return DB; 996} 997 998inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, 999 unsigned DiagID){ 1000 assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); 1001 CurDiagLoc = Loc; 1002 CurDiagID = DiagID; 1003 return DiagnosticBuilder(this); 1004} 1005inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { 1006 return Report(SourceLocation(), DiagID); 1007} 1008 1009//===----------------------------------------------------------------------===// 1010// Diagnostic 1011//===----------------------------------------------------------------------===// 1012 1013/// A little helper class (which is basically a smart pointer that forwards 1014/// info from DiagnosticsEngine) that allows clients to enquire about the 1015/// currently in-flight diagnostic. 1016class Diagnostic { 1017 const DiagnosticsEngine *DiagObj; 1018 StringRef StoredDiagMessage; 1019public: 1020 explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {} 1021 Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage) 1022 : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {} 1023 1024 const DiagnosticsEngine *getDiags() const { return DiagObj; } 1025 unsigned getID() const { return DiagObj->CurDiagID; } 1026 const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; } 1027 bool hasSourceManager() const { return DiagObj->hasSourceManager(); } 1028 SourceManager &getSourceManager() const { return DiagObj->getSourceManager();} 1029 1030 unsigned getNumArgs() const { return DiagObj->NumDiagArgs; } 1031 1032 /// getArgKind - Return the kind of the specified index. Based on the kind 1033 /// of argument, the accessors below can be used to get the value. 1034 DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const { 1035 assert(Idx < getNumArgs() && "Argument index out of range!"); 1036 return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx]; 1037 } 1038 1039 /// getArgStdStr - Return the provided argument string specified by Idx. 1040 const std::string &getArgStdStr(unsigned Idx) const { 1041 assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string && 1042 "invalid argument accessor!"); 1043 return DiagObj->DiagArgumentsStr[Idx]; 1044 } 1045 1046 /// getArgCStr - Return the specified C string argument. 1047 const char *getArgCStr(unsigned Idx) const { 1048 assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string && 1049 "invalid argument accessor!"); 1050 return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]); 1051 } 1052 1053 /// getArgSInt - Return the specified signed integer argument. 1054 int getArgSInt(unsigned Idx) const { 1055 assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint && 1056 "invalid argument accessor!"); 1057 return (int)DiagObj->DiagArgumentsVal[Idx]; 1058 } 1059 1060 /// getArgUInt - Return the specified unsigned integer argument. 1061 unsigned getArgUInt(unsigned Idx) const { 1062 assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint && 1063 "invalid argument accessor!"); 1064 return (unsigned)DiagObj->DiagArgumentsVal[Idx]; 1065 } 1066 1067 /// getArgIdentifier - Return the specified IdentifierInfo argument. 1068 const IdentifierInfo *getArgIdentifier(unsigned Idx) const { 1069 assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo && 1070 "invalid argument accessor!"); 1071 return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]); 1072 } 1073 1074 /// getRawArg - Return the specified non-string argument in an opaque form. 1075 intptr_t getRawArg(unsigned Idx) const { 1076 assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string && 1077 "invalid argument accessor!"); 1078 return DiagObj->DiagArgumentsVal[Idx]; 1079 } 1080 1081 /// getNumRanges - Return the number of source ranges associated with this 1082 /// diagnostic. 1083 unsigned getNumRanges() const { 1084 return DiagObj->NumDiagRanges; 1085 } 1086 1087 const CharSourceRange &getRange(unsigned Idx) const { 1088 assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!"); 1089 return DiagObj->DiagRanges[Idx]; 1090 } 1091 1092 /// \brief Return an array reference for this diagnostic's ranges. 1093 ArrayRef<CharSourceRange> getRanges() const { 1094 return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges); 1095 } 1096 1097 unsigned getNumFixItHints() const { 1098 return DiagObj->NumDiagFixItHints; 1099 } 1100 1101 const FixItHint &getFixItHint(unsigned Idx) const { 1102 assert(Idx < getNumFixItHints() && "Invalid index!"); 1103 return DiagObj->DiagFixItHints[Idx]; 1104 } 1105 1106 const FixItHint *getFixItHints() const { 1107 return getNumFixItHints()? DiagObj->DiagFixItHints : 0; 1108 } 1109 1110 /// FormatDiagnostic - Format this diagnostic into a string, substituting the 1111 /// formal arguments into the %0 slots. The result is appended onto the Str 1112 /// array. 1113 void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const; 1114 1115 /// FormatDiagnostic - Format the given format-string into the 1116 /// output buffer using the arguments stored in this diagnostic. 1117 void FormatDiagnostic(const char *DiagStr, const char *DiagEnd, 1118 SmallVectorImpl<char> &OutStr) const; 1119}; 1120 1121/** 1122 * \brief Represents a diagnostic in a form that can be retained until its 1123 * corresponding source manager is destroyed. 1124 */ 1125class StoredDiagnostic { 1126 unsigned ID; 1127 DiagnosticsEngine::Level Level; 1128 FullSourceLoc Loc; 1129 std::string Message; 1130 std::vector<CharSourceRange> Ranges; 1131 std::vector<FixItHint> FixIts; 1132 1133public: 1134 StoredDiagnostic(); 1135 StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); 1136 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1137 StringRef Message); 1138 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1139 StringRef Message, FullSourceLoc Loc, 1140 ArrayRef<CharSourceRange> Ranges, 1141 ArrayRef<FixItHint> Fixits); 1142 ~StoredDiagnostic(); 1143 1144 /// \brief Evaluates true when this object stores a diagnostic. 1145 operator bool() const { return Message.size() > 0; } 1146 1147 unsigned getID() const { return ID; } 1148 DiagnosticsEngine::Level getLevel() const { return Level; } 1149 const FullSourceLoc &getLocation() const { return Loc; } 1150 StringRef getMessage() const { return Message; } 1151 1152 void setLocation(FullSourceLoc Loc) { this->Loc = Loc; } 1153 1154 typedef std::vector<CharSourceRange>::const_iterator range_iterator; 1155 range_iterator range_begin() const { return Ranges.begin(); } 1156 range_iterator range_end() const { return Ranges.end(); } 1157 unsigned range_size() const { return Ranges.size(); } 1158 1159 ArrayRef<CharSourceRange> getRanges() const { 1160 return llvm::makeArrayRef(Ranges); 1161 } 1162 1163 1164 typedef std::vector<FixItHint>::const_iterator fixit_iterator; 1165 fixit_iterator fixit_begin() const { return FixIts.begin(); } 1166 fixit_iterator fixit_end() const { return FixIts.end(); } 1167 unsigned fixit_size() const { return FixIts.size(); } 1168 1169 ArrayRef<FixItHint> getFixIts() const { 1170 return llvm::makeArrayRef(FixIts); 1171 } 1172}; 1173 1174/// DiagnosticConsumer - This is an abstract interface implemented by clients of 1175/// the front-end, which formats and prints fully processed diagnostics. 1176class DiagnosticConsumer { 1177protected: 1178 unsigned NumWarnings; // Number of warnings reported 1179 unsigned NumErrors; // Number of errors reported 1180 1181public: 1182 DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { } 1183 1184 unsigned getNumErrors() const { return NumErrors; } 1185 unsigned getNumWarnings() const { return NumWarnings; } 1186 virtual void clear() { NumWarnings = NumErrors = 0; } 1187 1188 virtual ~DiagnosticConsumer(); 1189 1190 /// BeginSourceFile - Callback to inform the diagnostic client that processing 1191 /// of a source file is beginning. 1192 /// 1193 /// Note that diagnostics may be emitted outside the processing of a source 1194 /// file, for example during the parsing of command line options. However, 1195 /// diagnostics with source range information are required to only be emitted 1196 /// in between BeginSourceFile() and EndSourceFile(). 1197 /// 1198 /// \arg LO - The language options for the source file being processed. 1199 /// \arg PP - The preprocessor object being used for the source; this optional 1200 /// and may not be present, for example when processing AST source files. 1201 virtual void BeginSourceFile(const LangOptions &LangOpts, 1202 const Preprocessor *PP = 0) {} 1203 1204 /// EndSourceFile - Callback to inform the diagnostic client that processing 1205 /// of a source file has ended. The diagnostic client should assume that any 1206 /// objects made available via \see BeginSourceFile() are inaccessible. 1207 virtual void EndSourceFile() {} 1208 1209 /// \brief Callback to inform the diagnostic client that processing of all 1210 /// source files has ended. 1211 virtual void finish() {} 1212 1213 /// IncludeInDiagnosticCounts - This method (whose default implementation 1214 /// returns true) indicates whether the diagnostics handled by this 1215 /// DiagnosticConsumer should be included in the number of diagnostics 1216 /// reported by DiagnosticsEngine. 1217 virtual bool IncludeInDiagnosticCounts() const; 1218 1219 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 1220 /// capturing it to a log as needed. 1221 /// 1222 /// Default implementation just keeps track of the total number of warnings 1223 /// and errors. 1224 virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 1225 const Diagnostic &Info); 1226 1227 /// \brief Clone the diagnostic consumer, producing an equivalent consumer 1228 /// that can be used in a different context. 1229 virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0; 1230}; 1231 1232/// IgnoringDiagConsumer - This is a diagnostic client that just ignores all 1233/// diags. 1234class IgnoringDiagConsumer : public DiagnosticConsumer { 1235 virtual void anchor(); 1236 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 1237 const Diagnostic &Info) { 1238 // Just ignore it. 1239 } 1240 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { 1241 return new IgnoringDiagConsumer(); 1242 } 1243}; 1244 1245// Struct used for sending info about how a type should be printed. 1246struct TemplateDiffTypes { 1247 intptr_t FromType; 1248 intptr_t ToType; 1249 unsigned PrintTree : 1; 1250 unsigned PrintFromType : 1; 1251 unsigned ElideType : 1; 1252 unsigned ShowColors : 1; 1253}; 1254 1255/// Special character that the diagnostic printer will use to toggle the bold 1256/// attribute. The character itself will be not be printed. 1257const char ToggleHighlight = 127; 1258 1259} // end namespace clang 1260 1261#endif 1262