Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares the different classes involved in low level diagnostics.
0010 //
0011 // Diagnostics reporting is still done as part of the LLVMContext.
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_IR_DIAGNOSTICINFO_H
0015 #define LLVM_IR_DIAGNOSTICINFO_H
0016 
0017 #include "llvm-c/Types.h"
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/ADT/Twine.h"
0022 #include "llvm/IR/DebugLoc.h"
0023 #include "llvm/Support/CBindingWrapping.h"
0024 #include "llvm/Support/ErrorHandling.h"
0025 #include "llvm/Support/SourceMgr.h"
0026 #include "llvm/Support/TypeSize.h"
0027 #include <algorithm>
0028 #include <cstdint>
0029 #include <functional>
0030 #include <iterator>
0031 #include <optional>
0032 #include <string>
0033 
0034 namespace llvm {
0035 
0036 // Forward declarations.
0037 class DiagnosticPrinter;
0038 class DIFile;
0039 class DISubprogram;
0040 class CallInst;
0041 class Function;
0042 class Instruction;
0043 class InstructionCost;
0044 class Module;
0045 class Type;
0046 class Value;
0047 
0048 /// Defines the different supported severity of a diagnostic.
0049 enum DiagnosticSeverity : char {
0050   DS_Error,
0051   DS_Warning,
0052   DS_Remark,
0053   // A note attaches additional information to one of the previous diagnostic
0054   // types.
0055   DS_Note
0056 };
0057 
0058 /// Defines the different supported kind of a diagnostic.
0059 /// This enum should be extended with a new ID for each added concrete subclass.
0060 enum DiagnosticKind {
0061   DK_Generic,
0062   DK_GenericWithLoc,
0063   DK_InlineAsm,
0064   DK_RegAllocFailure,
0065   DK_ResourceLimit,
0066   DK_StackSize,
0067   DK_Linker,
0068   DK_Lowering,
0069   DK_DebugMetadataVersion,
0070   DK_DebugMetadataInvalid,
0071   DK_Instrumentation,
0072   DK_ISelFallback,
0073   DK_SampleProfile,
0074   DK_OptimizationRemark,
0075   DK_OptimizationRemarkMissed,
0076   DK_OptimizationRemarkAnalysis,
0077   DK_OptimizationRemarkAnalysisFPCommute,
0078   DK_OptimizationRemarkAnalysisAliasing,
0079   DK_OptimizationFailure,
0080   DK_FirstRemark = DK_OptimizationRemark,
0081   DK_LastRemark = DK_OptimizationFailure,
0082   DK_MachineOptimizationRemark,
0083   DK_MachineOptimizationRemarkMissed,
0084   DK_MachineOptimizationRemarkAnalysis,
0085   DK_FirstMachineRemark = DK_MachineOptimizationRemark,
0086   DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
0087   DK_MIRParser,
0088   DK_PGOProfile,
0089   DK_Unsupported,
0090   DK_SrcMgr,
0091   DK_DontCall,
0092   DK_MisExpect,
0093   DK_FirstPluginKind // Must be last value to work with
0094                      // getNextAvailablePluginDiagnosticKind
0095 };
0096 
0097 /// Get the next available kind ID for a plugin diagnostic.
0098 /// Each time this function is called, it returns a different number.
0099 /// Therefore, a plugin that wants to "identify" its own classes
0100 /// with a dynamic identifier, just have to use this method to get a new ID
0101 /// and assign it to each of its classes.
0102 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
0103 /// Thus, the plugin identifiers will not conflict with the
0104 /// DiagnosticKind values.
0105 int getNextAvailablePluginDiagnosticKind();
0106 
0107 /// This is the base abstract class for diagnostic reporting in
0108 /// the backend.
0109 /// The print method must be overloaded by the subclasses to print a
0110 /// user-friendly message in the client of the backend (let us call it a
0111 /// frontend).
0112 class DiagnosticInfo {
0113 private:
0114   /// Kind defines the kind of report this is about.
0115   const /* DiagnosticKind */ int Kind;
0116   /// Severity gives the severity of the diagnostic.
0117   const DiagnosticSeverity Severity;
0118 
0119   virtual void anchor();
0120 public:
0121   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
0122       : Kind(Kind), Severity(Severity) {}
0123 
0124   virtual ~DiagnosticInfo() = default;
0125 
0126   /* DiagnosticKind */ int getKind() const { return Kind; }
0127   DiagnosticSeverity getSeverity() const { return Severity; }
0128 
0129   /// Print using the given \p DP a user-friendly message.
0130   /// This is the default message that will be printed to the user.
0131   /// It is used when the frontend does not directly take advantage
0132   /// of the information contained in fields of the subclasses.
0133   /// The printed message must not end with '.' nor start with a severity
0134   /// keyword.
0135   virtual void print(DiagnosticPrinter &DP) const = 0;
0136 };
0137 
0138 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
0139 
0140 class DiagnosticInfoGeneric : public DiagnosticInfo {
0141   const Twine &MsgStr;
0142   const Instruction *Inst = nullptr;
0143 
0144 public:
0145   /// \p MsgStr is the message to be reported to the frontend.
0146   /// This class does not copy \p MsgStr, therefore the reference must be valid
0147   /// for the whole life time of the Diagnostic.
0148   DiagnosticInfoGeneric(const Twine &MsgStr,
0149                         DiagnosticSeverity Severity = DS_Error)
0150       : DiagnosticInfo(DK_Generic, Severity), MsgStr(MsgStr) {}
0151 
0152   DiagnosticInfoGeneric(const Instruction *I, const Twine &ErrMsg,
0153                         DiagnosticSeverity Severity = DS_Error)
0154       : DiagnosticInfo(DK_Generic, Severity), MsgStr(ErrMsg), Inst(I) {}
0155 
0156   const Twine &getMsgStr() const { return MsgStr; }
0157   const Instruction *getInstruction() const { return Inst; }
0158 
0159   /// \see DiagnosticInfo::print.
0160   void print(DiagnosticPrinter &DP) const override;
0161 
0162   static bool classof(const DiagnosticInfo *DI) {
0163     return DI->getKind() == DK_Generic;
0164   }
0165 };
0166 
0167 /// Diagnostic information for inline asm reporting.
0168 /// This is basically a message and an optional location.
0169 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
0170 private:
0171   /// Optional line information. 0 if not set.
0172   uint64_t LocCookie = 0;
0173   /// Message to be reported.
0174   const Twine &MsgStr;
0175   /// Optional origin of the problem.
0176   const Instruction *Instr = nullptr;
0177 
0178 public:
0179   /// \p LocCookie if non-zero gives the line number for this report.
0180   /// \p MsgStr gives the message.
0181   /// This class does not copy \p MsgStr, therefore the reference must be valid
0182   /// for the whole life time of the Diagnostic.
0183   DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr,
0184                           DiagnosticSeverity Severity = DS_Error);
0185 
0186   /// \p Instr gives the original instruction that triggered the diagnostic.
0187   /// \p MsgStr gives the message.
0188   /// This class does not copy \p MsgStr, therefore the reference must be valid
0189   /// for the whole life time of the Diagnostic.
0190   /// Same for \p I.
0191   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
0192                           DiagnosticSeverity Severity = DS_Error);
0193 
0194   uint64_t getLocCookie() const { return LocCookie; }
0195   const Twine &getMsgStr() const { return MsgStr; }
0196   const Instruction *getInstruction() const { return Instr; }
0197 
0198   /// \see DiagnosticInfo::print.
0199   void print(DiagnosticPrinter &DP) const override;
0200 
0201   static bool classof(const DiagnosticInfo *DI) {
0202     return DI->getKind() == DK_InlineAsm;
0203   }
0204 };
0205 
0206 /// Diagnostic information for debug metadata version reporting.
0207 /// This is basically a module and a version.
0208 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
0209 private:
0210   /// The module that is concerned by this debug metadata version diagnostic.
0211   const Module &M;
0212   /// The actual metadata version.
0213   unsigned MetadataVersion;
0214 
0215 public:
0216   /// \p The module that is concerned by this debug metadata version diagnostic.
0217   /// \p The actual metadata version.
0218   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
0219                                      DiagnosticSeverity Severity = DS_Warning)
0220       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
0221         MetadataVersion(MetadataVersion) {}
0222 
0223   const Module &getModule() const { return M; }
0224   unsigned getMetadataVersion() const { return MetadataVersion; }
0225 
0226   /// \see DiagnosticInfo::print.
0227   void print(DiagnosticPrinter &DP) const override;
0228 
0229   static bool classof(const DiagnosticInfo *DI) {
0230     return DI->getKind() == DK_DebugMetadataVersion;
0231   }
0232 };
0233 
0234 /// Diagnostic information for stripping invalid debug metadata.
0235 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
0236 private:
0237   /// The module that is concerned by this debug metadata version diagnostic.
0238   const Module &M;
0239 
0240 public:
0241   /// \p The module that is concerned by this debug metadata version diagnostic.
0242   DiagnosticInfoIgnoringInvalidDebugMetadata(
0243       const Module &M, DiagnosticSeverity Severity = DS_Warning)
0244       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
0245 
0246   const Module &getModule() const { return M; }
0247 
0248   /// \see DiagnosticInfo::print.
0249   void print(DiagnosticPrinter &DP) const override;
0250 
0251   static bool classof(const DiagnosticInfo *DI) {
0252     return DI->getKind() == DK_DebugMetadataInvalid;
0253   }
0254 };
0255 
0256 /// Diagnostic information for the sample profiler.
0257 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
0258 public:
0259   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
0260                               const Twine &Msg,
0261                               DiagnosticSeverity Severity = DS_Error)
0262       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
0263         LineNum(LineNum), Msg(Msg) {}
0264   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
0265                               DiagnosticSeverity Severity = DS_Error)
0266       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
0267         Msg(Msg) {}
0268   DiagnosticInfoSampleProfile(const Twine &Msg,
0269                               DiagnosticSeverity Severity = DS_Error)
0270       : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
0271 
0272   /// \see DiagnosticInfo::print.
0273   void print(DiagnosticPrinter &DP) const override;
0274 
0275   static bool classof(const DiagnosticInfo *DI) {
0276     return DI->getKind() == DK_SampleProfile;
0277   }
0278 
0279   StringRef getFileName() const { return FileName; }
0280   unsigned getLineNum() const { return LineNum; }
0281   const Twine &getMsg() const { return Msg; }
0282 
0283 private:
0284   /// Name of the input file associated with this diagnostic.
0285   StringRef FileName;
0286 
0287   /// Line number where the diagnostic occurred. If 0, no line number will
0288   /// be emitted in the message.
0289   unsigned LineNum = 0;
0290 
0291   /// Message to report.
0292   const Twine &Msg;
0293 };
0294 
0295 /// Diagnostic information for the PGO profiler.
0296 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
0297 public:
0298   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
0299                            DiagnosticSeverity Severity = DS_Error)
0300       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
0301 
0302   /// \see DiagnosticInfo::print.
0303   void print(DiagnosticPrinter &DP) const override;
0304 
0305   static bool classof(const DiagnosticInfo *DI) {
0306     return DI->getKind() == DK_PGOProfile;
0307   }
0308 
0309   const char *getFileName() const { return FileName; }
0310   const Twine &getMsg() const { return Msg; }
0311 
0312 private:
0313   /// Name of the input file associated with this diagnostic.
0314   const char *FileName;
0315 
0316   /// Message to report.
0317   const Twine &Msg;
0318 };
0319 
0320 class DiagnosticLocation {
0321   DIFile *File = nullptr;
0322   unsigned Line = 0;
0323   unsigned Column = 0;
0324 
0325 public:
0326   DiagnosticLocation() = default;
0327   DiagnosticLocation(const DebugLoc &DL);
0328   DiagnosticLocation(const DISubprogram *SP);
0329 
0330   bool isValid() const { return File; }
0331   /// Return the full path to the file.
0332   std::string getAbsolutePath() const;
0333   /// Return the file name relative to the compilation directory.
0334   StringRef getRelativePath() const;
0335   unsigned getLine() const { return Line; }
0336   unsigned getColumn() const { return Column; }
0337 };
0338 
0339 /// Common features for diagnostics with an associated location.
0340 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
0341   void anchor() override;
0342 public:
0343   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
0344   /// the location information to use in the diagnostic.
0345   DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
0346                                  enum DiagnosticSeverity Severity,
0347                                  const Function &Fn,
0348                                  const DiagnosticLocation &Loc)
0349       : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
0350 
0351   /// Return true if location information is available for this diagnostic.
0352   bool isLocationAvailable() const { return Loc.isValid(); }
0353 
0354   /// Return a string with the location information for this diagnostic
0355   /// in the format "file:line:col". If location information is not available,
0356   /// it returns "<unknown>:0:0".
0357   std::string getLocationStr() const;
0358 
0359   /// Return location information for this diagnostic in three parts:
0360   /// the relative source file path, line number and column.
0361   void getLocation(StringRef &RelativePath, unsigned &Line,
0362                    unsigned &Column) const;
0363 
0364   /// Return the absolute path tot the file.
0365   std::string getAbsolutePath() const;
0366   
0367   const Function &getFunction() const { return Fn; }
0368   DiagnosticLocation getLocation() const { return Loc; }
0369 
0370 private:
0371   /// Function where this diagnostic is triggered.
0372   const Function &Fn;
0373 
0374   /// Debug location where this diagnostic is triggered.
0375   DiagnosticLocation Loc;
0376 };
0377 
0378 class DiagnosticInfoGenericWithLoc : public DiagnosticInfoWithLocationBase {
0379 private:
0380   /// Message to be reported.
0381   const Twine &MsgStr;
0382 
0383 public:
0384   /// \p MsgStr is the message to be reported to the frontend.
0385   /// This class does not copy \p MsgStr, therefore the reference must be valid
0386   /// for the whole life time of the Diagnostic.
0387   DiagnosticInfoGenericWithLoc(const Twine &MsgStr, const Function &Fn,
0388                                const DiagnosticLocation &Loc,
0389                                DiagnosticSeverity Severity = DS_Error)
0390       : DiagnosticInfoWithLocationBase(DK_GenericWithLoc, Severity, Fn, Loc),
0391         MsgStr(MsgStr) {}
0392 
0393   const Twine &getMsgStr() const { return MsgStr; }
0394 
0395   /// \see DiagnosticInfo::print.
0396   void print(DiagnosticPrinter &DP) const override;
0397 
0398   static bool classof(const DiagnosticInfo *DI) {
0399     return DI->getKind() == DK_GenericWithLoc;
0400   }
0401 };
0402 
0403 class DiagnosticInfoRegAllocFailure : public DiagnosticInfoWithLocationBase {
0404 private:
0405   /// Message to be reported.
0406   const Twine &MsgStr;
0407 
0408 public:
0409   /// \p MsgStr is the message to be reported to the frontend.
0410   /// This class does not copy \p MsgStr, therefore the reference must be valid
0411   /// for the whole life time of the Diagnostic.
0412   DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
0413                                 const DiagnosticLocation &DL,
0414                                 DiagnosticSeverity Severity = DS_Error);
0415 
0416   DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
0417                                 DiagnosticSeverity Severity = DS_Error);
0418 
0419   const Twine &getMsgStr() const { return MsgStr; }
0420 
0421   /// \see DiagnosticInfo::print.
0422   void print(DiagnosticPrinter &DP) const override;
0423 
0424   static bool classof(const DiagnosticInfo *DI) {
0425     return DI->getKind() == DK_RegAllocFailure;
0426   }
0427 };
0428 
0429 /// Diagnostic information for stack size etc. reporting.
0430 /// This is basically a function and a size.
0431 class DiagnosticInfoResourceLimit : public DiagnosticInfoWithLocationBase {
0432 private:
0433   /// The function that is concerned by this resource limit diagnostic.
0434   const Function &Fn;
0435 
0436   /// Description of the resource type (e.g. stack size)
0437   const char *ResourceName;
0438 
0439   /// The computed size usage
0440   uint64_t ResourceSize;
0441 
0442   // Threshould passed
0443   uint64_t ResourceLimit;
0444 
0445 public:
0446   /// \p The function that is concerned by this stack size diagnostic.
0447   /// \p The computed stack size.
0448   DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
0449                               uint64_t ResourceSize, uint64_t ResourceLimit,
0450                               DiagnosticSeverity Severity = DS_Warning,
0451                               DiagnosticKind Kind = DK_ResourceLimit);
0452 
0453   const Function &getFunction() const { return Fn; }
0454   const char *getResourceName() const { return ResourceName; }
0455   uint64_t getResourceSize() const { return ResourceSize; }
0456   uint64_t getResourceLimit() const { return ResourceLimit; }
0457 
0458   /// \see DiagnosticInfo::print.
0459   void print(DiagnosticPrinter &DP) const override;
0460 
0461   static bool classof(const DiagnosticInfo *DI) {
0462     return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
0463   }
0464 };
0465 
0466 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
0467   void anchor() override;
0468 
0469 public:
0470   DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
0471                           uint64_t StackLimit,
0472                           DiagnosticSeverity Severity = DS_Warning)
0473       : DiagnosticInfoResourceLimit(Fn, "stack frame size", StackSize,
0474                                     StackLimit, Severity, DK_StackSize) {}
0475 
0476   uint64_t getStackSize() const { return getResourceSize(); }
0477   uint64_t getStackLimit() const { return getResourceLimit(); }
0478 
0479   static bool classof(const DiagnosticInfo *DI) {
0480     return DI->getKind() == DK_StackSize;
0481   }
0482 };
0483 
0484 /// Common features for diagnostics dealing with optimization remarks
0485 /// that are used by both IR and MIR passes.
0486 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
0487 public:
0488   /// Used to set IsVerbose via the stream interface.
0489   struct setIsVerbose {};
0490 
0491   /// When an instance of this is inserted into the stream, the arguments
0492   /// following will not appear in the remark printed in the compiler output
0493   /// (-Rpass) but only in the optimization record file
0494   /// (-fsave-optimization-record).
0495   struct setExtraArgs {};
0496 
0497   /// Used in the streaming interface as the general argument type.  It
0498   /// internally converts everything into a key-value pair.
0499   struct Argument {
0500     std::string Key;
0501     std::string Val;
0502     // If set, the debug location corresponding to the value.
0503     DiagnosticLocation Loc;
0504 
0505     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
0506     Argument(StringRef Key, const Value *V);
0507     Argument(StringRef Key, const Type *T);
0508     Argument(StringRef Key, StringRef S);
0509     Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {};
0510     Argument(StringRef Key, int N);
0511     Argument(StringRef Key, float N);
0512     Argument(StringRef Key, long N);
0513     Argument(StringRef Key, long long N);
0514     Argument(StringRef Key, unsigned N);
0515     Argument(StringRef Key, unsigned long N);
0516     Argument(StringRef Key, unsigned long long N);
0517     Argument(StringRef Key, ElementCount EC);
0518     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
0519     Argument(StringRef Key, DebugLoc dl);
0520     Argument(StringRef Key, InstructionCost C);
0521   };
0522 
0523   /// \p PassName is the name of the pass emitting this diagnostic. \p
0524   /// RemarkName is a textual identifier for the remark (single-word,
0525   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
0526   /// \p Loc is the location information to use in the diagnostic. If line table
0527   /// information is available, the diagnostic will include the source code
0528   /// location.
0529   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
0530                                  enum DiagnosticSeverity Severity,
0531                                  const char *PassName, StringRef RemarkName,
0532                                  const Function &Fn,
0533                                  const DiagnosticLocation &Loc)
0534       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
0535         PassName(PassName), RemarkName(RemarkName) {}
0536 
0537   void insert(StringRef S);
0538   void insert(Argument A);
0539   void insert(setIsVerbose V);
0540   void insert(setExtraArgs EA);
0541 
0542   /// \see DiagnosticInfo::print.
0543   void print(DiagnosticPrinter &DP) const override;
0544 
0545   /// Return true if this optimization remark is enabled by one of
0546   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
0547   /// or -pass-remarks-analysis). Note that this only handles the LLVM
0548   /// flags. We cannot access Clang flags from here (they are handled
0549   /// in BackendConsumer::OptimizationRemarkHandler).
0550   virtual bool isEnabled() const = 0;
0551 
0552   StringRef getPassName() const { return PassName; }
0553   StringRef getRemarkName() const { return RemarkName; }
0554   std::string getMsg() const;
0555   std::optional<uint64_t> getHotness() const { return Hotness; }
0556   void setHotness(std::optional<uint64_t> H) { Hotness = H; }
0557 
0558   bool isVerbose() const { return IsVerbose; }
0559 
0560   ArrayRef<Argument> getArgs() const { return Args; }
0561 
0562   static bool classof(const DiagnosticInfo *DI) {
0563     return (DI->getKind() >= DK_FirstRemark &&
0564             DI->getKind() <= DK_LastRemark) ||
0565            (DI->getKind() >= DK_FirstMachineRemark &&
0566             DI->getKind() <= DK_LastMachineRemark);
0567   }
0568 
0569   bool isPassed() const {
0570     return (getKind() == DK_OptimizationRemark ||
0571             getKind() == DK_MachineOptimizationRemark);
0572   }
0573 
0574   bool isMissed() const {
0575     return (getKind() == DK_OptimizationRemarkMissed ||
0576             getKind() == DK_MachineOptimizationRemarkMissed);
0577   }
0578 
0579   bool isAnalysis() const {
0580     return (getKind() == DK_OptimizationRemarkAnalysis ||
0581             getKind() == DK_MachineOptimizationRemarkAnalysis);
0582   }
0583 
0584 protected:
0585   /// Name of the pass that triggers this report. If this matches the
0586   /// regular expression given in -Rpass=regexp, then the remark will
0587   /// be emitted.
0588   const char *PassName;
0589 
0590   /// Textual identifier for the remark (single-word, camel-case). Can be used
0591   /// by external tools reading the output file for optimization remarks to
0592   /// identify the remark.
0593   StringRef RemarkName;
0594 
0595   /// If profile information is available, this is the number of times the
0596   /// corresponding code was executed in a profile instrumentation run.
0597   std::optional<uint64_t> Hotness;
0598 
0599   /// Arguments collected via the streaming interface.
0600   SmallVector<Argument, 4> Args;
0601 
0602   /// The remark is expected to be noisy.
0603   bool IsVerbose = false;
0604 
0605   /// If positive, the index of the first argument that only appear in
0606   /// the optimization records and not in the remark printed in the compiler
0607   /// output.
0608   int FirstExtraArgIndex = -1;
0609 };
0610 
0611 /// Allow the insertion operator to return the actual remark type rather than a
0612 /// common base class.  This allows returning the result of the insertion
0613 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
0614 template <class RemarkT>
0615 RemarkT &
0616 operator<<(RemarkT &R,
0617            std::enable_if_t<
0618                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0619                StringRef>
0620                S) {
0621   R.insert(S);
0622   return R;
0623 }
0624 
0625 /// Also allow r-value for the remark to allow insertion into a
0626 /// temporarily-constructed remark.
0627 template <class RemarkT>
0628 RemarkT &
0629 operator<<(RemarkT &&R,
0630            std::enable_if_t<
0631                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0632                StringRef>
0633                S) {
0634   R.insert(S);
0635   return R;
0636 }
0637 
0638 template <class RemarkT>
0639 RemarkT &
0640 operator<<(RemarkT &R,
0641            std::enable_if_t<
0642                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0643                DiagnosticInfoOptimizationBase::Argument>
0644                A) {
0645   R.insert(A);
0646   return R;
0647 }
0648 
0649 template <class RemarkT>
0650 RemarkT &
0651 operator<<(RemarkT &&R,
0652            std::enable_if_t<
0653                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0654                DiagnosticInfoOptimizationBase::Argument>
0655                A) {
0656   R.insert(A);
0657   return R;
0658 }
0659 
0660 template <class RemarkT>
0661 RemarkT &
0662 operator<<(RemarkT &R,
0663            std::enable_if_t<
0664                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0665                DiagnosticInfoOptimizationBase::setIsVerbose>
0666                V) {
0667   R.insert(V);
0668   return R;
0669 }
0670 
0671 template <class RemarkT>
0672 RemarkT &
0673 operator<<(RemarkT &&R,
0674            std::enable_if_t<
0675                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0676                DiagnosticInfoOptimizationBase::setIsVerbose>
0677                V) {
0678   R.insert(V);
0679   return R;
0680 }
0681 
0682 template <class RemarkT>
0683 RemarkT &
0684 operator<<(RemarkT &R,
0685            std::enable_if_t<
0686                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
0687                DiagnosticInfoOptimizationBase::setExtraArgs>
0688                EA) {
0689   R.insert(EA);
0690   return R;
0691 }
0692 
0693 /// Common features for diagnostics dealing with optimization remarks
0694 /// that are used by IR passes.
0695 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
0696   void anchor() override;
0697 public:
0698   /// \p PassName is the name of the pass emitting this diagnostic. \p
0699   /// RemarkName is a textual identifier for the remark (single-word,
0700   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
0701   /// \p Loc is the location information to use in the diagnostic. If line table
0702   /// information is available, the diagnostic will include the source code
0703   /// location. \p CodeRegion is IR value (currently basic block) that the
0704   /// optimization operates on. This is currently used to provide run-time
0705   /// hotness information with PGO.
0706   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
0707                                enum DiagnosticSeverity Severity,
0708                                const char *PassName, StringRef RemarkName,
0709                                const Function &Fn,
0710                                const DiagnosticLocation &Loc,
0711                                const Value *CodeRegion = nullptr)
0712       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
0713                                        Loc),
0714         CodeRegion(CodeRegion) {}
0715 
0716   /// This is ctor variant allows a pass to build an optimization remark
0717   /// from an existing remark.
0718   ///
0719   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
0720   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
0721   /// remark.  The string \p Prepend will be emitted before the original
0722   /// message.
0723   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
0724                                const DiagnosticInfoIROptimization &Orig)
0725       : DiagnosticInfoOptimizationBase(
0726             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
0727             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
0728         CodeRegion(Orig.getCodeRegion()) {
0729     *this << Prepend;
0730     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
0731   }
0732 
0733   /// Legacy interface.
0734   /// \p PassName is the name of the pass emitting this diagnostic.
0735   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
0736   /// the location information to use in the diagnostic. If line table
0737   /// information is available, the diagnostic will include the source code
0738   /// location. \p Msg is the message to show. Note that this class does not
0739   /// copy this message, so this reference must be valid for the whole life time
0740   /// of the diagnostic.
0741   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
0742                                enum DiagnosticSeverity Severity,
0743                                const char *PassName, const Function &Fn,
0744                                const DiagnosticLocation &Loc, const Twine &Msg)
0745       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
0746     *this << Msg.str();
0747   }
0748 
0749   const Value *getCodeRegion() const { return CodeRegion; }
0750 
0751   static bool classof(const DiagnosticInfo *DI) {
0752     return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
0753   }
0754 
0755 private:
0756   /// The IR value (currently basic block) that the optimization operates on.
0757   /// This is currently used to provide run-time hotness information with PGO.
0758   const Value *CodeRegion = nullptr;
0759 };
0760 
0761 /// Diagnostic information for applied optimization remarks.
0762 class OptimizationRemark : public DiagnosticInfoIROptimization {
0763 public:
0764   /// \p PassName is the name of the pass emitting this diagnostic. If this name
0765   /// matches the regular expression given in -Rpass=, then the diagnostic will
0766   /// be emitted. \p RemarkName is a textual identifier for the remark (single-
0767   /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
0768   /// region that the optimization operates on (currently only block is
0769   /// supported).
0770   OptimizationRemark(const char *PassName, StringRef RemarkName,
0771                      const DiagnosticLocation &Loc, const Value *CodeRegion);
0772 
0773   /// Same as above, but the debug location and code region are derived from \p
0774   /// Instr.
0775   OptimizationRemark(const char *PassName, StringRef RemarkName,
0776                      const Instruction *Inst);
0777 
0778   /// Same as above, but the debug location and code region are derived from \p
0779   /// Func.
0780   OptimizationRemark(const char *PassName, StringRef RemarkName,
0781                      const Function *Func);
0782 
0783   static bool classof(const DiagnosticInfo *DI) {
0784     return DI->getKind() == DK_OptimizationRemark;
0785   }
0786 
0787   /// \see DiagnosticInfoOptimizationBase::isEnabled.
0788   bool isEnabled() const override;
0789 
0790 private:
0791   /// This is deprecated now and only used by the function API below.
0792   /// \p PassName is the name of the pass emitting this diagnostic. If
0793   /// this name matches the regular expression given in -Rpass=, then the
0794   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
0795   /// is being emitted. \p Loc is the location information to use in the
0796   /// diagnostic. If line table information is available, the diagnostic
0797   /// will include the source code location. \p Msg is the message to show.
0798   /// Note that this class does not copy this message, so this reference
0799   /// must be valid for the whole life time of the diagnostic.
0800   OptimizationRemark(const char *PassName, const Function &Fn,
0801                      const DiagnosticLocation &Loc, const Twine &Msg)
0802       : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
0803                                      Fn, Loc, Msg) {}
0804 };
0805 
0806 /// Diagnostic information for missed-optimization remarks.
0807 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
0808 public:
0809   /// \p PassName is the name of the pass emitting this diagnostic. If this name
0810   /// matches the regular expression given in -Rpass-missed=, then the
0811   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
0812   /// remark (single-word, camel-case). \p Loc is the debug location and \p
0813   /// CodeRegion is the region that the optimization operates on (currently only
0814   /// block is supported).
0815   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
0816                            const DiagnosticLocation &Loc,
0817                            const Value *CodeRegion);
0818 
0819   /// Same as above but \p Inst is used to derive code region and debug
0820   /// location.
0821   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
0822                            const Instruction *Inst);
0823 
0824   /// Same as above but \p F is used to derive code region and debug
0825   /// location.
0826   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
0827                            const Function *F);
0828 
0829   static bool classof(const DiagnosticInfo *DI) {
0830     return DI->getKind() == DK_OptimizationRemarkMissed;
0831   }
0832 
0833   /// \see DiagnosticInfoOptimizationBase::isEnabled.
0834   bool isEnabled() const override;
0835 
0836 private:
0837   /// This is deprecated now and only used by the function API below.
0838   /// \p PassName is the name of the pass emitting this diagnostic. If
0839   /// this name matches the regular expression given in -Rpass-missed=, then the
0840   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
0841   /// is being emitted. \p Loc is the location information to use in the
0842   /// diagnostic. If line table information is available, the diagnostic
0843   /// will include the source code location. \p Msg is the message to show.
0844   /// Note that this class does not copy this message, so this reference
0845   /// must be valid for the whole life time of the diagnostic.
0846   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
0847                            const DiagnosticLocation &Loc, const Twine &Msg)
0848       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
0849                                      PassName, Fn, Loc, Msg) {}
0850 };
0851 
0852 /// Diagnostic information for optimization analysis remarks.
0853 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
0854 public:
0855   /// \p PassName is the name of the pass emitting this diagnostic. If this name
0856   /// matches the regular expression given in -Rpass-analysis=, then the
0857   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
0858   /// remark (single-word, camel-case). \p Loc is the debug location and \p
0859   /// CodeRegion is the region that the optimization operates on (currently only
0860   /// block is supported).
0861   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
0862                              const DiagnosticLocation &Loc,
0863                              const Value *CodeRegion);
0864 
0865   /// This is ctor variant allows a pass to build an optimization remark
0866   /// from an existing remark.
0867   ///
0868   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
0869   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
0870   /// remark.  The string \p Prepend will be emitted before the original
0871   /// message.
0872   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
0873                              const OptimizationRemarkAnalysis &Orig)
0874       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
0875 
0876   /// Same as above but \p Inst is used to derive code region and debug
0877   /// location.
0878   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
0879                              const Instruction *Inst);
0880 
0881   /// Same as above but \p F is used to derive code region and debug
0882   /// location.
0883   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
0884                              const Function *F);
0885 
0886   static bool classof(const DiagnosticInfo *DI) {
0887     return DI->getKind() == DK_OptimizationRemarkAnalysis;
0888   }
0889 
0890   /// \see DiagnosticInfoOptimizationBase::isEnabled.
0891   bool isEnabled() const override;
0892 
0893   static const char *AlwaysPrint;
0894 
0895   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
0896 
0897 protected:
0898   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
0899                              const Function &Fn, const DiagnosticLocation &Loc,
0900                              const Twine &Msg)
0901       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
0902 
0903   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
0904                              StringRef RemarkName,
0905                              const DiagnosticLocation &Loc,
0906                              const Value *CodeRegion);
0907 
0908 private:
0909   /// This is deprecated now and only used by the function API below.
0910   /// \p PassName is the name of the pass emitting this diagnostic. If
0911   /// this name matches the regular expression given in -Rpass-analysis=, then
0912   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
0913   /// is being emitted. \p Loc is the location information to use in the
0914   /// diagnostic. If line table information is available, the diagnostic will
0915   /// include the source code location. \p Msg is the message to show. Note that
0916   /// this class does not copy this message, so this reference must be valid for
0917   /// the whole life time of the diagnostic.
0918   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
0919                              const DiagnosticLocation &Loc, const Twine &Msg)
0920       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
0921                                      PassName, Fn, Loc, Msg) {}
0922 };
0923 
0924 /// Diagnostic information for optimization analysis remarks related to
0925 /// floating-point non-commutativity.
0926 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
0927   void anchor() override;
0928 public:
0929   /// \p PassName is the name of the pass emitting this diagnostic. If this name
0930   /// matches the regular expression given in -Rpass-analysis=, then the
0931   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
0932   /// remark (single-word, camel-case). \p Loc is the debug location and \p
0933   /// CodeRegion is the region that the optimization operates on (currently only
0934   /// block is supported). The front-end will append its own message related to
0935   /// options that address floating-point non-commutativity.
0936   OptimizationRemarkAnalysisFPCommute(const char *PassName,
0937                                       StringRef RemarkName,
0938                                       const DiagnosticLocation &Loc,
0939                                       const Value *CodeRegion)
0940       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
0941                                    PassName, RemarkName, Loc, CodeRegion) {}
0942 
0943   static bool classof(const DiagnosticInfo *DI) {
0944     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
0945   }
0946 
0947 private:
0948   /// This is deprecated now and only used by the function API below.
0949   /// \p PassName is the name of the pass emitting this diagnostic. If
0950   /// this name matches the regular expression given in -Rpass-analysis=, then
0951   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
0952   /// is being emitted. \p Loc is the location information to use in the
0953   /// diagnostic. If line table information is available, the diagnostic will
0954   /// include the source code location. \p Msg is the message to show. The
0955   /// front-end will append its own message related to options that address
0956   /// floating-point non-commutativity. Note that this class does not copy this
0957   /// message, so this reference must be valid for the whole life time of the
0958   /// diagnostic.
0959   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
0960                                       const DiagnosticLocation &Loc,
0961                                       const Twine &Msg)
0962       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
0963                                    PassName, Fn, Loc, Msg) {}
0964 };
0965 
0966 /// Diagnostic information for optimization analysis remarks related to
0967 /// pointer aliasing.
0968 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
0969   void anchor() override;
0970 public:
0971   /// \p PassName is the name of the pass emitting this diagnostic. If this name
0972   /// matches the regular expression given in -Rpass-analysis=, then the
0973   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
0974   /// remark (single-word, camel-case). \p Loc is the debug location and \p
0975   /// CodeRegion is the region that the optimization operates on (currently only
0976   /// block is supported). The front-end will append its own message related to
0977   /// options that address pointer aliasing legality.
0978   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
0979                                      const DiagnosticLocation &Loc,
0980                                      const Value *CodeRegion)
0981       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
0982                                    PassName, RemarkName, Loc, CodeRegion) {}
0983 
0984   static bool classof(const DiagnosticInfo *DI) {
0985     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
0986   }
0987 
0988 private:
0989   /// This is deprecated now and only used by the function API below.
0990   /// \p PassName is the name of the pass emitting this diagnostic. If
0991   /// this name matches the regular expression given in -Rpass-analysis=, then
0992   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
0993   /// is being emitted. \p Loc is the location information to use in the
0994   /// diagnostic. If line table information is available, the diagnostic will
0995   /// include the source code location. \p Msg is the message to show. The
0996   /// front-end will append its own message related to options that address
0997   /// pointer aliasing legality. Note that this class does not copy this
0998   /// message, so this reference must be valid for the whole life time of the
0999   /// diagnostic.
1000   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
1001                                      const DiagnosticLocation &Loc,
1002                                      const Twine &Msg)
1003       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
1004                                    PassName, Fn, Loc, Msg) {}
1005 };
1006 
1007 /// Diagnostic information for machine IR parser.
1008 // FIXME: Remove this, use DiagnosticInfoSrcMgr instead.
1009 class DiagnosticInfoMIRParser : public DiagnosticInfo {
1010   const SMDiagnostic &Diagnostic;
1011 
1012 public:
1013   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
1014                           const SMDiagnostic &Diagnostic)
1015       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
1016 
1017   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
1018 
1019   void print(DiagnosticPrinter &DP) const override;
1020 
1021   static bool classof(const DiagnosticInfo *DI) {
1022     return DI->getKind() == DK_MIRParser;
1023   }
1024 };
1025 
1026 /// Diagnostic information for IR instrumentation reporting.
1027 class DiagnosticInfoInstrumentation : public DiagnosticInfo {
1028   const Twine &Msg;
1029 
1030 public:
1031   DiagnosticInfoInstrumentation(const Twine &DiagMsg,
1032                                 DiagnosticSeverity Severity = DS_Warning)
1033       : DiagnosticInfo(DK_Instrumentation, Severity), Msg(DiagMsg) {}
1034 
1035   void print(DiagnosticPrinter &DP) const override;
1036 
1037   static bool classof(const DiagnosticInfo *DI) {
1038     return DI->getKind() == DK_Instrumentation;
1039   }
1040 };
1041 
1042 /// Diagnostic information for ISel fallback path.
1043 class DiagnosticInfoISelFallback : public DiagnosticInfo {
1044   /// The function that is concerned by this diagnostic.
1045   const Function &Fn;
1046 
1047 public:
1048   DiagnosticInfoISelFallback(const Function &Fn,
1049                              DiagnosticSeverity Severity = DS_Warning)
1050       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
1051 
1052   const Function &getFunction() const { return Fn; }
1053 
1054   void print(DiagnosticPrinter &DP) const override;
1055 
1056   static bool classof(const DiagnosticInfo *DI) {
1057     return DI->getKind() == DK_ISelFallback;
1058   }
1059 };
1060 
1061 // Create wrappers for C Binding types (see CBindingWrapping.h).
1062 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
1063 
1064 /// Diagnostic information for optimization failures.
1065 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
1066 public:
1067   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
1068   /// the location information to use in the diagnostic. If line table
1069   /// information is available, the diagnostic will include the source code
1070   /// location. \p Msg is the message to show. Note that this class does not
1071   /// copy this message, so this reference must be valid for the whole life time
1072   /// of the diagnostic.
1073   DiagnosticInfoOptimizationFailure(const Function &Fn,
1074                                     const DiagnosticLocation &Loc,
1075                                     const Twine &Msg)
1076       : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
1077                                      nullptr, Fn, Loc, Msg) {}
1078 
1079   /// \p PassName is the name of the pass emitting this diagnostic.  \p
1080   /// RemarkName is a textual identifier for the remark (single-word,
1081   /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
1082   /// region that the optimization operates on (currently basic block is
1083   /// supported).
1084   DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
1085                                     const DiagnosticLocation &Loc,
1086                                     const Value *CodeRegion);
1087 
1088   static bool classof(const DiagnosticInfo *DI) {
1089     return DI->getKind() == DK_OptimizationFailure;
1090   }
1091 
1092   /// \see DiagnosticInfoOptimizationBase::isEnabled.
1093   bool isEnabled() const override;
1094 };
1095 
1096 /// Diagnostic information for unsupported feature in backend.
1097 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
1098 private:
1099   Twine Msg;
1100 
1101 public:
1102   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
1103   /// the location information to use in the diagnostic. If line table
1104   /// information is available, the diagnostic will include the source code
1105   /// location. \p Msg is the message to show. Note that this class does not
1106   /// copy this message, so this reference must be valid for the whole life time
1107   /// of the diagnostic.
1108   DiagnosticInfoUnsupported(
1109       const Function &Fn, const Twine &Msg,
1110       const DiagnosticLocation &Loc = DiagnosticLocation(),
1111       DiagnosticSeverity Severity = DS_Error)
1112       : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
1113         Msg(Msg) {}
1114 
1115   static bool classof(const DiagnosticInfo *DI) {
1116     return DI->getKind() == DK_Unsupported;
1117   }
1118 
1119   const Twine &getMessage() const { return Msg; }
1120 
1121   void print(DiagnosticPrinter &DP) const override;
1122 };
1123 
1124 /// Diagnostic information for MisExpect analysis.
1125 class DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase {
1126 public:
1127   DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg);
1128 
1129   /// \see DiagnosticInfo::print.
1130   void print(DiagnosticPrinter &DP) const override;
1131 
1132   static bool classof(const DiagnosticInfo *DI) {
1133     return DI->getKind() == DK_MisExpect;
1134   }
1135 
1136   const Twine &getMsg() const { return Msg; }
1137 
1138 private:
1139   /// Message to report.
1140   const Twine &Msg;
1141 };
1142 
1143 static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {
1144   switch (DK) {
1145   case llvm::SourceMgr::DK_Error:
1146     return DS_Error;
1147     break;
1148   case llvm::SourceMgr::DK_Warning:
1149     return DS_Warning;
1150     break;
1151   case llvm::SourceMgr::DK_Note:
1152     return DS_Note;
1153     break;
1154   case llvm::SourceMgr::DK_Remark:
1155     return DS_Remark;
1156     break;
1157   }
1158   llvm_unreachable("unknown SourceMgr::DiagKind");
1159 }
1160 
1161 /// Diagnostic information for SMDiagnostic reporting.
1162 class DiagnosticInfoSrcMgr : public DiagnosticInfo {
1163   const SMDiagnostic &Diagnostic;
1164   StringRef ModName;
1165 
1166   // For inlineasm !srcloc translation.
1167   bool InlineAsmDiag;
1168   uint64_t LocCookie;
1169 
1170 public:
1171   DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic, StringRef ModName,
1172                        bool InlineAsmDiag = true, uint64_t LocCookie = 0)
1173       : DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())),
1174         Diagnostic(Diagnostic), ModName(ModName), InlineAsmDiag(InlineAsmDiag),
1175         LocCookie(LocCookie) {}
1176 
1177   StringRef getModuleName() const { return ModName; }
1178   bool isInlineAsmDiag() const { return InlineAsmDiag; }
1179   const SMDiagnostic &getSMDiag() const { return Diagnostic; }
1180   uint64_t getLocCookie() const { return LocCookie; }
1181   void print(DiagnosticPrinter &DP) const override;
1182 
1183   static bool classof(const DiagnosticInfo *DI) {
1184     return DI->getKind() == DK_SrcMgr;
1185   }
1186 };
1187 
1188 void diagnoseDontCall(const CallInst &CI);
1189 
1190 class DiagnosticInfoDontCall : public DiagnosticInfo {
1191   StringRef CalleeName;
1192   StringRef Note;
1193   uint64_t LocCookie;
1194 
1195 public:
1196   DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note,
1197                          DiagnosticSeverity DS, uint64_t LocCookie)
1198       : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note),
1199         LocCookie(LocCookie) {}
1200   StringRef getFunctionName() const { return CalleeName; }
1201   StringRef getNote() const { return Note; }
1202   uint64_t getLocCookie() const { return LocCookie; }
1203   void print(DiagnosticPrinter &DP) const override;
1204   static bool classof(const DiagnosticInfo *DI) {
1205     return DI->getKind() == DK_DontCall;
1206   }
1207 };
1208 
1209 } // end namespace llvm
1210 
1211 #endif // LLVM_IR_DIAGNOSTICINFO_H