Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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