//===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the different classes involved in low level diagnostics.
//
// Diagnostics reporting is still done as part of the LLVMContext.
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_DIAGNOSTICINFO_H
#define LLVM_IR_DIAGNOSTICINFO_H

#include "llvm-c/Types.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstdint>
#include <functional>
#include <iterator>
#include <string>

namespace llvm {

// Forward declarations.
class DiagnosticPrinter;
class CallInst;
class Function;
class Instruction;
class InstructionCost;
class LLVMContext;
class Module;
class SMDiagnostic;

/// Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity : char {
  DS_Error,
  DS_Warning,
  DS_Remark,
  // A note attaches additional information to one of the previous diagnostic
  // types.
  DS_Note
};

/// Defines the different supported kind of a diagnostic.
/// This enum should be extended with a new ID for each added concrete subclass.
enum DiagnosticKind {
  DK_InlineAsm,
  DK_ResourceLimit,
  DK_StackSize,
  DK_Linker,
  DK_Lowering,
  DK_DebugMetadataVersion,
  DK_DebugMetadataInvalid,
  DK_ISelFallback,
  DK_SampleProfile,
  DK_OptimizationRemark,
  DK_OptimizationRemarkMissed,
  DK_OptimizationRemarkAnalysis,
  DK_OptimizationRemarkAnalysisFPCommute,
  DK_OptimizationRemarkAnalysisAliasing,
  DK_OptimizationFailure,
  DK_FirstRemark = DK_OptimizationRemark,
  DK_LastRemark = DK_OptimizationFailure,
  DK_MachineOptimizationRemark,
  DK_MachineOptimizationRemarkMissed,
  DK_MachineOptimizationRemarkAnalysis,
  DK_FirstMachineRemark = DK_MachineOptimizationRemark,
  DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
  DK_MIRParser,
  DK_PGOProfile,
  DK_Unsupported,
  DK_SrcMgr,
  DK_DontCall,
  DK_FirstPluginKind // Must be last value to work with
                     // getNextAvailablePluginDiagnosticKind
};

/// Get the next available kind ID for a plugin diagnostic.
/// Each time this function is called, it returns a different number.
/// Therefore, a plugin that wants to "identify" its own classes
/// with a dynamic identifier, just have to use this method to get a new ID
/// and assign it to each of its classes.
/// The returned ID will be greater than or equal to DK_FirstPluginKind.
/// Thus, the plugin identifiers will not conflict with the
/// DiagnosticKind values.
int getNextAvailablePluginDiagnosticKind();

/// This is the base abstract class for diagnostic reporting in
/// the backend.
/// The print method must be overloaded by the subclasses to print a
/// user-friendly message in the client of the backend (let us call it a
/// frontend).
class DiagnosticInfo {
private:
  /// Kind defines the kind of report this is about.
  const /* DiagnosticKind */ int Kind;
  /// Severity gives the severity of the diagnostic.
  const DiagnosticSeverity Severity;

  virtual void anchor();
public:
  DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
      : Kind(Kind), Severity(Severity) {}

  virtual ~DiagnosticInfo() = default;

  /* DiagnosticKind */ int getKind() const { return Kind; }
  DiagnosticSeverity getSeverity() const { return Severity; }

  /// Print using the given \p DP a user-friendly message.
  /// This is the default message that will be printed to the user.
  /// It is used when the frontend does not directly take advantage
  /// of the information contained in fields of the subclasses.
  /// The printed message must not end with '.' nor start with a severity
  /// keyword.
  virtual void print(DiagnosticPrinter &DP) const = 0;
};

using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;

/// Diagnostic information for inline asm reporting.
/// This is basically a message and an optional location.
class DiagnosticInfoInlineAsm : public DiagnosticInfo {
private:
  /// Optional line information. 0 if not set.
  uint64_t LocCookie = 0;
  /// Message to be reported.
  const Twine &MsgStr;
  /// Optional origin of the problem.
  const Instruction *Instr = nullptr;

public:
  /// \p MsgStr is the message to be reported to the frontend.
  /// This class does not copy \p MsgStr, therefore the reference must be valid
  /// for the whole life time of the Diagnostic.
  DiagnosticInfoInlineAsm(const Twine &MsgStr,
                          DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}

  /// \p LocCookie if non-zero gives the line number for this report.
  /// \p MsgStr gives the message.
  /// This class does not copy \p MsgStr, therefore the reference must be valid
  /// for the whole life time of the Diagnostic.
  DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr,
                          DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
        MsgStr(MsgStr) {}

  /// \p Instr gives the original instruction that triggered the diagnostic.
  /// \p MsgStr gives the message.
  /// This class does not copy \p MsgStr, therefore the reference must be valid
  /// for the whole life time of the Diagnostic.
  /// Same for \p I.
  DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
                          DiagnosticSeverity Severity = DS_Error);

  uint64_t getLocCookie() const { return LocCookie; }
  const Twine &getMsgStr() const { return MsgStr; }
  const Instruction *getInstruction() const { return Instr; }

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_InlineAsm;
  }
};

/// Diagnostic information for stack size etc. reporting.
/// This is basically a function and a size.
class DiagnosticInfoResourceLimit : public DiagnosticInfo {
private:
  /// The function that is concerned by this resource limit diagnostic.
  const Function &Fn;

  /// Description of the resource type (e.g. stack size)
  const char *ResourceName;

  /// The computed size usage
  uint64_t ResourceSize;

  // Threshould passed
  uint64_t ResourceLimit;

public:
  /// \p The function that is concerned by this stack size diagnostic.
  /// \p The computed stack size.
  DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
                              uint64_t ResourceSize, uint64_t ResourceLimit,
                              DiagnosticSeverity Severity = DS_Warning,
                              DiagnosticKind Kind = DK_ResourceLimit)
      : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
        ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}

  const Function &getFunction() const { return Fn; }
  const char *getResourceName() const { return ResourceName; }
  uint64_t getResourceSize() const { return ResourceSize; }
  uint64_t getResourceLimit() const { return ResourceLimit; }

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
  }
};

class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
  void anchor() override;
public:
  DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
                          uint64_t StackLimit,
                          DiagnosticSeverity Severity = DS_Warning)
      : DiagnosticInfoResourceLimit(Fn, "stack frame size", StackSize,
                                    StackLimit, Severity, DK_StackSize) {}

  uint64_t getStackSize() const { return getResourceSize(); }
  uint64_t getStackLimit() const { return getResourceLimit(); }

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_StackSize;
  }
};

/// Diagnostic information for debug metadata version reporting.
/// This is basically a module and a version.
class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
private:
  /// The module that is concerned by this debug metadata version diagnostic.
  const Module &M;
  /// The actual metadata version.
  unsigned MetadataVersion;

public:
  /// \p The module that is concerned by this debug metadata version diagnostic.
  /// \p The actual metadata version.
  DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
                                     DiagnosticSeverity Severity = DS_Warning)
      : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
        MetadataVersion(MetadataVersion) {}

  const Module &getModule() const { return M; }
  unsigned getMetadataVersion() const { return MetadataVersion; }

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_DebugMetadataVersion;
  }
};

/// Diagnostic information for stripping invalid debug metadata.
class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
private:
  /// The module that is concerned by this debug metadata version diagnostic.
  const Module &M;

public:
  /// \p The module that is concerned by this debug metadata version diagnostic.
  DiagnosticInfoIgnoringInvalidDebugMetadata(
      const Module &M, DiagnosticSeverity Severity = DS_Warning)
      : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}

  const Module &getModule() const { return M; }

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_DebugMetadataInvalid;
  }
};

/// Diagnostic information for the sample profiler.
class DiagnosticInfoSampleProfile : public DiagnosticInfo {
public:
  DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
                              const Twine &Msg,
                              DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
        LineNum(LineNum), Msg(Msg) {}
  DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
                              DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
        Msg(Msg) {}
  DiagnosticInfoSampleProfile(const Twine &Msg,
                              DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_SampleProfile;
  }

  StringRef getFileName() const { return FileName; }
  unsigned getLineNum() const { return LineNum; }
  const Twine &getMsg() const { return Msg; }

private:
  /// Name of the input file associated with this diagnostic.
  StringRef FileName;

  /// Line number where the diagnostic occurred. If 0, no line number will
  /// be emitted in the message.
  unsigned LineNum = 0;

  /// Message to report.
  const Twine &Msg;
};

/// Diagnostic information for the PGO profiler.
class DiagnosticInfoPGOProfile : public DiagnosticInfo {
public:
  DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
                           DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_PGOProfile;
  }

  const char *getFileName() const { return FileName; }
  const Twine &getMsg() const { return Msg; }

private:
  /// Name of the input file associated with this diagnostic.
  const char *FileName;

  /// Message to report.
  const Twine &Msg;
};

class DiagnosticLocation {
  DIFile *File = nullptr;
  unsigned Line = 0;
  unsigned Column = 0;

public:
  DiagnosticLocation() = default;
  DiagnosticLocation(const DebugLoc &DL);
  DiagnosticLocation(const DISubprogram *SP);

  bool isValid() const { return File; }
  /// Return the full path to the file.
  std::string getAbsolutePath() const;
  /// Return the file name relative to the compilation directory.
  StringRef getRelativePath() const;
  unsigned getLine() const { return Line; }
  unsigned getColumn() const { return Column; }
};

/// Common features for diagnostics with an associated location.
class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
  void anchor() override;
public:
  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
  /// the location information to use in the diagnostic.
  DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
                                 enum DiagnosticSeverity Severity,
                                 const Function &Fn,
                                 const DiagnosticLocation &Loc)
      : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}

  /// Return true if location information is available for this diagnostic.
  bool isLocationAvailable() const { return Loc.isValid(); }

  /// Return a string with the location information for this diagnostic
  /// in the format "file:line:col". If location information is not available,
  /// it returns "<unknown>:0:0".
  std::string getLocationStr() const;

  /// Return location information for this diagnostic in three parts:
  /// the relative source file path, line number and column.
  void getLocation(StringRef &RelativePath, unsigned &Line,
                   unsigned &Column) const;

  /// Return the absolute path tot the file.
  std::string getAbsolutePath() const;
  
  const Function &getFunction() const { return Fn; }
  DiagnosticLocation getLocation() const { return Loc; }

private:
  /// Function where this diagnostic is triggered.
  const Function &Fn;

  /// Debug location where this diagnostic is triggered.
  DiagnosticLocation Loc;
};

/// Common features for diagnostics dealing with optimization remarks
/// that are used by both IR and MIR passes.
class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
public:
  /// Used to set IsVerbose via the stream interface.
  struct setIsVerbose {};

  /// When an instance of this is inserted into the stream, the arguments
  /// following will not appear in the remark printed in the compiler output
  /// (-Rpass) but only in the optimization record file
  /// (-fsave-optimization-record).
  struct setExtraArgs {};

  /// Used in the streaming interface as the general argument type.  It
  /// internally converts everything into a key-value pair.
  struct Argument {
    std::string Key;
    std::string Val;
    // If set, the debug location corresponding to the value.
    DiagnosticLocation Loc;

    explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
    Argument(StringRef Key, const Value *V);
    Argument(StringRef Key, const Type *T);
    Argument(StringRef Key, StringRef S);
    Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {};
    Argument(StringRef Key, int N);
    Argument(StringRef Key, float N);
    Argument(StringRef Key, long N);
    Argument(StringRef Key, long long N);
    Argument(StringRef Key, unsigned N);
    Argument(StringRef Key, unsigned long N);
    Argument(StringRef Key, unsigned long long N);
    Argument(StringRef Key, ElementCount EC);
    Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
    Argument(StringRef Key, DebugLoc dl);
    Argument(StringRef Key, InstructionCost C);
  };

  /// \p PassName is the name of the pass emitting this diagnostic. \p
  /// RemarkName is a textual identifier for the remark (single-word,
  /// camel-case). \p Fn is the function where the diagnostic is being emitted.
  /// \p Loc is the location information to use in the diagnostic. If line table
  /// information is available, the diagnostic will include the source code
  /// location.
  DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
                                 enum DiagnosticSeverity Severity,
                                 const char *PassName, StringRef RemarkName,
                                 const Function &Fn,
                                 const DiagnosticLocation &Loc)
      : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
        PassName(PassName), RemarkName(RemarkName) {}

  void insert(StringRef S);
  void insert(Argument A);
  void insert(setIsVerbose V);
  void insert(setExtraArgs EA);

  /// \see DiagnosticInfo::print.
  void print(DiagnosticPrinter &DP) const override;

  /// Return true if this optimization remark is enabled by one of
  /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
  /// or -pass-remarks-analysis). Note that this only handles the LLVM
  /// flags. We cannot access Clang flags from here (they are handled
  /// in BackendConsumer::OptimizationRemarkHandler).
  virtual bool isEnabled() const = 0;

  StringRef getPassName() const { return PassName; }
  StringRef getRemarkName() const { return RemarkName; }
  std::string getMsg() const;
  Optional<uint64_t> getHotness() const { return Hotness; }
  void setHotness(Optional<uint64_t> H) { Hotness = H; }

  bool isVerbose() const { return IsVerbose; }

  ArrayRef<Argument> getArgs() const { return Args; }

  static bool classof(const DiagnosticInfo *DI) {
    return (DI->getKind() >= DK_FirstRemark &&
            DI->getKind() <= DK_LastRemark) ||
           (DI->getKind() >= DK_FirstMachineRemark &&
            DI->getKind() <= DK_LastMachineRemark);
  }

  bool isPassed() const {
    return (getKind() == DK_OptimizationRemark ||
            getKind() == DK_MachineOptimizationRemark);
  }

  bool isMissed() const {
    return (getKind() == DK_OptimizationRemarkMissed ||
            getKind() == DK_MachineOptimizationRemarkMissed);
  }

  bool isAnalysis() const {
    return (getKind() == DK_OptimizationRemarkAnalysis ||
            getKind() == DK_MachineOptimizationRemarkAnalysis);
  }

protected:
  /// Name of the pass that triggers this report. If this matches the
  /// regular expression given in -Rpass=regexp, then the remark will
  /// be emitted.
  const char *PassName;

  /// Textual identifier for the remark (single-word, camel-case). Can be used
  /// by external tools reading the output file for optimization remarks to
  /// identify the remark.
  StringRef RemarkName;

  /// If profile information is available, this is the number of times the
  /// corresponding code was executed in a profile instrumentation run.
  Optional<uint64_t> Hotness;

  /// Arguments collected via the streaming interface.
  SmallVector<Argument, 4> Args;

  /// The remark is expected to be noisy.
  bool IsVerbose = false;

  /// If positive, the index of the first argument that only appear in
  /// the optimization records and not in the remark printed in the compiler
  /// output.
  int FirstExtraArgIndex = -1;
};

/// Allow the insertion operator to return the actual remark type rather than a
/// common base class.  This allows returning the result of the insertion
/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               StringRef>
               S) {
  R.insert(S);
  return R;
}

/// Also allow r-value for the remark to allow insertion into a
/// temporarily-constructed remark.
template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               StringRef>
               S) {
  R.insert(S);
  return R;
}

template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               DiagnosticInfoOptimizationBase::Argument>
               A) {
  R.insert(A);
  return R;
}

template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               DiagnosticInfoOptimizationBase::Argument>
               A) {
  R.insert(A);
  return R;
}

template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               DiagnosticInfoOptimizationBase::setIsVerbose>
               V) {
  R.insert(V);
  return R;
}

template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               DiagnosticInfoOptimizationBase::setIsVerbose>
               V) {
  R.insert(V);
  return R;
}

template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
           std::enable_if_t<
               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
               DiagnosticInfoOptimizationBase::setExtraArgs>
               EA) {
  R.insert(EA);
  return R;
}

/// Common features for diagnostics dealing with optimization remarks
/// that are used by IR passes.
class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
  void anchor() override;
public:
  /// \p PassName is the name of the pass emitting this diagnostic. \p
  /// RemarkName is a textual identifier for the remark (single-word,
  /// camel-case). \p Fn is the function where the diagnostic is being emitted.
  /// \p Loc is the location information to use in the diagnostic. If line table
  /// information is available, the diagnostic will include the source code
  /// location. \p CodeRegion is IR value (currently basic block) that the
  /// optimization operates on. This is currently used to provide run-time
  /// hotness information with PGO.
  DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
                               enum DiagnosticSeverity Severity,
                               const char *PassName, StringRef RemarkName,
                               const Function &Fn,
                               const DiagnosticLocation &Loc,
                               const Value *CodeRegion = nullptr)
      : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
                                       Loc),
        CodeRegion(CodeRegion) {}

  /// This is ctor variant allows a pass to build an optimization remark
  /// from an existing remark.
  ///
  /// This is useful when a transformation pass (e.g LV) wants to emit a remark
  /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
  /// remark.  The string \p Prepend will be emitted before the original
  /// message.
  DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
                               const DiagnosticInfoIROptimization &Orig)
      : DiagnosticInfoOptimizationBase(
            (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
            Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
        CodeRegion(Orig.getCodeRegion()) {
    *this << Prepend;
    std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
  }

  /// Legacy interface.
  /// \p PassName is the name of the pass emitting this diagnostic.
  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
  /// the location information to use in the diagnostic. If line table
  /// information is available, the diagnostic will include the source code
  /// location. \p Msg is the message to show. Note that this class does not
  /// copy this message, so this reference must be valid for the whole life time
  /// of the diagnostic.
  DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
                               enum DiagnosticSeverity Severity,
                               const char *PassName, const Function &Fn,
                               const DiagnosticLocation &Loc, const Twine &Msg)
      : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
    *this << Msg.str();
  }

  const Value *getCodeRegion() const { return CodeRegion; }

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
  }

private:
  /// The IR value (currently basic block) that the optimization operates on.
  /// This is currently used to provide run-time hotness information with PGO.
  const Value *CodeRegion = nullptr;
};

/// Diagnostic information for applied optimization remarks.
class OptimizationRemark : public DiagnosticInfoIROptimization {
public:
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
  /// matches the regular expression given in -Rpass=, then the diagnostic will
  /// be emitted. \p RemarkName is a textual identifier for the remark (single-
  /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
  /// region that the optimization operates on (currently only block is
  /// supported).
  OptimizationRemark(const char *PassName, StringRef RemarkName,
                     const DiagnosticLocation &Loc, const Value *CodeRegion);

  /// Same as above, but the debug location and code region are derived from \p
  /// Instr.
  OptimizationRemark(const char *PassName, StringRef RemarkName,
                     const Instruction *Inst);

  /// Same as above, but the debug location and code region are derived from \p
  /// Func.
  OptimizationRemark(const char *PassName, StringRef RemarkName,
                     const Function *Func);

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationRemark;
  }

  /// \see DiagnosticInfoOptimizationBase::isEnabled.
  bool isEnabled() const override;

private:
  /// This is deprecated now and only used by the function API below.
  /// \p PassName is the name of the pass emitting this diagnostic. If
  /// this name matches the regular expression given in -Rpass=, then the
  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
  /// is being emitted. \p Loc is the location information to use in the
  /// diagnostic. If line table information is available, the diagnostic
  /// will include the source code location. \p Msg is the message to show.
  /// Note that this class does not copy this message, so this reference
  /// must be valid for the whole life time of the diagnostic.
  OptimizationRemark(const char *PassName, const Function &Fn,
                     const DiagnosticLocation &Loc, const Twine &Msg)
      : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
                                     Fn, Loc, Msg) {}
};

/// Diagnostic information for missed-optimization remarks.
class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
public:
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
  /// matches the regular expression given in -Rpass-missed=, then the
  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
  /// remark (single-word, camel-case). \p Loc is the debug location and \p
  /// CodeRegion is the region that the optimization operates on (currently only
  /// block is supported).
  OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
                           const DiagnosticLocation &Loc,
                           const Value *CodeRegion);

  /// Same as above but \p Inst is used to derive code region and debug
  /// location.
  OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
                           const Instruction *Inst);

  /// Same as above but \p F is used to derive code region and debug
  /// location.
  OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
                           const Function *F);

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationRemarkMissed;
  }

  /// \see DiagnosticInfoOptimizationBase::isEnabled.
  bool isEnabled() const override;

private:
  /// This is deprecated now and only used by the function API below.
  /// \p PassName is the name of the pass emitting this diagnostic. If
  /// this name matches the regular expression given in -Rpass-missed=, then the
  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
  /// is being emitted. \p Loc is the location information to use in the
  /// diagnostic. If line table information is available, the diagnostic
  /// will include the source code location. \p Msg is the message to show.
  /// Note that this class does not copy this message, so this reference
  /// must be valid for the whole life time of the diagnostic.
  OptimizationRemarkMissed(const char *PassName, const Function &Fn,
                           const DiagnosticLocation &Loc, const Twine &Msg)
      : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
                                     PassName, Fn, Loc, Msg) {}
};

/// Diagnostic information for optimization analysis remarks.
class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
public:
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
  /// matches the regular expression given in -Rpass-analysis=, then the
  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
  /// remark (single-word, camel-case). \p Loc is the debug location and \p
  /// CodeRegion is the region that the optimization operates on (currently only
  /// block is supported).
  OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
                             const DiagnosticLocation &Loc,
                             const Value *CodeRegion);

  /// This is ctor variant allows a pass to build an optimization remark
  /// from an existing remark.
  ///
  /// This is useful when a transformation pass (e.g LV) wants to emit a remark
  /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
  /// remark.  The string \p Prepend will be emitted before the original
  /// message.
  OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
                             const OptimizationRemarkAnalysis &Orig)
      : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}

  /// Same as above but \p Inst is used to derive code region and debug
  /// location.
  OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
                             const Instruction *Inst);

  /// Same as above but \p F is used to derive code region and debug
  /// location.
  OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
                             const Function *F);

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationRemarkAnalysis;
  }

  /// \see DiagnosticInfoOptimizationBase::isEnabled.
  bool isEnabled() const override;

  static const char *AlwaysPrint;

  bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }

protected:
  OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
                             const Function &Fn, const DiagnosticLocation &Loc,
                             const Twine &Msg)
      : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}

  OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
                             StringRef RemarkName,
                             const DiagnosticLocation &Loc,
                             const Value *CodeRegion);

private:
  /// This is deprecated now and only used by the function API below.
  /// \p PassName is the name of the pass emitting this diagnostic. If
  /// this name matches the regular expression given in -Rpass-analysis=, then
  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
  /// is being emitted. \p Loc is the location information to use in the
  /// diagnostic. If line table information is available, the diagnostic will
  /// include the source code location. \p Msg is the message to show. Note that
  /// this class does not copy this message, so this reference must be valid for
  /// the whole life time of the diagnostic.
  OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
                             const DiagnosticLocation &Loc, const Twine &Msg)
      : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
                                     PassName, Fn, Loc, Msg) {}
};

/// Diagnostic information for optimization analysis remarks related to
/// floating-point non-commutativity.
class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
  void anchor() override;
public:
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
  /// matches the regular expression given in -Rpass-analysis=, then the
  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
  /// remark (single-word, camel-case). \p Loc is the debug location and \p
  /// CodeRegion is the region that the optimization operates on (currently only
  /// block is supported). The front-end will append its own message related to
  /// options that address floating-point non-commutativity.
  OptimizationRemarkAnalysisFPCommute(const char *PassName,
                                      StringRef RemarkName,
                                      const DiagnosticLocation &Loc,
                                      const Value *CodeRegion)
      : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
                                   PassName, RemarkName, Loc, CodeRegion) {}

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
  }

private:
  /// This is deprecated now and only used by the function API below.
  /// \p PassName is the name of the pass emitting this diagnostic. If
  /// this name matches the regular expression given in -Rpass-analysis=, then
  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
  /// is being emitted. \p Loc is the location information to use in the
  /// diagnostic. If line table information is available, the diagnostic will
  /// include the source code location. \p Msg is the message to show. The
  /// front-end will append its own message related to options that address
  /// floating-point non-commutativity. Note that this class does not copy this
  /// message, so this reference must be valid for the whole life time of the
  /// diagnostic.
  OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
                                      const DiagnosticLocation &Loc,
                                      const Twine &Msg)
      : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
                                   PassName, Fn, Loc, Msg) {}
};

/// Diagnostic information for optimization analysis remarks related to
/// pointer aliasing.
class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
  void anchor() override;
public:
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
  /// matches the regular expression given in -Rpass-analysis=, then the
  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
  /// remark (single-word, camel-case). \p Loc is the debug location and \p
  /// CodeRegion is the region that the optimization operates on (currently only
  /// block is supported). The front-end will append its own message related to
  /// options that address pointer aliasing legality.
  OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
                                     const DiagnosticLocation &Loc,
                                     const Value *CodeRegion)
      : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
                                   PassName, RemarkName, Loc, CodeRegion) {}

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
  }

private:
  /// This is deprecated now and only used by the function API below.
  /// \p PassName is the name of the pass emitting this diagnostic. If
  /// this name matches the regular expression given in -Rpass-analysis=, then
  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
  /// is being emitted. \p Loc is the location information to use in the
  /// diagnostic. If line table information is available, the diagnostic will
  /// include the source code location. \p Msg is the message to show. The
  /// front-end will append its own message related to options that address
  /// pointer aliasing legality. Note that this class does not copy this
  /// message, so this reference must be valid for the whole life time of the
  /// diagnostic.
  OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
                                     const DiagnosticLocation &Loc,
                                     const Twine &Msg)
      : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
                                   PassName, Fn, Loc, Msg) {}
};

/// Diagnostic information for machine IR parser.
// FIXME: Remove this, use DiagnosticInfoSrcMgr instead.
class DiagnosticInfoMIRParser : public DiagnosticInfo {
  const SMDiagnostic &Diagnostic;

public:
  DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
                          const SMDiagnostic &Diagnostic)
      : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}

  const SMDiagnostic &getDiagnostic() const { return Diagnostic; }

  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_MIRParser;
  }
};

/// Diagnostic information for ISel fallback path.
class DiagnosticInfoISelFallback : public DiagnosticInfo {
  /// The function that is concerned by this diagnostic.
  const Function &Fn;

public:
  DiagnosticInfoISelFallback(const Function &Fn,
                             DiagnosticSeverity Severity = DS_Warning)
      : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}

  const Function &getFunction() const { return Fn; }

  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_ISelFallback;
  }
};

// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)

/// Diagnostic information for optimization failures.
class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
public:
  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
  /// the location information to use in the diagnostic. If line table
  /// information is available, the diagnostic will include the source code
  /// location. \p Msg is the message to show. Note that this class does not
  /// copy this message, so this reference must be valid for the whole life time
  /// of the diagnostic.
  DiagnosticInfoOptimizationFailure(const Function &Fn,
                                    const DiagnosticLocation &Loc,
                                    const Twine &Msg)
      : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
                                     nullptr, Fn, Loc, Msg) {}

  /// \p PassName is the name of the pass emitting this diagnostic.  \p
  /// RemarkName is a textual identifier for the remark (single-word,
  /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
  /// region that the optimization operates on (currently basic block is
  /// supported).
  DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
                                    const DiagnosticLocation &Loc,
                                    const Value *CodeRegion);

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_OptimizationFailure;
  }

  /// \see DiagnosticInfoOptimizationBase::isEnabled.
  bool isEnabled() const override;
};

/// Diagnostic information for unsupported feature in backend.
class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
private:
  Twine Msg;

public:
  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
  /// the location information to use in the diagnostic. If line table
  /// information is available, the diagnostic will include the source code
  /// location. \p Msg is the message to show. Note that this class does not
  /// copy this message, so this reference must be valid for the whole life time
  /// of the diagnostic.
  DiagnosticInfoUnsupported(
      const Function &Fn, const Twine &Msg,
      const DiagnosticLocation &Loc = DiagnosticLocation(),
      DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
        Msg(Msg) {}

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_Unsupported;
  }

  const Twine &getMessage() const { return Msg; }

  void print(DiagnosticPrinter &DP) const override;
};

static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {
  switch (DK) {
  case llvm::SourceMgr::DK_Error:
    return DS_Error;
    break;
  case llvm::SourceMgr::DK_Warning:
    return DS_Warning;
    break;
  case llvm::SourceMgr::DK_Note:
    return DS_Note;
    break;
  case llvm::SourceMgr::DK_Remark:
    return DS_Remark;
    break;
  }
  llvm_unreachable("unknown SourceMgr::DiagKind");
}

/// Diagnostic information for SMDiagnostic reporting.
class DiagnosticInfoSrcMgr : public DiagnosticInfo {
  const SMDiagnostic &Diagnostic;

  // For inlineasm !srcloc translation.
  bool InlineAsmDiag;
  unsigned LocCookie;

public:
  DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic,
                       bool InlineAsmDiag = true, unsigned LocCookie = 0)
      : DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())),
        Diagnostic(Diagnostic), InlineAsmDiag(InlineAsmDiag),
        LocCookie(LocCookie) {}

  bool isInlineAsmDiag() const { return InlineAsmDiag; }
  const SMDiagnostic &getSMDiag() const { return Diagnostic; }
  unsigned getLocCookie() const { return LocCookie; }
  void print(DiagnosticPrinter &DP) const override;

  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_SrcMgr;
  }
};

void diagnoseDontCall(const CallInst &CI);

class DiagnosticInfoDontCall : public DiagnosticInfo {
  StringRef CalleeName;
  StringRef Note;
  unsigned LocCookie;

public:
  DiagnosticInfoDontCall(StringRef CalleeName, StringRef Note,
                         DiagnosticSeverity DS, unsigned LocCookie)
      : DiagnosticInfo(DK_DontCall, DS), CalleeName(CalleeName), Note(Note),
        LocCookie(LocCookie) {}
  StringRef getFunctionName() const { return CalleeName; }
  StringRef getNote() const { return Note; }
  unsigned getLocCookie() const { return LocCookie; }
  void print(DiagnosticPrinter &DP) const override;
  static bool classof(const DiagnosticInfo *DI) {
    return DI->getKind() == DK_DontCall;
  }
};

} // end namespace llvm

#endif // LLVM_IR_DIAGNOSTICINFO_H
