1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- 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 // This file declares the different classes involved in low level diagnostics. 11 // 12 // Diagnostics reporting is still done as part of the LLVMContext. 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_DIAGNOSTICINFO_H 16 #define LLVM_IR_DIAGNOSTICINFO_H 17 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/IR/DebugLoc.h" 21 #include "llvm/Support/CBindingWrapping.h" 22 #include "llvm-c/Types.h" 23 #include <functional> 24 #include <string> 25 26 namespace llvm { 27 28 // Forward declarations. 29 class DiagnosticPrinter; 30 class Function; 31 class Instruction; 32 class LLVMContext; 33 class Module; 34 class SMDiagnostic; 35 36 /// \brief Defines the different supported severity of a diagnostic. 37 enum DiagnosticSeverity : char { 38 DS_Error, 39 DS_Warning, 40 DS_Remark, 41 // A note attaches additional information to one of the previous diagnostic 42 // types. 43 DS_Note 44 }; 45 46 /// \brief Defines the different supported kind of a diagnostic. 47 /// This enum should be extended with a new ID for each added concrete subclass. 48 enum DiagnosticKind { 49 DK_Bitcode, 50 DK_InlineAsm, 51 DK_ResourceLimit, 52 DK_StackSize, 53 DK_Linker, 54 DK_DebugMetadataVersion, 55 DK_DebugMetadataInvalid, 56 DK_SampleProfile, 57 DK_OptimizationRemark, 58 DK_OptimizationRemarkMissed, 59 DK_OptimizationRemarkAnalysis, 60 DK_OptimizationRemarkAnalysisFPCommute, 61 DK_OptimizationRemarkAnalysisAliasing, 62 DK_OptimizationFailure, 63 DK_FirstRemark = DK_OptimizationRemark, 64 DK_LastRemark = DK_OptimizationFailure, 65 DK_MIRParser, 66 DK_PGOProfile, 67 DK_Unsupported, 68 DK_FirstPluginKind 69 }; 70 71 /// \brief Get the next available kind ID for a plugin diagnostic. 72 /// Each time this function is called, it returns a different number. 73 /// Therefore, a plugin that wants to "identify" its own classes 74 /// with a dynamic identifier, just have to use this method to get a new ID 75 /// and assign it to each of its classes. 76 /// The returned ID will be greater than or equal to DK_FirstPluginKind. 77 /// Thus, the plugin identifiers will not conflict with the 78 /// DiagnosticKind values. 79 int getNextAvailablePluginDiagnosticKind(); 80 81 /// \brief This is the base abstract class for diagnostic reporting in 82 /// the backend. 83 /// The print method must be overloaded by the subclasses to print a 84 /// user-friendly message in the client of the backend (let us call it a 85 /// frontend). 86 class DiagnosticInfo { 87 private: 88 /// Kind defines the kind of report this is about. 89 const /* DiagnosticKind */ int Kind; 90 /// Severity gives the severity of the diagnostic. 91 const DiagnosticSeverity Severity; 92 93 public: DiagnosticInfo(int Kind,DiagnosticSeverity Severity)94 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity) 95 : Kind(Kind), Severity(Severity) {} 96 ~DiagnosticInfo()97 virtual ~DiagnosticInfo() {} 98 getKind()99 /* DiagnosticKind */ int getKind() const { return Kind; } getSeverity()100 DiagnosticSeverity getSeverity() const { return Severity; } 101 102 /// Print using the given \p DP a user-friendly message. 103 /// This is the default message that will be printed to the user. 104 /// It is used when the frontend does not directly take advantage 105 /// of the information contained in fields of the subclasses. 106 /// The printed message must not end with '.' nor start with a severity 107 /// keyword. 108 virtual void print(DiagnosticPrinter &DP) const = 0; 109 }; 110 111 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction; 112 113 /// Diagnostic information for inline asm reporting. 114 /// This is basically a message and an optional location. 115 class DiagnosticInfoInlineAsm : public DiagnosticInfo { 116 private: 117 /// Optional line information. 0 if not set. 118 unsigned LocCookie; 119 /// Message to be reported. 120 const Twine &MsgStr; 121 /// Optional origin of the problem. 122 const Instruction *Instr; 123 124 public: 125 /// \p MsgStr is the message to be reported to the frontend. 126 /// This class does not copy \p MsgStr, therefore the reference must be valid 127 /// for the whole life time of the Diagnostic. 128 DiagnosticInfoInlineAsm(const Twine &MsgStr, 129 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_InlineAsm,Severity)130 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), 131 Instr(nullptr) {} 132 133 /// \p LocCookie if non-zero gives the line number for this report. 134 /// \p MsgStr gives the message. 135 /// This class does not copy \p MsgStr, therefore the reference must be valid 136 /// for the whole life time of the Diagnostic. 137 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr, 138 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_InlineAsm,Severity)139 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie), 140 MsgStr(MsgStr), Instr(nullptr) {} 141 142 /// \p Instr gives the original instruction that triggered the diagnostic. 143 /// \p MsgStr gives the message. 144 /// This class does not copy \p MsgStr, therefore the reference must be valid 145 /// for the whole life time of the Diagnostic. 146 /// Same for \p I. 147 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr, 148 DiagnosticSeverity Severity = DS_Error); 149 getLocCookie()150 unsigned getLocCookie() const { return LocCookie; } getMsgStr()151 const Twine &getMsgStr() const { return MsgStr; } getInstruction()152 const Instruction *getInstruction() const { return Instr; } 153 154 /// \see DiagnosticInfo::print. 155 void print(DiagnosticPrinter &DP) const override; 156 classof(const DiagnosticInfo * DI)157 static bool classof(const DiagnosticInfo *DI) { 158 return DI->getKind() == DK_InlineAsm; 159 } 160 }; 161 162 /// Diagnostic information for stack size etc. reporting. 163 /// This is basically a function and a size. 164 class DiagnosticInfoResourceLimit : public DiagnosticInfo { 165 private: 166 /// The function that is concerned by this resource limit diagnostic. 167 const Function &Fn; 168 169 /// Description of the resource type (e.g. stack size) 170 const char *ResourceName; 171 172 /// The computed size usage 173 uint64_t ResourceSize; 174 175 // Threshould passed 176 uint64_t ResourceLimit; 177 178 public: 179 /// \p The function that is concerned by this stack size diagnostic. 180 /// \p The computed stack size. 181 DiagnosticInfoResourceLimit(const Function &Fn, 182 const char *ResourceName, 183 uint64_t ResourceSize, 184 DiagnosticSeverity Severity = DS_Warning, 185 DiagnosticKind Kind = DK_ResourceLimit, 186 uint64_t ResourceLimit = 0) DiagnosticInfo(Kind,Severity)187 : DiagnosticInfo(Kind, Severity), 188 Fn(Fn), 189 ResourceName(ResourceName), 190 ResourceSize(ResourceSize), 191 ResourceLimit(ResourceLimit) {} 192 getFunction()193 const Function &getFunction() const { return Fn; } getResourceName()194 const char *getResourceName() const { return ResourceName; } getResourceSize()195 uint64_t getResourceSize() const { return ResourceSize; } getResourceLimit()196 uint64_t getResourceLimit() const { return ResourceLimit; } 197 198 /// \see DiagnosticInfo::print. 199 void print(DiagnosticPrinter &DP) const override; 200 classof(const DiagnosticInfo * DI)201 static bool classof(const DiagnosticInfo *DI) { 202 return DI->getKind() == DK_ResourceLimit || 203 DI->getKind() == DK_StackSize; 204 } 205 }; 206 207 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit { 208 public: 209 DiagnosticInfoStackSize(const Function &Fn, 210 uint64_t StackSize, 211 DiagnosticSeverity Severity = DS_Warning, 212 uint64_t StackLimit = 0) 213 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, 214 Severity, DK_StackSize, StackLimit) {} 215 getStackSize()216 uint64_t getStackSize() const { return getResourceSize(); } getStackLimit()217 uint64_t getStackLimit() const { return getResourceLimit(); } 218 classof(const DiagnosticInfo * DI)219 static bool classof(const DiagnosticInfo *DI) { 220 return DI->getKind() == DK_StackSize; 221 } 222 }; 223 224 /// Diagnostic information for debug metadata version reporting. 225 /// This is basically a module and a version. 226 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo { 227 private: 228 /// The module that is concerned by this debug metadata version diagnostic. 229 const Module &M; 230 /// The actual metadata version. 231 unsigned MetadataVersion; 232 233 public: 234 /// \p The module that is concerned by this debug metadata version diagnostic. 235 /// \p The actual metadata version. 236 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion, 237 DiagnosticSeverity Severity = DS_Warning) DiagnosticInfo(DK_DebugMetadataVersion,Severity)238 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M), 239 MetadataVersion(MetadataVersion) {} 240 getModule()241 const Module &getModule() const { return M; } getMetadataVersion()242 unsigned getMetadataVersion() const { return MetadataVersion; } 243 244 /// \see DiagnosticInfo::print. 245 void print(DiagnosticPrinter &DP) const override; 246 classof(const DiagnosticInfo * DI)247 static bool classof(const DiagnosticInfo *DI) { 248 return DI->getKind() == DK_DebugMetadataVersion; 249 } 250 }; 251 252 /// Diagnostic information for stripping invalid debug metadata. 253 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo { 254 private: 255 /// The module that is concerned by this debug metadata version diagnostic. 256 const Module &M; 257 258 public: 259 /// \p The module that is concerned by this debug metadata version diagnostic. 260 DiagnosticInfoIgnoringInvalidDebugMetadata( 261 const Module &M, DiagnosticSeverity Severity = DS_Warning) DiagnosticInfo(DK_DebugMetadataVersion,Severity)262 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {} 263 getModule()264 const Module &getModule() const { return M; } 265 266 /// \see DiagnosticInfo::print. 267 void print(DiagnosticPrinter &DP) const override; 268 classof(const DiagnosticInfo * DI)269 static bool classof(const DiagnosticInfo *DI) { 270 return DI->getKind() == DK_DebugMetadataInvalid; 271 } 272 }; 273 274 275 /// Diagnostic information for the sample profiler. 276 class DiagnosticInfoSampleProfile : public DiagnosticInfo { 277 public: 278 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum, 279 const Twine &Msg, 280 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_SampleProfile,Severity)281 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 282 LineNum(LineNum), Msg(Msg) {} 283 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, 284 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_SampleProfile,Severity)285 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), 286 LineNum(0), Msg(Msg) {} 287 DiagnosticInfoSampleProfile(const Twine &Msg, 288 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_SampleProfile,Severity)289 : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {} 290 291 /// \see DiagnosticInfo::print. 292 void print(DiagnosticPrinter &DP) const override; 293 classof(const DiagnosticInfo * DI)294 static bool classof(const DiagnosticInfo *DI) { 295 return DI->getKind() == DK_SampleProfile; 296 } 297 getFileName()298 StringRef getFileName() const { return FileName; } getLineNum()299 unsigned getLineNum() const { return LineNum; } getMsg()300 const Twine &getMsg() const { return Msg; } 301 302 private: 303 /// Name of the input file associated with this diagnostic. 304 StringRef FileName; 305 306 /// Line number where the diagnostic occurred. If 0, no line number will 307 /// be emitted in the message. 308 unsigned LineNum; 309 310 /// Message to report. 311 const Twine &Msg; 312 }; 313 314 /// Diagnostic information for the PGO profiler. 315 class DiagnosticInfoPGOProfile : public DiagnosticInfo { 316 public: 317 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg, 318 DiagnosticSeverity Severity = DS_Error) DiagnosticInfo(DK_PGOProfile,Severity)319 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {} 320 321 /// \see DiagnosticInfo::print. 322 void print(DiagnosticPrinter &DP) const override; 323 classof(const DiagnosticInfo * DI)324 static bool classof(const DiagnosticInfo *DI) { 325 return DI->getKind() == DK_PGOProfile; 326 } 327 getFileName()328 const char *getFileName() const { return FileName; } getMsg()329 const Twine &getMsg() const { return Msg; } 330 331 private: 332 /// Name of the input file associated with this diagnostic. 333 const char *FileName; 334 335 /// Message to report. 336 const Twine &Msg; 337 }; 338 339 /// Common features for diagnostics with an associated DebugLoc 340 class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo { 341 public: 342 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 343 /// the location information to use in the diagnostic. DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind,enum DiagnosticSeverity Severity,const Function & Fn,const DebugLoc & DLoc)344 DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind, 345 enum DiagnosticSeverity Severity, 346 const Function &Fn, 347 const DebugLoc &DLoc) 348 : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {} 349 350 /// Return true if location information is available for this diagnostic. 351 bool isLocationAvailable() const; 352 353 /// Return a string with the location information for this diagnostic 354 /// in the format "file:line:col". If location information is not available, 355 /// it returns "<unknown>:0:0". 356 const std::string getLocationStr() const; 357 358 /// Return location information for this diagnostic in three parts: 359 /// the source file name, line number and column. 360 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const; 361 getFunction()362 const Function &getFunction() const { return Fn; } getDebugLoc()363 const DebugLoc &getDebugLoc() const { return DLoc; } 364 365 private: 366 /// Function where this diagnostic is triggered. 367 const Function &Fn; 368 369 /// Debug location where this diagnostic is triggered. 370 DebugLoc DLoc; 371 }; 372 373 /// Common features for diagnostics dealing with optimization remarks. 374 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase { 375 public: 376 /// \p PassName is the name of the pass emitting this diagnostic. 377 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 378 /// the location information to use in the diagnostic. If line table 379 /// information is available, the diagnostic will include the source code 380 /// location. \p Msg is the message to show. Note that this class does not 381 /// copy this message, so this reference must be valid for the whole life time 382 /// of the diagnostic. DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,enum DiagnosticSeverity Severity,const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)383 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, 384 enum DiagnosticSeverity Severity, 385 const char *PassName, const Function &Fn, 386 const DebugLoc &DLoc, const Twine &Msg) 387 : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), 388 PassName(PassName), Msg(Msg) {} 389 390 /// \see DiagnosticInfo::print. 391 void print(DiagnosticPrinter &DP) const override; 392 393 /// Return true if this optimization remark is enabled by one of 394 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed, 395 /// or -pass-remarks-analysis). Note that this only handles the LLVM 396 /// flags. We cannot access Clang flags from here (they are handled 397 /// in BackendConsumer::OptimizationRemarkHandler). 398 virtual bool isEnabled() const = 0; 399 getPassName()400 const char *getPassName() const { return PassName; } getMsg()401 const Twine &getMsg() const { return Msg; } 402 classof(const DiagnosticInfo * DI)403 static bool classof(const DiagnosticInfo *DI) { 404 return DI->getKind() >= DK_FirstRemark && 405 DI->getKind() <= DK_LastRemark; 406 } 407 408 private: 409 /// Name of the pass that triggers this report. If this matches the 410 /// regular expression given in -Rpass=regexp, then the remark will 411 /// be emitted. 412 const char *PassName; 413 414 /// Message to report. 415 const Twine &Msg; 416 }; 417 418 /// Diagnostic information for applied optimization remarks. 419 class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase { 420 public: 421 /// \p PassName is the name of the pass emitting this diagnostic. If 422 /// this name matches the regular expression given in -Rpass=, then the 423 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 424 /// is being emitted. \p DLoc is the location information to use in the 425 /// diagnostic. If line table information is available, the diagnostic 426 /// will include the source code location. \p Msg is the message to show. 427 /// Note that this class does not copy this message, so this reference 428 /// must be valid for the whole life time of the diagnostic. DiagnosticInfoOptimizationRemark(const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)429 DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn, 430 const DebugLoc &DLoc, const Twine &Msg) 431 : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, 432 PassName, Fn, DLoc, Msg) {} 433 classof(const DiagnosticInfo * DI)434 static bool classof(const DiagnosticInfo *DI) { 435 return DI->getKind() == DK_OptimizationRemark; 436 } 437 438 /// \see DiagnosticInfoOptimizationBase::isEnabled. 439 bool isEnabled() const override; 440 }; 441 442 /// Diagnostic information for missed-optimization remarks. 443 class DiagnosticInfoOptimizationRemarkMissed 444 : public DiagnosticInfoOptimizationBase { 445 public: 446 /// \p PassName is the name of the pass emitting this diagnostic. If 447 /// this name matches the regular expression given in -Rpass-missed=, then the 448 /// diagnostic will be emitted. \p Fn is the function where the diagnostic 449 /// is being emitted. \p DLoc is the location information to use in the 450 /// diagnostic. If line table information is available, the diagnostic 451 /// will include the source code location. \p Msg is the message to show. 452 /// Note that this class does not copy this message, so this reference 453 /// must be valid for the whole life time of the diagnostic. DiagnosticInfoOptimizationRemarkMissed(const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)454 DiagnosticInfoOptimizationRemarkMissed(const char *PassName, 455 const Function &Fn, 456 const DebugLoc &DLoc, const Twine &Msg) 457 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark, 458 PassName, Fn, DLoc, Msg) {} 459 classof(const DiagnosticInfo * DI)460 static bool classof(const DiagnosticInfo *DI) { 461 return DI->getKind() == DK_OptimizationRemarkMissed; 462 } 463 464 /// \see DiagnosticInfoOptimizationBase::isEnabled. 465 bool isEnabled() const override; 466 }; 467 468 /// Diagnostic information for optimization analysis remarks. 469 class DiagnosticInfoOptimizationRemarkAnalysis 470 : public DiagnosticInfoOptimizationBase { 471 public: 472 /// \p PassName is the name of the pass emitting this diagnostic. If 473 /// this name matches the regular expression given in -Rpass-analysis=, then 474 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 475 /// is being emitted. \p DLoc is the location information to use in the 476 /// diagnostic. If line table information is available, the diagnostic will 477 /// include the source code location. \p Msg is the message to show. Note that 478 /// this class does not copy this message, so this reference must be valid for 479 /// the whole life time of the diagnostic. DiagnosticInfoOptimizationRemarkAnalysis(const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)480 DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName, 481 const Function &Fn, 482 const DebugLoc &DLoc, 483 const Twine &Msg) 484 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark, 485 PassName, Fn, DLoc, Msg) {} 486 classof(const DiagnosticInfo * DI)487 static bool classof(const DiagnosticInfo *DI) { 488 return DI->getKind() == DK_OptimizationRemarkAnalysis; 489 } 490 491 /// \see DiagnosticInfoOptimizationBase::isEnabled. 492 bool isEnabled() const override; 493 494 static const char *AlwaysPrint; 495 shouldAlwaysPrint()496 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; } 497 498 protected: DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind,const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)499 DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind, 500 const char *PassName, 501 const Function &Fn, 502 const DebugLoc &DLoc, 503 const Twine &Msg) 504 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, 505 Msg) {} 506 }; 507 508 /// Diagnostic information for optimization analysis remarks related to 509 /// floating-point non-commutativity. 510 class DiagnosticInfoOptimizationRemarkAnalysisFPCommute 511 : public DiagnosticInfoOptimizationRemarkAnalysis { 512 public: 513 /// \p PassName is the name of the pass emitting this diagnostic. If 514 /// this name matches the regular expression given in -Rpass-analysis=, then 515 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 516 /// is being emitted. \p DLoc is the location information to use in the 517 /// diagnostic. If line table information is available, the diagnostic will 518 /// include the source code location. \p Msg is the message to show. The 519 /// front-end will append its own message related to options that address 520 /// floating-point non-commutativity. Note that this class does not copy this 521 /// message, so this reference must be valid for the whole life time of the 522 /// diagnostic. DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)523 DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char *PassName, 524 const Function &Fn, 525 const DebugLoc &DLoc, 526 const Twine &Msg) 527 : DiagnosticInfoOptimizationRemarkAnalysis( 528 DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, DLoc, Msg) {} 529 classof(const DiagnosticInfo * DI)530 static bool classof(const DiagnosticInfo *DI) { 531 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; 532 } 533 }; 534 535 /// Diagnostic information for optimization analysis remarks related to 536 /// pointer aliasing. 537 class DiagnosticInfoOptimizationRemarkAnalysisAliasing 538 : public DiagnosticInfoOptimizationRemarkAnalysis { 539 public: 540 /// \p PassName is the name of the pass emitting this diagnostic. If 541 /// this name matches the regular expression given in -Rpass-analysis=, then 542 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic 543 /// is being emitted. \p DLoc is the location information to use in the 544 /// diagnostic. If line table information is available, the diagnostic will 545 /// include the source code location. \p Msg is the message to show. The 546 /// front-end will append its own message related to options that address 547 /// pointer aliasing legality. Note that this class does not copy this 548 /// message, so this reference must be valid for the whole life time of the 549 /// diagnostic. DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char * PassName,const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)550 DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName, 551 const Function &Fn, 552 const DebugLoc &DLoc, 553 const Twine &Msg) 554 : DiagnosticInfoOptimizationRemarkAnalysis( 555 DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {} 556 classof(const DiagnosticInfo * DI)557 static bool classof(const DiagnosticInfo *DI) { 558 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; 559 } 560 }; 561 562 /// Diagnostic information for machine IR parser. 563 class DiagnosticInfoMIRParser : public DiagnosticInfo { 564 const SMDiagnostic &Diagnostic; 565 566 public: DiagnosticInfoMIRParser(DiagnosticSeverity Severity,const SMDiagnostic & Diagnostic)567 DiagnosticInfoMIRParser(DiagnosticSeverity Severity, 568 const SMDiagnostic &Diagnostic) 569 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {} 570 getDiagnostic()571 const SMDiagnostic &getDiagnostic() const { return Diagnostic; } 572 573 void print(DiagnosticPrinter &DP) const override; 574 classof(const DiagnosticInfo * DI)575 static bool classof(const DiagnosticInfo *DI) { 576 return DI->getKind() == DK_MIRParser; 577 } 578 }; 579 580 // Create wrappers for C Binding types (see CBindingWrapping.h). 581 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef) 582 583 /// Emit an optimization-applied message. \p PassName is the name of the pass 584 /// emitting the message. If -Rpass= is given and \p PassName matches the 585 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is 586 /// the function triggering the remark, \p DLoc is the debug location where 587 /// the diagnostic is generated. \p Msg is the message string to use. 588 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, 589 const Function &Fn, const DebugLoc &DLoc, 590 const Twine &Msg); 591 592 /// Emit an optimization-missed message. \p PassName is the name of the 593 /// pass emitting the message. If -Rpass-missed= is given and \p PassName 594 /// matches the regular expression in -Rpass, then the remark will be 595 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the 596 /// debug location where the diagnostic is generated. \p Msg is the 597 /// message string to use. 598 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, 599 const Function &Fn, const DebugLoc &DLoc, 600 const Twine &Msg); 601 602 /// Emit an optimization analysis remark message. \p PassName is the name of 603 /// the pass emitting the message. If -Rpass-analysis= is given and \p 604 /// PassName matches the regular expression in -Rpass, then the remark will be 605 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug 606 /// location where the diagnostic is generated. \p Msg is the message string 607 /// to use. 608 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, 609 const Function &Fn, const DebugLoc &DLoc, 610 const Twine &Msg); 611 612 /// Emit an optimization analysis remark related to messages about 613 /// floating-point non-commutativity. \p PassName is the name of the pass 614 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches 615 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is 616 /// the function triggering the remark, \p DLoc is the debug location where the 617 /// diagnostic is generated. \p Msg is the message string to use. 618 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, 619 const char *PassName, 620 const Function &Fn, 621 const DebugLoc &DLoc, 622 const Twine &Msg); 623 624 /// Emit an optimization analysis remark related to messages about 625 /// pointer aliasing. \p PassName is the name of the pass emitting the message. 626 /// If -Rpass-analysis= is given and \p PassName matches the regular expression 627 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering 628 /// the remark, \p DLoc is the debug location where the diagnostic is generated. 629 /// \p Msg is the message string to use. 630 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, 631 const char *PassName, 632 const Function &Fn, 633 const DebugLoc &DLoc, 634 const Twine &Msg); 635 636 /// Diagnostic information for optimization failures. 637 class DiagnosticInfoOptimizationFailure 638 : public DiagnosticInfoOptimizationBase { 639 public: 640 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 641 /// the location information to use in the diagnostic. If line table 642 /// information is available, the diagnostic will include the source code 643 /// location. \p Msg is the message to show. Note that this class does not 644 /// copy this message, so this reference must be valid for the whole life time 645 /// of the diagnostic. DiagnosticInfoOptimizationFailure(const Function & Fn,const DebugLoc & DLoc,const Twine & Msg)646 DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc, 647 const Twine &Msg) 648 : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning, 649 nullptr, Fn, DLoc, Msg) {} 650 classof(const DiagnosticInfo * DI)651 static bool classof(const DiagnosticInfo *DI) { 652 return DI->getKind() == DK_OptimizationFailure; 653 } 654 655 /// \see DiagnosticInfoOptimizationBase::isEnabled. 656 bool isEnabled() const override; 657 }; 658 659 /// Diagnostic information for unsupported feature in backend. 660 class DiagnosticInfoUnsupported 661 : public DiagnosticInfoWithDebugLocBase { 662 private: 663 Twine Msg; 664 665 public: 666 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is 667 /// the location information to use in the diagnostic. If line table 668 /// information is available, the diagnostic will include the source code 669 /// location. \p Msg is the message to show. Note that this class does not 670 /// copy this message, so this reference must be valid for the whole life time 671 /// of the diagnostic. 672 DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg, 673 DebugLoc DLoc = DebugLoc(), 674 DiagnosticSeverity Severity = DS_Error) DiagnosticInfoWithDebugLocBase(DK_Unsupported,Severity,Fn,DLoc)675 : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc), 676 Msg(Msg) {} 677 classof(const DiagnosticInfo * DI)678 static bool classof(const DiagnosticInfo *DI) { 679 return DI->getKind() == DK_Unsupported; 680 } 681 getMessage()682 const Twine &getMessage() const { return Msg; } 683 684 void print(DiagnosticPrinter &DP) const override; 685 }; 686 687 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the 688 /// function triggering the warning, \p DLoc is the debug location where the 689 /// diagnostic is generated. \p Msg is the message string to use. 690 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, 691 const DebugLoc &DLoc, const Twine &Msg); 692 693 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the 694 /// function triggering the warning, \p DLoc is the debug location where the 695 /// diagnostic is generated. \p Msg is the message string to use. 696 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, 697 const DebugLoc &DLoc, const Twine &Msg); 698 699 } // end namespace llvm 700 701 #endif // LLVM_IR_DIAGNOSTICINFO_H 702