LCOV - code coverage report
Current view: top level - include/llvm/IR - DiagnosticInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 75 85 88.2 %
Date: 2018-07-13 00:08:38 Functions: 21 54 38.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13