//===---- llvm/Support/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_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H

#include "llvm/ADT/DenseMapInfo.h"

namespace llvm {
  class MDNode;
  class LLVMContext;
  
  /// 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.
    unsigned 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 = 0);
    
    /// 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;
    
    
    /// 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;
  };

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

#endif /* LLVM_DEBUGLOC_H */
