//===-- llvm/CodeGen/DebugLocEntry.h - Entry in debug_loc list -*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H

#include "DebugLocStream.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Debug.h"

namespace llvm {
class AsmPrinter;

/// This struct describes target specific location.
struct TargetIndexLocation {
  int Index;
  int Offset;

  TargetIndexLocation() = default;
  TargetIndexLocation(unsigned Idx, int64_t Offset)
      : Index(Idx), Offset(Offset) {}

  bool operator==(const TargetIndexLocation &Other) const {
    return Index == Other.Index && Offset == Other.Offset;
  }
};

/// A single location or constant within a variable location description, with
/// either a single entry (with an optional DIExpression) used for a DBG_VALUE,
/// or a list of entries used for a DBG_VALUE_LIST.
class DbgValueLocEntry {

  /// Type of entry that this represents.
  enum EntryType {
    E_Location,
    E_Integer,
    E_ConstantFP,
    E_ConstantInt,
    E_TargetIndexLocation
  };
  enum EntryType EntryKind;

  /// Either a constant,
  union {
    int64_t Int;
    const ConstantFP *CFP;
    const ConstantInt *CIP;
  } Constant;

  union {
    /// Or a location in the machine frame.
    MachineLocation Loc;
    /// Or a location from target specific location.
    TargetIndexLocation TIL;
  };

public:
  DbgValueLocEntry(int64_t i) : EntryKind(E_Integer) { Constant.Int = i; }
  DbgValueLocEntry(const ConstantFP *CFP) : EntryKind(E_ConstantFP) {
    Constant.CFP = CFP;
  }
  DbgValueLocEntry(const ConstantInt *CIP) : EntryKind(E_ConstantInt) {
    Constant.CIP = CIP;
  }
  DbgValueLocEntry(MachineLocation Loc) : EntryKind(E_Location), Loc(Loc) {}
  DbgValueLocEntry(TargetIndexLocation Loc)
      : EntryKind(E_TargetIndexLocation), TIL(Loc) {}

  bool isLocation() const { return EntryKind == E_Location; }
  bool isIndirectLocation() const {
    return EntryKind == E_Location && Loc.isIndirect();
  }
  bool isTargetIndexLocation() const {
    return EntryKind == E_TargetIndexLocation;
  }
  bool isInt() const { return EntryKind == E_Integer; }
  bool isConstantFP() const { return EntryKind == E_ConstantFP; }
  bool isConstantInt() const { return EntryKind == E_ConstantInt; }
  int64_t getInt() const { return Constant.Int; }
  const ConstantFP *getConstantFP() const { return Constant.CFP; }
  const ConstantInt *getConstantInt() const { return Constant.CIP; }
  MachineLocation getLoc() const { return Loc; }
  TargetIndexLocation getTargetIndexLocation() const { return TIL; }
  friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  LLVM_DUMP_METHOD void dump() const {
    if (isLocation()) {
      llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
      if (Loc.isIndirect())
        llvm::dbgs() << "+0";
      llvm::dbgs() << "} ";
    } else if (isConstantInt())
      Constant.CIP->dump();
    else if (isConstantFP())
      Constant.CFP->dump();
  }
#endif
};

/// The location of a single variable, composed of an expression and 0 or more
/// DbgValueLocEntries.
class DbgValueLoc {
  /// Any complex address location expression for this DbgValueLoc.
  const DIExpression *Expression;

  SmallVector<DbgValueLocEntry, 2> ValueLocEntries;

  bool IsVariadic;

public:
  DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
      : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
        IsVariadic(true) {}

  DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
              bool IsVariadic)
      : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
        IsVariadic(IsVariadic) {
#ifndef NDEBUG
    assert(Expr->isValid() ||
           !any_of(Locs, [](auto LE) { return LE.isLocation(); }));
    if (!IsVariadic) {
      assert(ValueLocEntries.size() == 1);
    }
#endif
  }

  DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
      : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
    assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
           "DBG_VALUE with a machine location must have a valid expression.");
  }

  bool isFragment() const { return getExpression()->isFragment(); }
  bool isEntryVal() const { return getExpression()->isEntryValue(); }
  bool isVariadic() const { return IsVariadic; }
  bool isEquivalent(const DbgValueLoc &Other) const {
    // Cannot be equivalent with different numbers of entries.
    if (ValueLocEntries.size() != Other.ValueLocEntries.size())
      return false;
    bool ThisIsIndirect =
        !IsVariadic && ValueLocEntries[0].isIndirectLocation();
    bool OtherIsIndirect =
        !Other.IsVariadic && Other.ValueLocEntries[0].isIndirectLocation();
    // Check equivalence of DIExpressions + Directness together.
    if (!DIExpression::isEqualExpression(Expression, ThisIsIndirect,
                                         Other.Expression, OtherIsIndirect))
      return false;
    // Indirectness should have been accounted for in the above check, so just
    // compare register values directly here.
    if (ThisIsIndirect || OtherIsIndirect) {
      DbgValueLocEntry ThisOp = ValueLocEntries[0];
      DbgValueLocEntry OtherOp = Other.ValueLocEntries[0];
      return ThisOp.isLocation() && OtherOp.isLocation() &&
             ThisOp.getLoc().getReg() == OtherOp.getLoc().getReg();
    }
    // If neither are indirect, then just compare the loc entries directly.
    return ValueLocEntries == Other.ValueLocEntries;
  }
  const DIExpression *getExpression() const { return Expression; }
  ArrayRef<DbgValueLocEntry> getLocEntries() const { return ValueLocEntries; }
  friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
  friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  LLVM_DUMP_METHOD void dump() const {
    for (const DbgValueLocEntry &DV : ValueLocEntries)
      DV.dump();
    if (Expression)
      Expression->dump();
  }
#endif
};

/// This struct describes location entries emitted in the .debug_loc
/// section.
class DebugLocEntry {
  /// Begin and end symbols for the address range that this location is valid.
  const MCSymbol *Begin;
  const MCSymbol *End;

  /// A nonempty list of locations/constants belonging to this entry,
  /// sorted by offset.
  SmallVector<DbgValueLoc, 1> Values;

public:
  /// Create a location list entry for the range [\p Begin, \p End).
  ///
  /// \param Vals One or more values describing (parts of) the variable.
  DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End,
                ArrayRef<DbgValueLoc> Vals)
      : Begin(Begin), End(End) {
    addValues(Vals);
  }

  /// Attempt to merge this DebugLocEntry with Next and return
  /// true if the merge was successful. Entries can be merged if they
  /// share the same Loc/Constant and if Next immediately follows this
  /// Entry.
  bool MergeRanges(const DebugLocEntry &Next) {
    // If this and Next are describing the same variable, merge them.
    if (End != Next.Begin)
      return false;
    if (Values.size() != Next.Values.size())
      return false;
    for (unsigned EntryIdx = 0; EntryIdx < Values.size(); ++EntryIdx)
      if (!Values[EntryIdx].isEquivalent(Next.Values[EntryIdx]))
        return false;
    End = Next.End;
    return true;
  }

  const MCSymbol *getBeginSym() const { return Begin; }
  const MCSymbol *getEndSym() const { return End; }
  ArrayRef<DbgValueLoc> getValues() const { return Values; }
  void addValues(ArrayRef<DbgValueLoc> Vals) {
    Values.append(Vals.begin(), Vals.end());
    sortUniqueValues();
    assert((Values.size() == 1 || all_of(Values, [](DbgValueLoc V) {
              return V.isFragment();
            })) && "must either have a single value or multiple pieces");
  }

  // Sort the pieces by offset.
  // Remove any duplicate entries by dropping all but the first.
  void sortUniqueValues() {
    // Values is either 1 item that does not have a fragment, or many items
    // that all do. No need to sort if the former and also prevents operator<
    // being called on a non fragment item when _GLIBCXX_DEBUG is defined.
    if (Values.size() == 1)
      return;
    llvm::sort(Values);
    Values.erase(std::unique(Values.begin(), Values.end(),
                             [](const DbgValueLoc &A, const DbgValueLoc &B) {
                               return A.getExpression() == B.getExpression();
                             }),
                 Values.end());
  }

  /// Lower this entry into a DWARF expression.
  void finalize(const AsmPrinter &AP,
                DebugLocStream::ListBuilder &List,
                const DIBasicType *BT,
                DwarfCompileUnit &TheCU);
};

/// Compare two DbgValueLocEntries for equality.
inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
  if (A.EntryKind != B.EntryKind)
    return false;

  switch (A.EntryKind) {
  case DbgValueLocEntry::E_Location:
    return A.Loc == B.Loc;
  case DbgValueLocEntry::E_TargetIndexLocation:
    return A.TIL == B.TIL;
  case DbgValueLocEntry::E_Integer:
    return A.Constant.Int == B.Constant.Int;
  case DbgValueLocEntry::E_ConstantFP:
    return A.Constant.CFP == B.Constant.CFP;
  case DbgValueLocEntry::E_ConstantInt:
    return A.Constant.CIP == B.Constant.CIP;
  }
  llvm_unreachable("unhandled EntryKind");
}

/// Compare two DbgValueLocs for equality.
inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
  return A.ValueLocEntries == B.ValueLocEntries &&
         A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
}

/// Compare two fragments based on their offset.
inline bool operator<(const DbgValueLoc &A,
                      const DbgValueLoc &B) {
  return A.getExpression()->getFragmentInfo()->OffsetInBits <
         B.getExpression()->getFragmentInfo()->OffsetInBits;
}

}

#endif
