//===- DebugLoc.h - Debug Location Information ------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a number of light weight data structures used
// to describe and track debug location information.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_DEBUGLOC_H
#define LLVM_IR_DEBUGLOC_H

#include "llvm/Support/DataTypes.h"

namespace llvm {
  template <typename T> struct DenseMapInfo;
  class MDNode;
  class LLVMContext;
  class raw_ostream;

  /// DebugLoc - Debug location id.  This is carried by Instruction, SDNode,
  /// and MachineInstr to compactly encode file/line/scope information for an
  /// operation.
  class DebugLoc {
    friend struct DenseMapInfo<DebugLoc>;

    /// getEmptyKey() - A private constructor that returns an unknown that is
    /// not equal to the tombstone key or DebugLoc().
    static DebugLoc getEmptyKey() {
      DebugLoc DL;
      DL.LineCol = 1;
      return DL;
    }

    /// getTombstoneKey() - A private constructor that returns an unknown that
    /// is not equal to the empty key or DebugLoc().
    static DebugLoc getTombstoneKey() {
      DebugLoc DL;
      DL.LineCol = 2;
      return DL;
    }

    /// LineCol - This 32-bit value encodes the line and column number for the
    /// location, encoded as 24-bits for line and 8 bits for col.  A value of 0
    /// for either means unknown.
    uint32_t LineCol;

    /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
    /// decoded by LLVMContext.  0 is unknown.
    int ScopeIdx;
  public:
    DebugLoc() : LineCol(0), ScopeIdx(0) {}  // Defaults to unknown.

    /// get - Get a new DebugLoc that corresponds to the specified line/col
    /// scope/inline location.
    static DebugLoc get(unsigned Line, unsigned Col,
                        MDNode *Scope, MDNode *InlinedAt = nullptr);

    /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
    static DebugLoc getFromDILocation(MDNode *N);

    /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
    static DebugLoc getFromDILexicalBlock(MDNode *N);

    /// isUnknown - Return true if this is an unknown location.
    bool isUnknown() const { return ScopeIdx == 0; }

    unsigned getLine() const {
      return (LineCol << 8) >> 8;  // Mask out column.
    }

    unsigned getCol() const {
      return LineCol >> 24;
    }

    /// getScope - This returns the scope pointer for this DebugLoc, or null if
    /// invalid.
    MDNode *getScope(const LLVMContext &Ctx) const;

    /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
    /// null if invalid or not present.
    MDNode *getInlinedAt(const LLVMContext &Ctx) const;

    /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
    void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
                              const LLVMContext &Ctx) const;

    /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
    MDNode *getScopeNode(const LLVMContext &Ctx) const;

    // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
    // number info for the function.
    DebugLoc getFnDebugLoc(const LLVMContext &Ctx) const;

    /// getAsMDNode - This method converts the compressed DebugLoc node into a
    /// DILocation compatible MDNode.
    MDNode *getAsMDNode(const LLVMContext &Ctx) const;

    bool operator==(const DebugLoc &DL) const {
      return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
    }
    bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }

    void dump(const LLVMContext &Ctx) const;
    /// \brief prints source location /path/to/file.exe:line:col @[inlined at]
    void print(const LLVMContext &Ctx, raw_ostream &OS) const;
  };

  template <>
  struct DenseMapInfo<DebugLoc> {
    static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
    static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
    static unsigned getHashValue(const DebugLoc &Key);
    static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
  };
} // end namespace llvm

#endif /* LLVM_SUPPORT_DEBUGLOC_H */
