Home | History | Annotate | Download | only in IR
      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:
     94   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
     95       : Kind(Kind), Severity(Severity) {}
     96 
     97   virtual ~DiagnosticInfo() {}
     98 
     99   /* DiagnosticKind */ int getKind() const { return Kind; }
    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)
    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)
    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 
    150   unsigned getLocCookie() const { return LocCookie; }
    151   const Twine &getMsgStr() const { return MsgStr; }
    152   const Instruction *getInstruction() const { return Instr; }
    153 
    154   /// \see DiagnosticInfo::print.
    155   void print(DiagnosticPrinter &DP) const override;
    156 
    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)
    187       : DiagnosticInfo(Kind, Severity),
    188         Fn(Fn),
    189         ResourceName(ResourceName),
    190         ResourceSize(ResourceSize),
    191         ResourceLimit(ResourceLimit) {}
    192 
    193   const Function &getFunction() const { return Fn; }
    194   const char *getResourceName() const { return ResourceName; }
    195   uint64_t getResourceSize() const { return ResourceSize; }
    196   uint64_t getResourceLimit() const { return ResourceLimit; }
    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_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 
    216   uint64_t getStackSize() const { return getResourceSize(); }
    217   uint64_t getStackLimit() const { return getResourceLimit(); }
    218 
    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)
    238       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
    239         MetadataVersion(MetadataVersion) {}
    240 
    241   const Module &getModule() const { return M; }
    242   unsigned getMetadataVersion() const { return MetadataVersion; }
    243 
    244   /// \see DiagnosticInfo::print.
    245   void print(DiagnosticPrinter &DP) const override;
    246 
    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)
    262       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
    263 
    264   const Module &getModule() const { return M; }
    265 
    266   /// \see DiagnosticInfo::print.
    267   void print(DiagnosticPrinter &DP) const override;
    268 
    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)
    281       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    282         LineNum(LineNum), Msg(Msg) {}
    283   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
    284                               DiagnosticSeverity Severity = DS_Error)
    285       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    286         LineNum(0), Msg(Msg) {}
    287   DiagnosticInfoSampleProfile(const Twine &Msg,
    288                               DiagnosticSeverity Severity = DS_Error)
    289       : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
    290 
    291   /// \see DiagnosticInfo::print.
    292   void print(DiagnosticPrinter &DP) const override;
    293 
    294   static bool classof(const DiagnosticInfo *DI) {
    295     return DI->getKind() == DK_SampleProfile;
    296   }
    297 
    298   StringRef getFileName() const { return FileName; }
    299   unsigned getLineNum() const { return LineNum; }
    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)
    319       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
    320 
    321   /// \see DiagnosticInfo::print.
    322   void print(DiagnosticPrinter &DP) const override;
    323 
    324   static bool classof(const DiagnosticInfo *DI) {
    325     return DI->getKind() == DK_PGOProfile;
    326   }
    327 
    328   const char *getFileName() const { return FileName; }
    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.
    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 
    362   const Function &getFunction() const { return Fn; }
    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.
    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 
    400   const char *getPassName() const { return PassName; }
    401   const Twine &getMsg() const { return Msg; }
    402 
    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.
    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 
    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.
    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 
    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.
    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 
    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 
    496   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
    497 
    498 protected:
    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.
    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 
    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.
    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 
    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:
    567   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
    568                           const SMDiagnostic &Diagnostic)
    569       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
    570 
    571   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
    572 
    573   void print(DiagnosticPrinter &DP) const override;
    574 
    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.
    646   DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
    647                                     const Twine &Msg)
    648       : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
    649                                        nullptr, Fn, DLoc, Msg) {}
    650 
    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)
    675       : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
    676         Msg(Msg) {}
    677 
    678   static bool classof(const DiagnosticInfo *DI) {
    679     return DI->getKind() == DK_Unsupported;
    680   }
    681 
    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