//===--- SILLocation.h - Location information for SIL nodes -----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SIL_LOCATION_H
#define SWIFT_SIL_LOCATION_H

#include "llvm/ADT/PointerUnion.h"
#include "swift/Basic/SourceLoc.h"
#include "swift/Basic/SourceManager.h"
#include "swift/AST/TypeAlignments.h"

#include <cstddef>
#include <type_traits>

namespace swift {

class SourceLoc;
class ReturnStmt;
class BraceStmt;
class AbstractClosureExpr;
class AbstractFunctionDecl;

/// This is a pointer to the AST node that a SIL instruction was
/// derived from. This may be null if AST information is unavailable or
/// stripped.
///
/// FIXME: This should eventually include inlining history, generics
/// instantiation info, etc (when we get to it).
///
class SILLocation {
private:
  template <class T, class Enable = void>
  struct base_type;

  template <class T>
  struct base_type<T,
      typename std::enable_if<std::is_base_of<Decl, T>::value>::type> {
    using type = Decl;
  };

  template <class T>
  struct base_type<T,
      typename std::enable_if<std::is_base_of<Expr, T>::value>::type> {
    using type = Expr;
  };

  template <class T>
  struct base_type<T,
      typename std::enable_if<std::is_base_of<Stmt, T>::value>::type> {
    using type = Stmt;
  };

  template <class T>
  struct base_type<T,
      typename std::enable_if<std::is_base_of<Pattern, T>::value>::type> {
    using type = Pattern;
  };

  using ASTNodeTy = llvm::PointerUnion<Stmt *, Expr *, Decl *, Pattern *>;

public:
  enum LocationKind : unsigned {
    RegularKind = 1,
    ReturnKind = 2,
    ImplicitReturnKind = 3,
    InlinedKind = 4,
    MandatoryInlinedKind = 5,
    CleanupKind = 6,
    ArtificialUnreachableKind = 7
  };

  enum StorageKind : unsigned {
    UnknownKind = 0,
    ASTNodeKind = 1 << 3,
    SILFileKind = 1 << 4,
    DebugInfoKind = 1 << 3 | 1 << 4
  };

  struct DebugLoc {
    unsigned Line;
    unsigned Column;
    StringRef Filename;

    DebugLoc(unsigned Line = 0, unsigned Column = 0,
             StringRef Filename = StringRef())
        : Line(Line), Column(Column), Filename(Filename) {}

    inline bool operator==(const DebugLoc &R) const {
      return Line == R.Line && Column == R.Column &&
             Filename.equals(R.Filename);
    }
  };

protected:
  union UnderlyingLocation {
    UnderlyingLocation() : DebugInfoLoc({}) {}
    UnderlyingLocation(ASTNodeTy N) : ASTNode(N) {}
    UnderlyingLocation(SourceLoc L) : SILFileLoc(L) {}
    UnderlyingLocation(DebugLoc D)
        : DebugInfoLoc({D.Filename.data(), D.Line, D.Column}) {}
    struct ASTNodeLoc {
      ASTNodeLoc(ASTNodeTy N) : Primary(N) {}
      /// Primary AST location, always used for diagnostics.
      ASTNodeTy Primary;
      /// Sometimes the location for diagnostics needs to be
      /// different than the one used to emit the line table. If
      /// HasDebugLoc is set, this is used for the debug info.
      ASTNodeTy ForDebugger;
    } ASTNode;

    /// A location inside a textual .sil file.
    SourceLoc SILFileLoc;

    /// A deserialized source location.
    ///
    /// This represents \e most of the information in a SILLocation::DebugLoc,
    /// but for bit-packing purposes the length of the filename is stored in
    /// the SILLocation's ExtraStorageData instead of here.
    ///
    /// \sa SILLocation::getDebugInfoLoc
    struct CompactDebugLoc {
      const char *FilenameData;
      unsigned Line;
      unsigned Column;
    } DebugInfoLoc;
  } Loc;

  /// The kind of this SIL location.
  unsigned KindData;

  /// Extra data that's not in UnderlyingLocation to keep the size of
  /// SILLocation down.
  unsigned ExtraStorageData = 0;

  enum {
    LocationKindBits = 3,
    LocationKindMask = 7,

    StorageKindBits = 2,
    StorageKindMask = (1 << 3) | (1 << 4),
    SpecialFlagsMask = ~ (LocationKindMask | StorageKindMask),

    /// Used to mark this instruction as part of auto-generated
    /// code block.
    AutoGeneratedBit = 5,

    /// Used to redefine the default source location used to
    /// represent this SILLocation. For example, when the host instruction
    /// is known to correspond to the beginning or the end of the source
    /// range of the ASTNode.
    PointsToStartBit = 6,
    PointsToEndBit = 7,

    /// Used to notify that this instruction belongs to the top-
    /// level (module) scope.
    ///
    /// FIXME: If Module becomes a Decl, this could be removed.
    IsInTopLevel = 8,

    /// Marks this instruction as belonging to the function prologue.
    IsInPrologue = 9
  };

  template <typename T>
  T *getNodeAs(ASTNodeTy Node) const {
    using base = typename base_type<T>::type*;
    return dyn_cast_or_null<T>(Node.dyn_cast<base>());
  }

  template <typename T>
  bool isNode(ASTNodeTy Node) const {
    assert(isASTNode());
    if (Loc.ASTNode.Primary.is<typename base_type<T>::type*>())
      return isa<T>(Node.get<typename base_type<T>::type*>());
    return false;
  }

  template <typename T>
  T *castNodeTo(ASTNodeTy Node) const {
    return cast<T>(Node.get<typename base_type<T>::type*>());
  }

  /// \defgroup SILLocation constructors.
  /// @{

  /// This constructor is used to support getAs operation.
  SILLocation() { assert(Loc.DebugInfoLoc.Line == 0); }
  SILLocation(LocationKind K, unsigned Flags = 0) : KindData(K | Flags) {
    assert(Loc.DebugInfoLoc.Line == 0);
  }

  SILLocation(Stmt *S, LocationKind K, unsigned Flags = 0)
      : Loc(S), KindData(K | Flags) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }

  SILLocation(Expr *E, LocationKind K, unsigned Flags = 0)
      : Loc(E), KindData(K | Flags) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }

  SILLocation(Decl *D, LocationKind K, unsigned Flags = 0)
      : Loc(D), KindData(K | Flags) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }

  SILLocation(Pattern *P, LocationKind K, unsigned Flags = 0)
      : Loc(P), KindData(K | Flags) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }

  SILLocation(SourceLoc L, LocationKind K, unsigned Flags = 0)
      : Loc(L), KindData(K | Flags) {
    setStorageKind(SILFileKind);
    assert(isSILFile());
  }

  SILLocation(DebugLoc L, LocationKind K, unsigned Flags = 0)
      : KindData(K | Flags) {
    setDebugInfoLoc(L);
  }
  /// @}

private:
  friend class ImplicitReturnLocation;
  friend class MandatoryInlinedLocation;
  friend class InlinedLocation;
  friend class CleanupLocation;

  void setLocationKind(LocationKind K) { KindData |= (K & LocationKindMask); }
  // SWIFT_ENABLE_TENSORFLOW
  // TODO: Assess if this API can be unified with the one above.
  void setAndOverwriteLocationKind(LocationKind K) {
    KindData = (K & LocationKindMask);
  }
  void setStorageKind(StorageKind K) { KindData |= (K & StorageKindMask); }
  unsigned getSpecialFlags() const { return KindData & SpecialFlagsMask; }
  void setSpecialFlags(unsigned Flags) {
    KindData |= (Flags & SpecialFlagsMask);
  }

  SourceLoc getSourceLoc(ASTNodeTy N) const;
  SourceLoc getStartSourceLoc(ASTNodeTy N) const;
  SourceLoc getEndSourceLoc(ASTNodeTy N) const;

public:

  /// When an ASTNode gets implicitly converted into a SILLocation we
  /// construct a RegularLocation. Since RegularLocations represent the majority
  /// of locations, this greatly simplifies the user code.
  SILLocation(Stmt *S) : Loc(S), KindData(RegularKind) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }
  SILLocation(Expr *E) : Loc(E), KindData(RegularKind) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }
  SILLocation(Decl *D) : Loc(D), KindData(RegularKind) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }
  SILLocation(Pattern *P) : Loc(P), KindData(RegularKind) {
    setStorageKind(ASTNodeKind);
    assert(isASTNode());
  }

  static SILLocation invalid() { return SILLocation(); }

  /// Check if the location wraps an AST node or a valid SIL file
  /// location.
  ///
  /// Artificial locations and the top-level module locations will be null.
  bool isNull() const {
    switch (getStorageKind()) {
    case ASTNodeKind:   return Loc.ASTNode.Primary.isNull();
    case DebugInfoKind: return ExtraStorageData == 0;
    case SILFileKind:   return Loc.SILFileLoc.isInvalid();
    default:            return true;
    }
  }
  explicit operator bool() const { return !isNull(); }

  /// Return whether this location is backed by an AST node.
  bool isASTNode() const { return getStorageKind() == ASTNodeKind; }

  /// Return whether this location came from a SIL file.
  bool isSILFile() const { return getStorageKind() == SILFileKind; }

  /// Return whether this location came from a textual SIL file.
  bool isDebugInfoLoc() const { return getStorageKind() == DebugInfoKind; }

  /// Marks the location as coming from auto-generated body.
  void markAutoGenerated() { KindData |= (1 << AutoGeneratedBit); }

  /// Returns true if the location represents an artificially generated
  /// body, such as thunks or default destructors.
  ///
  /// These locations should not be included in the debug line table.
  /// These might also need special handling by the debugger since they might
  /// contain calls, which the debugger could be able to step into.
  bool isAutoGenerated() const { return KindData & (1 << AutoGeneratedBit); }

  /// Returns true if the line number of this location is zero.
  bool isLineZero(const SourceManager &SM) const {
    return decodeDebugLoc(SM).Line == 0;
  }

  /// Changes the default source location position to point to start of
  /// the AST node.
  void pointToStart() { KindData |= (1 << PointsToStartBit); }

  /// Changes the default source location position to point to the end of
  /// the AST node.
  void pointToEnd() { KindData |= (1 << PointsToEndBit); }

  /// Mark this location as the location corresponding to the top-level
  /// (module-level) code.
  void markAsInTopLevel() { KindData |= (1 << IsInTopLevel); }

  /// Check is this location is associated with the top level/module.
  bool isInTopLevel() const { return KindData & (1 << IsInTopLevel); }

  /// Mark this location as being part of the function
  /// prologue, which means that it deals with setting up the stack
  /// frame. The first breakpoint location in a function is at the end
  /// of the prologue.
  void markAsPrologue() { KindData |= (1 << IsInPrologue); }

  /// Check is this location is part of a function's implicit prologue.
  bool isInPrologue() const { return KindData & (1 << IsInPrologue); }

  /// Add an ASTNode to use as the location for debugging
  /// purposes if this location is different from the location used
  /// for diagnostics.
  template <typename T>
  void setDebugLoc(T *ASTNodeForDebugging) {
    assert(!hasDebugLoc() && "DebugLoc already present");
    assert(isASTNode() && "not an AST location");
    Loc.ASTNode.ForDebugger = ASTNodeForDebugging;
  }
  bool hasDebugLoc() const {
    return isASTNode() && !Loc.ASTNode.ForDebugger.isNull();
  }

  /// Populate this empty SILLocation with a DebugLoc.
  void setDebugInfoLoc(DebugLoc L) {
    ExtraStorageData = L.Filename.size();
    assert(ExtraStorageData == L.Filename.size() &&
           "file name is longer than 32 bits");
    Loc = L;
    setStorageKind(DebugInfoKind);
  }

  /// Check if the corresponding source code location definitely points
  ///  to the start of the AST node.
  bool alwaysPointsToStart() const { return KindData & (1 << PointsToStartBit);}

  /// Check if the corresponding source code location definitely points
  ///  to the end of the AST node.
  bool alwaysPointsToEnd() const { return KindData & (1 << PointsToEndBit); }

  LocationKind getKind() const {
    return LocationKind(KindData & LocationKindMask);
  }
  StorageKind getStorageKind() const {
    return StorageKind(KindData & StorageKindMask);
  }

  template <typename T>
  bool is() const {
    return T::isKind(*this);
  }

  template <typename T>
  T castTo() const {
    assert(T::isKind(*this));
    T t;
    SILLocation& tr = t;
    tr = *this;
    return t;
  }

  template <typename T>
  Optional<T> getAs() const {
    if (!T::isKind(*this))
      return Optional<T>();
    T t;
    SILLocation& tr = t;
    tr = *this;
    return t;
  }

  /// If the current value is of the specified AST unit type T,
  /// return it, otherwise return null.
  template <typename T> T *getAsASTNode() const {
    return isASTNode() ? getNodeAs<T>(Loc.ASTNode.Primary) : nullptr;
  }

  /// Returns true if the Location currently points to the AST node
  /// matching type T.
  template <typename T> bool isASTNode() const {
    return isASTNode() && isNode<T>(Loc.ASTNode.Primary);
  }

  /// Returns the primary value as the specified AST node type. If the
  /// specified type is incorrect, asserts.
  template <typename T> T *castToASTNode() const {
    assert(isASTNode());
    return castNodeTo<T>(Loc.ASTNode.Primary);
  }

  /// If the DebugLoc is of the specified AST unit type T,
  /// return it, otherwise return null.
  template <typename T> T *getDebugLocAsASTNode() const {
    assert(hasDebugLoc() && "no debug location");
    return getNodeAs<T>(Loc.ASTNode.ForDebugger);
  }

  /// Return the location as a DeclContext or null.
  DeclContext *getAsDeclContext() const;

  /// Convert a specialized location kind into a regular location.
  SILLocation getAsRegularLocation() {
    SILLocation RegularLoc = *this;
    RegularLoc.setLocationKind(RegularKind);
    return RegularLoc;
  }

  // SWIFT_ENABLE_TENSORFLOW
  /// Convert a specialized location kind into a regular location, by completely
  /// overwriting the existing location kind in `RegularLoc`. In contrast, the
  /// above function does a bitwise OR on the existing location kind and
  /// RegularKind.
  // TODO: Assess if these two APIs can be unified.
  SILLocation getAsRegularLocationWithOverwrite() {
    SILLocation RegularLoc = *this;
    RegularLoc.setAndOverwriteLocationKind(RegularKind);
    return RegularLoc;
  }

  SourceLoc getDebugSourceLoc() const;
  SourceLoc getSourceLoc() const;
  SourceLoc getStartSourceLoc() const;
  SourceLoc getEndSourceLoc() const;
  SourceRange getSourceRange() const {
    return {getStartSourceLoc(), getEndSourceLoc()};
  }
  DebugLoc getDebugInfoLoc() const {
    assert(isDebugInfoLoc());
    return DebugLoc(Loc.DebugInfoLoc.Line, Loc.DebugInfoLoc.Column,
                    StringRef(Loc.DebugInfoLoc.FilenameData, ExtraStorageData));
  }

  /// Fingerprint a DebugLoc for use in a DenseMap.
  using DebugLocKey = std::pair<std::pair<unsigned, unsigned>, StringRef>;
  struct DebugLocHash : public DebugLocKey {
    DebugLocHash(DebugLoc L) : DebugLocKey({{L.Line, L.Column}, L.Filename}) {}
  };

  /// Extract the line, column, and filename.
  static DebugLoc decode(SourceLoc Loc, const SourceManager &SM);

  /// Return the decoded debug location.
  LLVM_NODISCARD DebugLoc decodeDebugLoc(const SourceManager &SM) const {
    return isDebugInfoLoc() ? getDebugInfoLoc()
                            : decode(getDebugSourceLoc(), SM);
  }

  /// Compiler-generated locations may be applied to instructions without any
  /// clear correspondence to an AST node in an otherwise normal function.
  static DebugLoc getCompilerGeneratedDebugLoc() {
    return {0, 0, "<compiler-generated>"};
  }
  
  /// Pretty-print the value.
  void dump(const SourceManager &SM) const;
  void print(raw_ostream &OS, const SourceManager &SM) const;

  /// Returns an opaque pointer value for the debug location that may
  /// be used to unique debug locations.
  const void *getOpaquePointerValue() const {
    if (isSILFile())
      return Loc.SILFileLoc.getOpaquePointerValue();
    if (isASTNode())
      return Loc.ASTNode.Primary.getOpaqueValue();
    else
      return 0;
  }
  unsigned getOpaqueKind() const { return KindData; }

  inline bool operator==(const SILLocation& R) const {
    return KindData == R.KindData &&
           Loc.ASTNode.Primary.getOpaqueValue() ==
               R.Loc.ASTNode.Primary.getOpaqueValue() &&
           Loc.ASTNode.ForDebugger.getOpaqueValue() ==
               R.Loc.ASTNode.ForDebugger.getOpaqueValue();
  }

  inline bool operator!=(const SILLocation &R) const { return !(*this == R); }
};

/// Allowed on any instruction.
class RegularLocation : public SILLocation {
public:
  RegularLocation(Stmt *S) : SILLocation(S, RegularKind) {}
  RegularLocation(Expr *E) : SILLocation(E, RegularKind) {}
  RegularLocation(Decl *D) : SILLocation(D, RegularKind) {}
  RegularLocation(Pattern *P) : SILLocation(P, RegularKind) {}
  RegularLocation(SourceLoc L) : SILLocation(L, RegularKind) {}
  RegularLocation(DebugLoc L) : SILLocation(L, RegularKind) {}

  /// Returns a location representing the module.
  static RegularLocation getModuleLocation() {
    RegularLocation Loc;
    Loc.markAsInTopLevel();
    return Loc;
  }

  /// If the current value is of the specified AST unit type T,
  /// return it, otherwise return null.
  template <typename T> T *getAs() const { return getNodeAs<T>(Loc.ASTNode); }

  /// Returns true if the Location currently points to the AST node
  /// matching type T.
  template <typename T> bool is() const { return isNode<T>(Loc.ASTNode); }

  /// Returns the primary value as the specified AST node type. If the
  /// specified type is incorrect, asserts.
  template <typename T> T *castTo() const { return castNodeTo<T>(Loc.ASTNode); }

  /// Compiler-generated locations may be applied to instructions without any
  /// clear correspondence to an AST node in an otherwise normal function.
  /// The auto-generated bit also turns off certain diagnostics passes such.
  static RegularLocation getAutoGeneratedLocation() {
    RegularLocation AL(getCompilerGeneratedDebugLoc());
    AL.markAutoGenerated();
    return AL;
  }

  /// Returns a location that is compiler-generated, but with a hint as to where
  /// it may have been generated from. These locations will have an artificial
  /// line location of zero in DWARF, but in CodeView we want to use the given
  /// line since line zero does not represent an artificial line in CodeView.
  template <typename InputLocTy>
  static RegularLocation getAutoGeneratedLocation(InputLocTy L) {
    RegularLocation AL(L);
    AL.markAutoGenerated();
    return AL;
  }

private:
  RegularLocation() : SILLocation(RegularKind) {}

  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == RegularKind;
  }
};

/// Used to represent a return instruction in user code.
///
/// Allowed on an BranchInst, ReturnInst.
class ReturnLocation : public SILLocation {
public:
  ReturnLocation(ReturnStmt *RS);

  /// Construct the return location for a constructor or a destructor.
  ReturnLocation(BraceStmt *BS);

  ReturnStmt *get();

private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == ReturnKind;
  }
};

/// Used on the instruction that was generated to represent an implicit
/// return from a function.
///
/// Allowed on an BranchInst, ReturnInst.
class ImplicitReturnLocation : public SILLocation {
public:

  ImplicitReturnLocation(AbstractClosureExpr *E);

  ImplicitReturnLocation(ReturnStmt *S);

  ImplicitReturnLocation(AbstractFunctionDecl *AFD);

  /// Construct from a RegularLocation; preserve all special bits.
  ///
  /// Note, this can construct an implicit return for an arbitrary expression
  /// (specifically, in case of auto-generated bodies).
  static SILLocation getImplicitReturnLoc(SILLocation L);

  AbstractClosureExpr *get();

private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == ImplicitReturnKind;
  }
  ImplicitReturnLocation() : SILLocation(ImplicitReturnKind) {}
};

/// Marks instructions that correspond to inlined function body and
/// setup code. This location should not be used for inlined transparent
/// bodies, see MandatoryInlinedLocation.
///
/// This location wraps the call site ASTNode.
///
/// Allowed on any instruction except for ReturnInst.
class InlinedLocation : public SILLocation {
public:
  InlinedLocation(Expr *CallSite) : SILLocation(CallSite, InlinedKind) {}
  InlinedLocation(Stmt *S) : SILLocation(S, InlinedKind) {}
  InlinedLocation(Pattern *P) : SILLocation(P, InlinedKind) {}
  InlinedLocation(Decl *D) : SILLocation(D, InlinedKind) {}

  /// Constructs an inlined location when the call site is represented by a
  /// SILFile location.
  InlinedLocation(SourceLoc L) : SILLocation(InlinedKind) {
    setStorageKind(SILFileKind);
    Loc.SILFileLoc = L;
  }

  static InlinedLocation getInlinedLocation(SILLocation L);

private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == InlinedKind;
  }
  InlinedLocation() : SILLocation(InlinedKind) {}

  InlinedLocation(Expr *E, unsigned F) : SILLocation(E, InlinedKind, F) {}
  InlinedLocation(Stmt *S, unsigned F) : SILLocation(S, InlinedKind, F) {}
  InlinedLocation(Pattern *P, unsigned F) : SILLocation(P, InlinedKind, F) {}
  InlinedLocation(Decl *D, unsigned F) : SILLocation(D, InlinedKind, F) {}
  InlinedLocation(SourceLoc L, unsigned F) : SILLocation(L, InlinedKind, F) {}

  static InlinedLocation getModuleLocation(unsigned Flags) {
    auto L = InlinedLocation();
    L.setSpecialFlags(Flags);
    return L;
  }

};

/// Marks instructions that correspond to inlined function body and
/// setup code for transparent functions, inlined as part of mandatory inlining
/// pass.
///
/// This location wraps the call site ASTNode.
///
/// Allowed on any instruction except for ReturnInst.
class MandatoryInlinedLocation : public SILLocation {
public:
  MandatoryInlinedLocation(Expr *CallSite) :
    SILLocation(CallSite, MandatoryInlinedKind) {}
  MandatoryInlinedLocation(Stmt *S) : SILLocation(S, MandatoryInlinedKind) {}
  MandatoryInlinedLocation(Pattern *P) : SILLocation(P, MandatoryInlinedKind) {}
  MandatoryInlinedLocation(Decl *D) : SILLocation(D, MandatoryInlinedKind) {}

  /// Constructs an inlined location when the call site is represented by a
  /// SILFile location.
  MandatoryInlinedLocation(SourceLoc L)
      : SILLocation(L, MandatoryInlinedKind) {}

  static MandatoryInlinedLocation getMandatoryInlinedLocation(SILLocation L);
  static MandatoryInlinedLocation getAutoGeneratedLocation();

  static MandatoryInlinedLocation getModuleLocation(unsigned Flags) {
    auto L = MandatoryInlinedLocation();
    L.setSpecialFlags(Flags);
    return L;
  }
  
private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == MandatoryInlinedKind;
  }
  MandatoryInlinedLocation() : SILLocation(MandatoryInlinedKind) {}
  MandatoryInlinedLocation(Expr *E, unsigned F)
      : SILLocation(E, MandatoryInlinedKind, F) {}
  MandatoryInlinedLocation(Stmt *S, unsigned F)
      : SILLocation(S, MandatoryInlinedKind, F) {}
  MandatoryInlinedLocation(Pattern *P, unsigned F)
      : SILLocation(P, MandatoryInlinedKind, F) {}
  MandatoryInlinedLocation(Decl *D, unsigned F)
      : SILLocation(D, MandatoryInlinedKind, F) {}
  MandatoryInlinedLocation(SourceLoc L, unsigned F)
      : SILLocation(L, MandatoryInlinedKind, F) {}
  MandatoryInlinedLocation(DebugLoc L, unsigned F)
      : SILLocation(L, MandatoryInlinedKind, F) {}
};

/// Used on the instruction performing auto-generated cleanup such as
/// deallocs, destructor calls.
///
/// The cleanups are performed after completing the evaluation of the AST Node
/// wrapped inside the SILLocation. This location wraps the statement
/// representing the enclosing scope, for example, FuncDecl, ParenExpr. The
/// scope's end location points to the SourceLoc that shows when the operation
/// is performed at runtime.
///
/// Allowed on any instruction except for ReturnInst.
/// Locations of an inlined destructor should also be represented by this.
class CleanupLocation : public SILLocation {
public:
  CleanupLocation(Expr *E) : SILLocation(E, CleanupKind) {}
  CleanupLocation(Stmt *S) : SILLocation(S, CleanupKind) {}
  CleanupLocation(Pattern *P) : SILLocation(P, CleanupKind) {}
  CleanupLocation(Decl *D) : SILLocation(D, CleanupKind) {}

  static CleanupLocation get(SILLocation L);

  /// Returns a location representing a cleanup on the module level.
  static CleanupLocation getModuleCleanupLocation() {
    CleanupLocation Loc;
    Loc.markAsInTopLevel();
    return Loc;
  }

private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return L.getKind() == CleanupKind;
  }
  CleanupLocation() : SILLocation(CleanupKind) {}

  CleanupLocation(Expr *E, unsigned F) : SILLocation(E, CleanupKind, F) {}
  CleanupLocation(Stmt *S, unsigned F) : SILLocation(S, CleanupKind, F) {}
  CleanupLocation(Pattern *P, unsigned F) : SILLocation(P, CleanupKind, F) {}
  CleanupLocation(Decl *D, unsigned F) : SILLocation(D, CleanupKind, F) {}
};

/// Used to represent an unreachable location that was
/// auto-generated and has no correspondence to user code. It should
/// not be used in diagnostics or for debugging.
///
/// Differentiates an unreachable instruction, which is generated by
/// DCE, from an unreachable instruction in user code (output of SILGen).
/// Allowed on an unreachable instruction.
class ArtificialUnreachableLocation : public SILLocation {
public:
  ArtificialUnreachableLocation() : SILLocation(ArtificialUnreachableKind) {}
private:
  friend class SILLocation;
  static bool isKind(const SILLocation& L) {
    return (L.getKind() == ArtificialUnreachableKind);
  }
};

class SILDebugScope;

/// A SILLocation paired with a SILDebugScope.
class SILDebugLocation {
  const SILDebugScope *debugScope;
  SILLocation location;

public:
  SILDebugLocation()
      : debugScope(nullptr),
        location(RegularLocation::getAutoGeneratedLocation()) {}
  SILDebugLocation(SILLocation location, const SILDebugScope *debugScope)
      : debugScope(debugScope), location(location) {}
  SILLocation getLocation() const { return location; }
  const SILDebugScope *getScope() const { return debugScope; }
  operator bool() const { return bool(location) && debugScope; }
};

} // end swift namespace


#endif
