1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- 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 // This file declares the different classes involved in low level diagnostics. 10 // 11 // Diagnostics reporting is still done as part of the LLVMContext. 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_IR_DIAGNOSTICINFO_H 15 #define LLVM_IR_DIAGNOSTICINFO_H 16 17 #include "llvm-c/Types.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/ADT/Twine.h" 22 #include "llvm/IR/DebugLoc.h" 23 #include "llvm/Support/CBindingWrapping.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/SourceMgr.h" 26 #include "llvm/Support/TypeSize.h" 27 #include <algorithm> 28 #include <cstdint> 29 #include <functional> 30 #include <iterator> 31 #include <optional> 32 #include <string> 33 34 namespace llvm { 35 36 // Forward declarations. 37 class DiagnosticPrinter; 38 class DIFile; 39 class DISubprogram; 40 class CallInst; 41 class Function; 42 class Instruction; 43 class InstructionCost; 44 class Module; 45 class Type; 46 class Value; 47 48 /// Defines the different supported severity of a diagnostic. 49 enum DiagnosticSeverity : char { 50 DS_Error, 51 DS_Warning, 52 DS_Remark, 53 // A note attaches additional information to one of the previous diagnostic 54 // types. 55 DS_Note 56 }; 57 58 /// Defines the different supported kind of a diagnostic. 59 /// This enum should be extended with a new ID for each added concrete subclass. 60 enum DiagnosticKind { 61 DK_Generic, 62 DK_GenericWithLoc, 63 DK_InlineAsm, 64 DK_RegAllocFailure, 65 DK_ResourceLimit, 66 DK_StackSize, 67 DK_Linker, 68 DK_Lowering, 69 DK_DebugMetadataVersion, 70 DK_DebugMetadataInvalid, 71 DK_Instrumentation, 72 DK_ISelFallback, 73 DK_SampleProfile, 74 DK_OptimizationRemark, 75 DK_OptimizationRemarkMissed, 76 DK_OptimizationRemarkAnalysis, 77 DK_OptimizationRemarkAnalysisFPCommute, 78 DK_OptimizationRemarkAnalysisAliasing, 79 DK_OptimizationFailure, 80 DK_FirstRemark = DK_OptimizationRemark, 81 DK_LastRemark = DK_OptimizationFailure, 82 DK_MachineOptimizationRemark, 83 DK_MachineOptimizationRemarkMissed, 84 DK_MachineOptimizationRemarkAnalysis, 85 DK_FirstMachineRemark = DK_MachineOptimizationRemark, 86 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis, 87 DK_MIRParser, 88 DK_PGOProfile, 89 DK_Unsupported, 90 DK_SrcMgr, 91 DK_DontCall, 92 DK_MisExpect, 93 DK_FirstPluginKind // Must be last value to work with 94 // getNextAvailablePluginDiagnosticKind 95 }; 96 97 /// Get the next available kind ID for a plugin diagnostic. 98 /// Each time this function is called, it returns a different number. 99 /// Therefore, a plugin that wants to "identify" its own classes 100 /// with a dynamic identifier, just have to use this method to get a new ID 101 /// and assign it to each of its classes. 102 /// The returned ID will be greater than or equal to DK_FirstPluginKind. 103 /// Thus, the plugin identifiers will not conflict with the 104 /// DiagnosticKind values. 105 int getNextAvailablePluginDiagnosticKind(); 106 107 /// This is the base abstract class for diagnostic reporting in 108 /// the backend. 109 /// The print method must be overloaded by the subclasses to print a 110 /// user-friendly message in the client of the backend (let us call it a 111 /// frontend). 112 class DiagnosticInfo { 113 private: 114 /// Kind defines the kind of report this is about. 115 const /* DiagnosticKind */ int Kind; 116 /// Severity gives the severity of the diagnostic. 117 const DiagnosticSeverity Severity; 118 119 virtual void anchor(); 120 public: 121 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity) 122 : Kind(Kind), Severity(Severity) {} 123 124 virtual ~DiagnosticInfo() = default; 125 126 /* DiagnosticKind */ int getKind() const { return Kind; } 127 DiagnosticSeverity getSeverity() const { return Severity; } 128 129 /// Print using the given \p DP a user-friendly message. 130 /// This is the default message that will be printed to the user. 131 /// It is used when the frontend does not directly take advantage 132 /// of the information contained in fields of the subclasses. 133 /// The printed message must not end with '.' nor start with a severity 134 /// keyword. 135 virtual void print(DiagnosticPrinter &DP) const = 0; 136 }; 137 138 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>; 139 140 class DiagnosticInfoGeneric : public DiagnosticInfo { 141 const Twine &MsgStr; 142 const Instruction *Inst = nullptr; 143 144 public: 145 /// \p MsgStr is the message to be reported to the frontend. 146 /// This class does not copy \p MsgStr, therefore the reference must be valid 147 /// for the whole life time of the Diagnostic. 148 DiagnosticInfoGeneric(const Twine &MsgStr, 149 DiagnosticSeverity Severity = DS_Error) 150 : DiagnosticInfo(DK_Generic, Severity), MsgStr(MsgStr) {} 151 152 DiagnosticInfoGeneric(const Instruction *I, const Twine &ErrMsg, 153 DiagnosticSeverity Severity = DS_Error) 154 : DiagnosticInfo(DK_Generic, Severity), MsgStr(ErrMsg), Inst(I) {} 155 156 const Twine &getMsgStr() const { return MsgStr; } 157 const Instruction *getInstruction() const { return Inst; } 158 159 /// \see DiagnosticInfo::print. 160 void print(DiagnosticPrinter &DP) const override; 161 162 static bool classof(const DiagnosticInfo *DI) { 163 return DI->getKind() == DK_Generic; 164 } 165 }; 166 167 /// Diagnostic information for inline asm reporting. 168 /// This is basically a message and an optional location. 169 class DiagnosticInfoInlineAsm : public DiagnosticInfo { 170 private: 171 /// Optional line information. 0 if not set. 172 uint64_t LocCookie = 0; 173 /// Message to be reported. 174 const Twine &MsgStr; 175 /// Optional origin of the problem. 176 const Instruction *Instr = nullptr; 177 178 public: 179 /// \p LocCookie if non-zero gives the line number for this report. 180 /// \p MsgStr gives the message. 181 /// This class does not copy \p MsgStr, therefore the reference must be valid 182 /// for the whole life time of the Diagnostic. 183 DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr, 184 DiagnosticSeverity Severity = DS_Error); 185 186 /// \p Instr gives the original instruction that triggered the diagnostic. 187 /// \p MsgStr gives the message. 188 /// This class does not copy \p MsgStr, therefore the reference must be valid 189 /// for the whole life time of the Diagnostic. 190 /// Same for \p I. 191 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr, 192 DiagnosticSeverity Severity = DS_Error); 193 194 uint64_t getLocCookie() const { return LocCookie; } 195 const Twine &getMsgStr() const { return MsgStr; } 196 const Instruction *getInstruction() const { return Instr; } 197 198 /// \see DiagnosticInfo::print. 199 void print(DiagnosticPrinter &DP) const override; 200 201 static bool classof(const DiagnosticInfo *DI) { 202 return DI->getKind() == DK_InlineAsm; 203 } 204 }; 205 206 /// Diagnostic information for debug metadata version reporting. 207 /// This is basically a module and a version. 208 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo { 209 private: 210 /// The module that is concerned by this debug metadata version diagnostic. 211 const Module &M; 212 /// The actual metadata version. 213 unsigned MetadataVersion; 214 215 public: 216 /// \p The module that is concerned by this debug metadata version diagnostic. 217 /// \p The actual metadata version. 218 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion, 219 DiagnosticSeverity Severity = DS_Warning) 220 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M), 221 MetadataVersion(MetadataVersion) {} 222 223 const Module &getModule() const { return M; } 224 unsigned getMetadataVersion() const { return MetadataVersion; } 225 226 /// \see DiagnosticInfo::print. 227 void print(DiagnosticPrinter &DP) const override; 228 229 static bool classof(const DiagnosticInfo *DI) { 230 return DI->getKind() == DK_DebugMetadataVersion; 231 } 232 }; 233 234 /// Diagnostic information for stripping invalid debug metadata. 235 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo { 236 private: 237 /// The module that is concerned by this debug metadata version diagnostic. 238 const Module &M; 239 240 public: 241 /// \p The module that is concerned by this debug metadata version diagnostic. 242 DiagnosticInfoIgnoringInvalidDebugMetadata( 243 const Module &M, DiagnosticSeverity Severity = DS_Warning) 244 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {} 245 246 const Module &getModule() const { return M; } 247 248 /// \see DiagnosticInfo::print. 249 void print(DiagnosticPrinter &DP) const override; 250 251 static bool classof(const DiagnosticInfo *DI) { 252 return DI->getKind() == DK_DebugMetadataInvalid; 253 } 254 }; 255 256 /// Diagnostic information for the sample profiler. 257 class DiagnosticInfoSampleProfile : public DiagnosticInfo { 258 public: 259 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum, 260 const Twine &Msg, 261 DiagnosticSeverity Severity = DS_Error) 262 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 263 LineNum(LineNum), Msg(Msg) {} 264 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, 265 DiagnosticSeverity Severity = DS_Error) 266 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 267 Msg(Msg) {} 268 DiagnosticInfoSampleProfile(const Twine &Msg, 269 DiagnosticSeverity Severity = DS_Error) 270 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {} 271 272 /// \see DiagnosticInfo::print. 273 void print(DiagnosticPrinter &DP) const override; 274 275 static bool classof(const DiagnosticInfo *DI) { 276 return DI->getKind() == DK_SampleProfile; 277 } 278 279 StringRef getFileName() const { return FileName; } 280 unsigned getLineNum() const { return LineNum; } 281 const Twine &getMsg() const { return Msg; } 282 283 private: 284 /// Name of the input file associated with this diagnostic. 285 StringRef FileName; 286 287 /// Line number where the diagnostic occurred. If 0, no line number will 288 /// be emitted in the message. 289 unsigned LineNum = 0; 290 291 /// Message to report. 292 const Twine &Msg; 293 }; 294 295 /// Diagnostic information for the PGO profiler. 296 class DiagnosticInfoPGOProfile : public DiagnosticInfo { 297 public: 298 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg, 299 DiagnosticSeverity Severity = DS_Error) 300 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {} 301 302 /// \see DiagnosticInfo::print. 303 void print(DiagnosticPrinter &DP) const override; 304 305 static bool classof(const DiagnosticInfo *DI) { 306 return DI->getKind() == DK_PGOProfile; 307 } 308 309 const char *getFileName() const { return FileName; } 310 const Twine &getMsg() const { return Msg; } 311 312 private: 313 /// Name of the input file associated with this diagnostic. 314 const char *FileName; 315 316 /// Message to report. 317 const Twine &Msg; 318 }; 319 320 class DiagnosticLocation { 321 DIFile *File = nullptr; 322 unsigned Line = 0; 323 unsigned Column = 0; 324 325 public: 326 DiagnosticLocation() = default; 327 DiagnosticLocation(const DebugLoc &DL); 328 DiagnosticLocation(const DISubprogram *SP); 329 330 bool isValid() const { return File; } 331 /// Return the full path to the file. 332 std::string getAbsolutePath() const; 333 /// Return the file name relative to the compilation directory. 334 StringRef getRelativePath() const; 335 unsigned getLine() const { return Line; } 336 unsigned getColumn() const { return Column; } 337 }; 338 339 /// Common features for diagnostics with an associated location. 340 class DiagnosticInfoWithLocationBase : public DiagnosticInfo { 341 void anchor() override; 342 public: 343 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 344 /// the location information to use in the diagnostic. 345 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind, 346 enum DiagnosticSeverity Severity, 347 const Function &Fn, 348 const DiagnosticLocation &Loc) 349 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {} 350 351 /// Return true if location information is available for this diagnostic. 352 bool isLocationAvailable() const { return Loc.isValid(); } 353 354 /// Return a string with the location information for this diagnostic 355 /// in the format "file:line:col". If location information is not available, 356 /// it returns "<unknown>:0:0". 357 std::string getLocationStr() const; 358 359 /// Return location information for this diagnostic in three parts: 360 /// the relative source file path, line number and column. 361 void getLocation(StringRef &RelativePath, unsigned &Line, 362 unsigned &Column) const; 363 364 /// Return the absolute path tot the file. 365 std::string getAbsolutePath() const; 366 367 const Function &getFunction() const { return Fn; } 368 DiagnosticLocation getLocation() const { return Loc; } 369 370 private: 371 /// Function where this diagnostic is triggered. 372 const Function &Fn; 373 374 /// Debug location where this diagnostic is triggered. 375 DiagnosticLocation Loc; 376 }; 377 378 class DiagnosticInfoGenericWithLoc : public DiagnosticInfoWithLocationBase { 379 private: 380 /// Message to be reported. 381 const Twine &MsgStr; 382 383 public: 384 /// \p MsgStr is the message to be reported to the frontend. 385 /// This class does not copy \p MsgStr, therefore the reference must be valid 386 /// for the whole life time of the Diagnostic. 387 DiagnosticInfoGenericWithLoc(const Twine &MsgStr, const Function &Fn, 388 const DiagnosticLocation &Loc, 389 DiagnosticSeverity Severity = DS_Error) 390 : DiagnosticInfoWithLocationBase(DK_GenericWithLoc, Severity, Fn, Loc), 391 MsgStr(MsgStr) {} 392 393 const Twine &getMsgStr() const { return MsgStr; } 394 395 /// \see DiagnosticInfo::print. 396 void print(DiagnosticPrinter &DP) const override; 397 398 static bool classof(const DiagnosticInfo *DI) { 399 return DI->getKind() == DK_GenericWithLoc; 400 } 401 }; 402 403 class DiagnosticInfoRegAllocFailure : public DiagnosticInfoWithLocationBase { 404 private: 405 /// Message to be reported. 406 const Twine &MsgStr; 407 408 public: 409 /// \p MsgStr is the message to be reported to the frontend. 410 /// This class does not copy \p MsgStr, therefore the reference must be valid 411 /// for the whole life time of the Diagnostic. 412 DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn, 413 const DiagnosticLocation &DL, 414 DiagnosticSeverity Severity = DS_Error); 415 416 DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn, 417 DiagnosticSeverity Severity = DS_Error); 418 419 const Twine &getMsgStr() const { return MsgStr; } 420 421 /// \see DiagnosticInfo::print. 422 void print(DiagnosticPrinter &DP) const override; 423 424 static bool classof(const DiagnosticInfo *DI) { 425 return DI->getKind() == DK_RegAllocFailure; 426 } 427 }; 428 429 /// Diagnostic information for stack size etc. reporting. 430 /// This is basically a function and a size. 431 class DiagnosticInfoResourceLimit : public DiagnosticInfoWithLocationBase { 432 private: 433 /// The function that is concerned by this resource limit diagnostic. 434 const Function &Fn; 435 436 /// Description of the resource type (e.g. stack size) 437 const char *ResourceName; 438 439 /// The computed size usage 440 uint64_t ResourceSize; 441 442 // Threshould passed 443 uint64_t ResourceLimit; 444 445 public: 446 /// \p The function that is concerned by this stack size diagnostic. 447 /// \p The computed stack size. 448 DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName, 449 uint64_t ResourceSize, uint64_t ResourceLimit, 450 DiagnosticSeverity Severity = DS_Warning, 451 DiagnosticKind Kind = DK_ResourceLimit); 452 453 const Function &getFunction() const { return Fn; } 454 const char *getResourceName() const { return ResourceName; } 455 uint64_t getResourceSize() const { return ResourceSize; } 456 uint64_t getResourceLimit() const { return ResourceLimit; } 457 458 /// \see DiagnosticInfo::print. 459 void print(DiagnosticPrinter &DP) const override; 460 461 static bool classof(const DiagnosticInfo *DI) { 462 return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize; 463 } 464 }; 465 466 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit { 467 void anchor() override; 468 469 public: 470 DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize, 471 uint64_t StackLimit, 472 DiagnosticSeverity Severity = DS_Warning) 473 : DiagnosticInfoResourceLimit(Fn, "stack frame size", StackSize, 474 StackLimit, Severity, DK_StackSize) {} 475 476 uint64_t getStackSize() const { return getResourceSize(); } 477 uint64_t getStackLimit() const { return getResourceLimit(); } 478 479 static bool classof(const DiagnosticInfo *DI) { 480 return DI->getKind() == DK_StackSize; 481 } 482 }; 483 484 /// Common features for diagnostics dealing with optimization remarks 485 /// that are used by both IR and MIR passes. 486 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase { 487 public: 488 /// Used to set IsVerbose via the stream interface. 489 struct setIsVerbose {}; 490 491 /// When an instance of this is inserted into the stream, the arguments 492 /// following will not appear in the remark printed in the compiler output 493 /// (-Rpass) but only in the optimization record file 494 /// (-fsave-optimization-record). 495 struct setExtraArgs {}; 496 497 /// Used in the streaming interface as the general argument type. It 498 /// internally converts everything into a key-value pair. 499 struct Argument { 500 std::string Key; 501 std::string Val; 502 // If set, the debug location corresponding to the value. 503 DiagnosticLocation Loc; 504 505 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {} 506 Argument(StringRef Key, const Value *V); 507 Argument(StringRef Key, const Type *T); 508 Argument(StringRef Key, StringRef S); 509 Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {}; 510 Argument(StringRef Key, int N); 511 Argument(StringRef Key, float N); 512 Argument(StringRef Key, long N); 513 Argument(StringRef Key, long long N); 514 Argument(StringRef Key, unsigned N); 515 Argument(StringRef Key, unsigned long N); 516 Argument(StringRef Key, unsigned long long N); 517 Argument(StringRef Key, ElementCount EC); 518 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {} 519 Argument(StringRef Key, DebugLoc dl); 520 Argument(StringRef Key, InstructionCost C); 521 }; 522 523 /// \p PassName is the name of the pass emitting this diagnostic. \p 524 /// RemarkName is a textual identifier for the remark (single-word, 525 /// camel-case). \p Fn is the function where the diagnostic is being emitted. 526 /// \p Loc is the location information to use in the diagnostic. If line table 527 /// information is available, the diagnostic will include the source code 528 /// location. 529 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, 530 enum DiagnosticSeverity Severity, 531 const char *PassName, StringRef RemarkName, 532 const Function &Fn, 533 const DiagnosticLocation &Loc) 534 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc), 535 PassName(PassName), RemarkName(RemarkName) {} 536 537 void insert(StringRef S); 538 void insert(Argument A); 539 void insert(setIsVerbose V); 540 void insert(setExtraArgs EA); 541 542 /// \see DiagnosticInfo::print. 543 void print(DiagnosticPrinter &DP) const override; 544 545 /// Return true if this optimization remark is enabled by one of 546 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed, 547 /// or -pass-remarks-analysis). Note that this only handles the LLVM 548 /// flags. We cannot access Clang flags from here (they are handled 549 /// in BackendConsumer::OptimizationRemarkHandler). 550 virtual bool isEnabled() const = 0; 551 552 StringRef getPassName() const { return PassName; } 553 StringRef getRemarkName() const { return RemarkName; } 554 std::string getMsg() const; 555 std::optional<uint64_t> getHotness() const { return Hotness; } 556 void setHotness(std::optional<uint64_t> H) { Hotness = H; } 557 558 bool isVerbose() const { return IsVerbose; } 559 560 ArrayRef<Argument> getArgs() const { return Args; } 561 562 static bool classof(const DiagnosticInfo *DI) { 563 return (DI->getKind() >= DK_FirstRemark && 564 DI->getKind() <= DK_LastRemark) || 565 (DI->getKind() >= DK_FirstMachineRemark && 566 DI->getKind() <= DK_LastMachineRemark); 567 } 568 569 bool isPassed() const { 570 return (getKind() == DK_OptimizationRemark || 571 getKind() == DK_MachineOptimizationRemark); 572 } 573 574 bool isMissed() const { 575 return (getKind() == DK_OptimizationRemarkMissed || 576 getKind() == DK_MachineOptimizationRemarkMissed); 577 } 578 579 bool isAnalysis() const { 580 return (getKind() == DK_OptimizationRemarkAnalysis || 581 getKind() == DK_MachineOptimizationRemarkAnalysis); 582 } 583 584 protected: 585 /// Name of the pass that triggers this report. If this matches the 586 /// regular expression given in -Rpass=regexp, then the remark will 587 /// be emitted. 588 const char *PassName; 589 590 /// Textual identifier for the remark (single-word, camel-case). Can be used 591 /// by external tools reading the output file for optimization remarks to 592 /// identify the remark. 593 StringRef RemarkName; 594 595 /// If profile information is available, this is the number of times the 596 /// corresponding code was executed in a profile instrumentation run. 597 std::optional<uint64_t> Hotness; 598 599 /// Arguments collected via the streaming interface. 600 SmallVector<Argument, 4> Args; 601 602 /// The remark is expected to be noisy. 603 bool IsVerbose = false; 604 605 /// If positive, the index of the first argument that only appear in 606 /// the optimization records and not in the remark printed in the compiler 607 /// output. 608 int FirstExtraArgIndex = -1; 609 }; 610 611 /// Allow the insertion operator to return the actual remark type rather than a 612 /// common base class. This allows returning the result of the insertion 613 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". 614 template <class RemarkT> 615 RemarkT & 616 operator<<(RemarkT &R, 617 std::enable_if_t< 618 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 619 StringRef> 620 S) { 621 R.insert(S); 622 return R; 623 } 624 625 /// Also allow r-value for the remark to allow insertion into a 626 /// temporarily-constructed remark. 627 template <class RemarkT> 628 RemarkT & 629 operator<<(RemarkT &&R, 630 std::enable_if_t< 631 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 632 StringRef> 633 S) { 634 R.insert(S); 635 return R; 636 } 637 638 template <class RemarkT> 639 RemarkT & 640 operator<<(RemarkT &R, 641 std::enable_if_t< 642 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 643 DiagnosticInfoOptimizationBase::Argument> 644 A) { 645 R.insert(A); 646 return R; 647 } 648 649 template <class RemarkT> 650 RemarkT & 651 operator<<(RemarkT &&R, 652 std::enable_if_t< 653 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 654 DiagnosticInfoOptimizationBase::Argument> 655 A) { 656 R.insert(A); 657 return R; 658 } 659 660 template <class RemarkT> 661 RemarkT & 662 operator<<(RemarkT &R, 663 std::enable_if_t< 664 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 665 DiagnosticInfoOptimizationBase::setIsVerbose> 666 V) { 667 R.insert(V); 668 return R; 669 } 670 671 template <class RemarkT> 672 RemarkT & 673 operator<<(RemarkT &&R, 674 std::enable_if_t< 675 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 676 DiagnosticInfoOptimizationBase::setIsVerbose> 677 V) { 678 R.insert(V); 679 return R; 680 } 681 682 template <class RemarkT> 683 RemarkT & 684 operator<<(RemarkT &R, 685 std::enable_if_t< 686 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value, 687 DiagnosticInfoOptimizationBase::setExtraArgs> 688 EA) { 689 R.insert(EA); 690 return R; 691 } 692 693 /// Common features for diagnostics dealing with optimization remarks 694 /// that are used by IR passes. 695 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { 696 void anchor() override; 697 public: 698 /// \p PassName is the name of the pass emitting this diagnostic. \p 699 /// RemarkName is a textual identifier for the remark (single-word, 700 /// camel-case). \p Fn is the function where the diagnostic is being emitted. 701 /// \p Loc is the location information to use in the diagnostic. If line table 702 /// information is available, the diagnostic will include the source code 703 /// location. \p CodeRegion is IR value (currently basic block) that the 704 /// optimization operates on. This is currently used to provide run-time 705 /// hotness information with PGO. 706 DiagnosticInfoIROptimization(enum DiagnosticKind Kind, 707 enum DiagnosticSeverity Severity, 708 const char *PassName, StringRef RemarkName, 709 const Function &Fn, 710 const DiagnosticLocation &Loc, 711 const Value *CodeRegion = nullptr) 712 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn, 713 Loc), 714 CodeRegion(CodeRegion) {} 715 716 /// This is ctor variant allows a pass to build an optimization remark 717 /// from an existing remark. 718 /// 719 /// This is useful when a transformation pass (e.g LV) wants to emit a remark 720 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis 721 /// remark. The string \p Prepend will be emitted before the original 722 /// message. 723 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend, 724 const DiagnosticInfoIROptimization &Orig) 725 : DiagnosticInfoOptimizationBase( 726 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName, 727 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()), 728 CodeRegion(Orig.getCodeRegion()) { 729 *this << Prepend; 730 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args)); 731 } 732 733 /// Legacy interface. 734 /// \p PassName is the name of the pass emitting this diagnostic. 735 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 736 /// the location information to use in the diagnostic. If line table 737 /// information is available, the diagnostic will include the source code 738 /// location. \p Msg is the message to show. Note that this class does not 739 /// copy this message, so this reference must be valid for the whole life time 740 /// of the diagnostic. 741 DiagnosticInfoIROptimization(enum DiagnosticKind Kind, 742 enum DiagnosticSeverity Severity, 743 const char *PassName, const Function &Fn, 744 const DiagnosticLocation &Loc, const Twine &Msg) 745 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) { 746 *this << Msg.str(); 747 } 748 749 const Value *getCodeRegion() const { return CodeRegion; } 750 751 static bool classof(const DiagnosticInfo *DI) { 752 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark; 753 } 754 755 private: 756 /// The IR value (currently basic block) that the optimization operates on. 757 /// This is currently used to provide run-time hotness information with PGO. 758 const Value *CodeRegion = nullptr; 759 }; 760 761 /// Diagnostic information for applied optimization remarks. 762 class OptimizationRemark : public DiagnosticInfoIROptimization { 763 public: 764 /// \p PassName is the name of the pass emitting this diagnostic. If this name 765 /// matches the regular expression given in -Rpass=, then the diagnostic will 766 /// be emitted. \p RemarkName is a textual identifier for the remark (single- 767 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the 768 /// region that the optimization operates on (currently only block is 769 /// supported). 770 OptimizationRemark(const char *PassName, StringRef RemarkName, 771 const DiagnosticLocation &Loc, const Value *CodeRegion); 772 773 /// Same as above, but the debug location and code region are derived from \p 774 /// Instr. 775 OptimizationRemark(const char *PassName, StringRef RemarkName, 776 const Instruction *Inst); 777 778 /// Same as above, but the debug location and code region are derived from \p 779 /// Func. 780 OptimizationRemark(const char *PassName, StringRef RemarkName, 781 const Function *Func); 782 783 static bool classof(const DiagnosticInfo *DI) { 784 return DI->getKind() == DK_OptimizationRemark; 785 } 786 787 /// \see DiagnosticInfoOptimizationBase::isEnabled. 788 bool isEnabled() const override; 789 790 private: 791 /// This is deprecated now and only used by the function API below. 792 /// \p PassName is the name of the pass emitting this diagnostic. If 793 /// this name matches the regular expression given in -Rpass=, then the 794 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 795 /// is being emitted. \p Loc is the location information to use in the 796 /// diagnostic. If line table information is available, the diagnostic 797 /// will include the source code location. \p Msg is the message to show. 798 /// Note that this class does not copy this message, so this reference 799 /// must be valid for the whole life time of the diagnostic. 800 OptimizationRemark(const char *PassName, const Function &Fn, 801 const DiagnosticLocation &Loc, const Twine &Msg) 802 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, 803 Fn, Loc, Msg) {} 804 }; 805 806 /// Diagnostic information for missed-optimization remarks. 807 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization { 808 public: 809 /// \p PassName is the name of the pass emitting this diagnostic. If this name 810 /// matches the regular expression given in -Rpass-missed=, then the 811 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 812 /// remark (single-word, camel-case). \p Loc is the debug location and \p 813 /// CodeRegion is the region that the optimization operates on (currently only 814 /// block is supported). 815 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 816 const DiagnosticLocation &Loc, 817 const Value *CodeRegion); 818 819 /// Same as above but \p Inst is used to derive code region and debug 820 /// location. 821 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 822 const Instruction *Inst); 823 824 /// Same as above but \p F is used to derive code region and debug 825 /// location. 826 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, 827 const Function *F); 828 829 static bool classof(const DiagnosticInfo *DI) { 830 return DI->getKind() == DK_OptimizationRemarkMissed; 831 } 832 833 /// \see DiagnosticInfoOptimizationBase::isEnabled. 834 bool isEnabled() const override; 835 836 private: 837 /// This is deprecated now and only used by the function API below. 838 /// \p PassName is the name of the pass emitting this diagnostic. If 839 /// this name matches the regular expression given in -Rpass-missed=, then the 840 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 841 /// is being emitted. \p Loc is the location information to use in the 842 /// diagnostic. If line table information is available, the diagnostic 843 /// will include the source code location. \p Msg is the message to show. 844 /// Note that this class does not copy this message, so this reference 845 /// must be valid for the whole life time of the diagnostic. 846 OptimizationRemarkMissed(const char *PassName, const Function &Fn, 847 const DiagnosticLocation &Loc, const Twine &Msg) 848 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, 849 PassName, Fn, Loc, Msg) {} 850 }; 851 852 /// Diagnostic information for optimization analysis remarks. 853 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization { 854 public: 855 /// \p PassName is the name of the pass emitting this diagnostic. If this name 856 /// matches the regular expression given in -Rpass-analysis=, then the 857 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 858 /// remark (single-word, camel-case). \p Loc is the debug location and \p 859 /// CodeRegion is the region that the optimization operates on (currently only 860 /// block is supported). 861 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 862 const DiagnosticLocation &Loc, 863 const Value *CodeRegion); 864 865 /// This is ctor variant allows a pass to build an optimization remark 866 /// from an existing remark. 867 /// 868 /// This is useful when a transformation pass (e.g LV) wants to emit a remark 869 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis 870 /// remark. The string \p Prepend will be emitted before the original 871 /// message. 872 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend, 873 const OptimizationRemarkAnalysis &Orig) 874 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {} 875 876 /// Same as above but \p Inst is used to derive code region and debug 877 /// location. 878 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 879 const Instruction *Inst); 880 881 /// Same as above but \p F is used to derive code region and debug 882 /// location. 883 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, 884 const Function *F); 885 886 static bool classof(const DiagnosticInfo *DI) { 887 return DI->getKind() == DK_OptimizationRemarkAnalysis; 888 } 889 890 /// \see DiagnosticInfoOptimizationBase::isEnabled. 891 bool isEnabled() const override; 892 893 static const char *AlwaysPrint; 894 895 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; } 896 897 protected: 898 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, 899 const Function &Fn, const DiagnosticLocation &Loc, 900 const Twine &Msg) 901 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {} 902 903 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, 904 StringRef RemarkName, 905 const DiagnosticLocation &Loc, 906 const Value *CodeRegion); 907 908 private: 909 /// This is deprecated now and only used by the function API below. 910 /// \p PassName is the name of the pass emitting this diagnostic. If 911 /// this name matches the regular expression given in -Rpass-analysis=, then 912 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 913 /// is being emitted. \p Loc is the location information to use in the 914 /// diagnostic. If line table information is available, the diagnostic will 915 /// include the source code location. \p Msg is the message to show. Note that 916 /// this class does not copy this message, so this reference must be valid for 917 /// the whole life time of the diagnostic. 918 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn, 919 const DiagnosticLocation &Loc, const Twine &Msg) 920 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, 921 PassName, Fn, Loc, Msg) {} 922 }; 923 924 /// Diagnostic information for optimization analysis remarks related to 925 /// floating-point non-commutativity. 926 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis { 927 void anchor() override; 928 public: 929 /// \p PassName is the name of the pass emitting this diagnostic. If this name 930 /// matches the regular expression given in -Rpass-analysis=, then the 931 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 932 /// remark (single-word, camel-case). \p Loc is the debug location and \p 933 /// CodeRegion is the region that the optimization operates on (currently only 934 /// block is supported). The front-end will append its own message related to 935 /// options that address floating-point non-commutativity. 936 OptimizationRemarkAnalysisFPCommute(const char *PassName, 937 StringRef RemarkName, 938 const DiagnosticLocation &Loc, 939 const Value *CodeRegion) 940 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, 941 PassName, RemarkName, Loc, CodeRegion) {} 942 943 static bool classof(const DiagnosticInfo *DI) { 944 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; 945 } 946 947 private: 948 /// This is deprecated now and only used by the function API below. 949 /// \p PassName is the name of the pass emitting this diagnostic. If 950 /// this name matches the regular expression given in -Rpass-analysis=, then 951 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 952 /// is being emitted. \p Loc is the location information to use in the 953 /// diagnostic. If line table information is available, the diagnostic will 954 /// include the source code location. \p Msg is the message to show. The 955 /// front-end will append its own message related to options that address 956 /// floating-point non-commutativity. Note that this class does not copy this 957 /// message, so this reference must be valid for the whole life time of the 958 /// diagnostic. 959 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn, 960 const DiagnosticLocation &Loc, 961 const Twine &Msg) 962 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, 963 PassName, Fn, Loc, Msg) {} 964 }; 965 966 /// Diagnostic information for optimization analysis remarks related to 967 /// pointer aliasing. 968 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis { 969 void anchor() override; 970 public: 971 /// \p PassName is the name of the pass emitting this diagnostic. If this name 972 /// matches the regular expression given in -Rpass-analysis=, then the 973 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the 974 /// remark (single-word, camel-case). \p Loc is the debug location and \p 975 /// CodeRegion is the region that the optimization operates on (currently only 976 /// block is supported). The front-end will append its own message related to 977 /// options that address pointer aliasing legality. 978 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName, 979 const DiagnosticLocation &Loc, 980 const Value *CodeRegion) 981 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, 982 PassName, RemarkName, Loc, CodeRegion) {} 983 984 static bool classof(const DiagnosticInfo *DI) { 985 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; 986 } 987 988 private: 989 /// This is deprecated now and only used by the function API below. 990 /// \p PassName is the name of the pass emitting this diagnostic. If 991 /// this name matches the regular expression given in -Rpass-analysis=, then 992 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 993 /// is being emitted. \p Loc is the location information to use in the 994 /// diagnostic. If line table information is available, the diagnostic will 995 /// include the source code location. \p Msg is the message to show. The 996 /// front-end will append its own message related to options that address 997 /// pointer aliasing legality. Note that this class does not copy this 998 /// message, so this reference must be valid for the whole life time of the 999 /// diagnostic. 1000 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn, 1001 const DiagnosticLocation &Loc, 1002 const Twine &Msg) 1003 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, 1004 PassName, Fn, Loc, Msg) {} 1005 }; 1006 1007 /// Diagnostic information for machine IR parser. 1008 // FIXME: Remove this, use DiagnosticInfoSrcMgr instead. 1009 class DiagnosticInfoMIRParser : public DiagnosticInfo { 1010 const SMDiagnostic &Diagnostic; 1011 1012 public: 1013 DiagnosticInfoMIRParser(DiagnosticSeverity Severity, 1014 const SMDiagnostic &Diagnostic) 1015 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {} 1016 1017 const SMDiagnostic &getDiagnostic() const { return Diagnostic; } 1018 1019 void print(DiagnosticPrinter &DP) const override; 1020 1021 static bool classof(const DiagnosticInfo *DI) { 1022 return DI->getKind() == DK_MIRParser; 1023 } 1024 }; 1025 1026 /// Diagnostic information for IR instrumentation reporting. 1027 class DiagnosticInfoInstrumentation : public DiagnosticInfo { 1028 const Twine &Msg; 1029 1030 public: 1031 DiagnosticInfoInstrumentation(const Twine &DiagMsg, 1032 DiagnosticSeverity Severity = DS_Warning) 1033 : DiagnosticInfo(DK_Instrumentation, Severity), Msg(DiagMsg) {} 1034 1035 void print(DiagnosticPrinter &DP) const override; 1036 1037 static bool classof(const DiagnosticInfo *DI) { 1038 return DI->getKind() == DK_Instrumentation; 1039 } 1040 }; 1041 1042 /// Diagnostic information for ISel fallback path. 1043 class DiagnosticInfoISelFallback : public DiagnosticInfo { 1044 /// The function that is concerned by this diagnostic. 1045 const Function &Fn; 1046 1047 public: 1048 DiagnosticInfoISelFallback(const Function &Fn, 1049 DiagnosticSeverity Severity = DS_Warning) 1050 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {} 1051 1052 const Function &getFunction() const { return Fn; } 1053 1054 void print(DiagnosticPrinter &DP) const override; 1055 1056 static bool classof(const DiagnosticInfo *DI) { 1057 return DI->getKind() == DK_ISelFallback; 1058 } 1059 }; 1060 1061 // Create wrappers for C Binding types (see CBindingWrapping.h). 1062 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef) 1063 1064 /// Diagnostic information for optimization failures. 1065 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization { 1066 public: 1067 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 1068 /// the location information to use in the diagnostic. If line table 1069 /// information is available, the diagnostic will include the source code 1070 /// location. \p Msg is the message to show. Note that this class does not 1071 /// copy this message, so this reference must be valid for the whole life time 1072 /// of the diagnostic. 1073 DiagnosticInfoOptimizationFailure(const Function &Fn, 1074 const DiagnosticLocation &Loc, 1075 const Twine &Msg) 1076 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning, 1077 nullptr, Fn, Loc, Msg) {} 1078 1079 /// \p PassName is the name of the pass emitting this diagnostic. \p 1080 /// RemarkName is a textual identifier for the remark (single-word, 1081 /// camel-case). \p Loc is the debug location and \p CodeRegion is the 1082 /// region that the optimization operates on (currently basic block is 1083 /// supported). 1084 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName, 1085 const DiagnosticLocation &Loc, 1086 const Value *CodeRegion); 1087 1088 static bool classof(const DiagnosticInfo *DI) { 1089 return DI->getKind() == DK_OptimizationFailure; 1090 } 1091 1092 /// \see DiagnosticInfoOptimizationBase::isEnabled. 1093 bool isEnabled() const override; 1094 }; 1095 1096 /// Diagnostic information for unsupported feature in backend. 1097 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase { 1098 private: 1099 Twine Msg; 1100 1101 public: 1102 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is 1103 /// the location information to use in the diagnostic. If line table 1104 /// information is available, the diagnostic will include the source code 1105 /// location. \p Msg is the message to show. Note that this class does not 1106 /// copy this message, so this reference must be valid for the whole life time 1107 /// of the diagnostic. 1108 DiagnosticInfoUnsupported( 1109 const Function &Fn, const Twine &Msg, 1110 const DiagnosticLocation &Loc = DiagnosticLocation(), 1111 DiagnosticSeverity Severity = DS_Error) 1112 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc), 1113 Msg(Msg) {} 1114 1115 static bool classof(const DiagnosticInfo *DI) { 1116 return DI->getKind() == DK_Unsupported; 1117 } 1118 1119 const Twine &getMessage() const { return Msg; } 1120 1121 void print(DiagnosticPrinter &DP) const override; 1122 }; 1123 1124 /// Diagnostic information for MisExpect analysis. 1125 class DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase { 1126 public: 1127 DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg); 1128 1129 /// \see DiagnosticInfo::print. 1130 void print(DiagnosticPrinter &DP) const override; 1131 1132 static bool classof(const DiagnosticInfo *DI) { 1133 return DI->getKind() == DK_MisExpect; 1134 } 1135 1136 const Twine &getMsg() const { return Msg; } 1137 1138 private: 1139 /// Message to report. 1140 const Twine &Msg; 1141 }; 1142 1143 static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) { 1144 switch (DK) { 1145 case llvm::SourceMgr::DK_Error: 1146 return DS_Error; 1147 break; 1148 case llvm::SourceMgr::DK_Warning: 1149 return DS_Warning; 1150 break; 1151 case llvm::SourceMgr::DK_Note: 1152 return DS_Note; 1153 break; 1154 case llvm::SourceMgr::DK_Remark: 1155 return DS_Remark; 1156 break; 1157 } 1158 llvm_unreachable("unknown SourceMgr::DiagKind"); 1159 } 1160 1161 /// Diagnostic information for SMDiagnostic reporting. 1162 class DiagnosticInfoSrcMgr : public DiagnosticInfo { 1163 const SMDiagnostic &Diagnostic; 1164 StringRef ModName; 1165 1166 // For inlineasm !srcloc translation. 1167 bool InlineAsmDiag; 1168 uint64_t LocCookie; 1169 1170 public: 1171 DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic, StringRef ModName, 1172 bool InlineAsmDiag = true, uint64_t LocCookie = 0) 1173 : DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())), 1174 Diagnostic(Diagnostic), ModName(ModName), InlineAsmDiag(InlineAsmDiag), 1175 LocCookie(LocCookie) {} 1176 1177 StringRef getModuleName() const { return ModName; } 1178 bool isInlineAsmDiag() const { return InlineAsmDiag; } 1179 const SMDiagnostic &getSMDiag() const { return Diagnostic; } 1180 uint64_t getLocCookie() const { return LocCookie; } 1181 void print(DiagnosticPrinter &DP) const override; 1182 1183 static bool classof(const DiagnosticInfo *DI) { 1184 return DI->getKind() == DK_SrcMgr; 1185 } 1186 }; 1187 1188 void diagnoseDontCall(const CallInst &CI); 1189 1190 class DiagnosticInfoDontCall : public DiagnosticInfo { 1191 StringRef CalleeName; 1192 StringRef Note; 1193 uint64_t LocCookie; 1194 1195 public: 1196 DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note, 1197 DiagnosticSeverity DS, uint64_t LocCookie) 1198 : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note), 1199 LocCookie(LocCookie) {} 1200 StringRef getFunctionName() const { return CalleeName; } 1201 StringRef getNote() const { return Note; } 1202 uint64_t getLocCookie() const { return LocCookie; } 1203 void print(DiagnosticPrinter &DP) const override; 1204 static bool classof(const DiagnosticInfo *DI) { 1205 return DI->getKind() == DK_DontCall; 1206 } 1207 }; 1208 1209 } // end namespace llvm 1210 1211 #endif // LLVM_IR_DIAGNOSTICINFO_H 1212