//===--- SILLocation.cpp - Location information for SIL nodes -------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILLocation.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/Stmt.h"
#include "swift/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;


SourceLoc SILLocation::getSourceLoc() const {
  if (isSILFile())
    return Loc.SILFileLoc;

  // Don't crash if the location is a DebugLoc.
  // TODO: this is a workaround until rdar://problem/25225083 is implemented.
  if (isDebugInfoLoc())
    return SourceLoc();

  return getSourceLoc(Loc.ASTNode.Primary);
}

SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const {
  if (N.isNull())
    return SourceLoc();

  if (alwaysPointsToStart() ||
      alwaysPointsToEnd() ||
      is<CleanupLocation>() ||
      is<ImplicitReturnLocation>())
    return getEndSourceLoc(N);

  // Use the start location for the ReturnKind.
  if (is<ReturnLocation>())
    return getStartSourceLoc(N);

  if (auto *decl = N.dyn_cast<Decl*>())
    return decl->getLoc();
  if (auto *expr = N.dyn_cast<Expr*>())
    return expr->getLoc();
  if (auto *stmt = N.dyn_cast<Stmt*>())
    return stmt->getStartLoc();
  if (auto *patt = N.dyn_cast<Pattern*>())
    return patt->getStartLoc();
  llvm_unreachable("impossible SILLocation");
}

SourceLoc SILLocation::getDebugSourceLoc() const {
  assert(!isDebugInfoLoc());

  if (isSILFile())
    return Loc.SILFileLoc;

  if (isAutoGenerated())
    return SourceLoc();

  if (auto *expr = Loc.ASTNode.Primary.dyn_cast<Expr*>()) {
    if (isa<CallExpr>(expr))
      return expr->getEndLoc();
    // Code that has an autoclosure as location should not show up in
    // the line table (rdar://problem/14627460). Note also that the
    // closure function still has a valid DW_AT_decl_line.  Depending
    // on how we decide to resolve rdar://problem/14627460, we may
    // want to use the regular getLoc instead and rather use the
    // column info.
    if (isa<AutoClosureExpr>(expr))
      return SourceLoc();
  }

  if (Loc.ASTNode.ForDebugger)
    return getSourceLoc(Loc.ASTNode.ForDebugger);

  return getSourceLoc(Loc.ASTNode.Primary);
}

SourceLoc SILLocation::getStartSourceLoc() const {
  if (isAutoGenerated())
    return SourceLoc();
  if (isSILFile())
    return Loc.SILFileLoc;
  return getStartSourceLoc(Loc.ASTNode.Primary);
}

SourceLoc SILLocation::getStartSourceLoc(ASTNodeTy N) const {
  if (auto *decl = N.dyn_cast<Decl*>())
    return decl->getStartLoc();
  if (auto *expr = N.dyn_cast<Expr*>())
    return expr->getStartLoc();
  if (auto *stmt = N.dyn_cast<Stmt*>())
    return stmt->getStartLoc();
  if (auto *patt = N.dyn_cast<Pattern*>())
    return patt->getStartLoc();
  llvm_unreachable("impossible SILLocation");
}

SourceLoc SILLocation::getEndSourceLoc() const {
  if (isAutoGenerated())
    return SourceLoc();
  if (isSILFile())
    return Loc.SILFileLoc;
  return getEndSourceLoc(Loc.ASTNode.Primary);
}

SourceLoc SILLocation::getEndSourceLoc(ASTNodeTy N) const {
  if (auto decl = N.dyn_cast<Decl*>())
    return decl->getEndLoc();
  if (auto expr = N.dyn_cast<Expr*>())
    return expr->getEndLoc();
  if (auto stmt = N.dyn_cast<Stmt*>())
    return stmt->getEndLoc();
  if (auto patt = N.dyn_cast<Pattern*>())
    return patt->getEndLoc();
  llvm_unreachable("impossible SILLocation");
}

SILLocation::DebugLoc SILLocation::decode(SourceLoc Loc,
                                          const SourceManager &SM) {
  DebugLoc DL;
  if (Loc.isValid()) {
    DL.Filename = SM.getBufferIdentifierForLoc(Loc);
    std::tie(DL.Line, DL.Column) = SM.getLineAndColumn(Loc);
  }
  return DL;
}

void SILLocation::dump(const SourceManager &SM) const {
  if (auto D = getAsASTNode<Decl>())
    llvm::errs() << Decl::getKindName(D->getKind()) << "Decl @ ";
  if (auto E = getAsASTNode<Expr>())
    llvm::errs() << Expr::getKindName(E->getKind()) << "Expr @ ";
  if (auto S = getAsASTNode<Stmt>())
    llvm::errs() << Stmt::getKindName(S->getKind()) << "Stmt @ ";
  if (auto P = getAsASTNode<Pattern>())
    llvm::errs() << Pattern::getKindName(P->getKind()) << "Pattern @ ";

  print(llvm::errs(), SM);

  if (isAutoGenerated())     llvm::errs() << ":auto";
  if (alwaysPointsToStart()) llvm::errs() << ":start";
  if (alwaysPointsToEnd())   llvm::errs() << ":end";
  if (isInTopLevel())        llvm::errs() << ":toplevel";
  if (isInPrologue())        llvm::errs() << ":prologue";
  if (isSILFile())           llvm::errs() << ":sil";
  if (hasDebugLoc()) {
    llvm::errs() << ":debug[";
    getDebugSourceLoc().print(llvm::errs(), SM);
    llvm::errs() << "]\n";
  }
}

void SILLocation::print(raw_ostream &OS, const SourceManager &SM) const {
  if (isNull())
    OS << "<no loc>";
  getSourceLoc().print(OS, SM);
}

InlinedLocation InlinedLocation::getInlinedLocation(SILLocation L) {
  if (Expr *E = L.getAsASTNode<Expr>())
    return InlinedLocation(E, L.getSpecialFlags());
  if (Stmt *S = L.getAsASTNode<Stmt>())
    return InlinedLocation(S, L.getSpecialFlags());
  if (Pattern *P = L.getAsASTNode<Pattern>())
    return InlinedLocation(P, L.getSpecialFlags());
  if (Decl *D = L.getAsASTNode<Decl>())
    return InlinedLocation(D, L.getSpecialFlags());

  if (L.isSILFile())
    return InlinedLocation(L.Loc.SILFileLoc, L.getSpecialFlags());

  if (L.isInTopLevel())
    return InlinedLocation::getModuleLocation(L.getSpecialFlags());

  if (L.isAutoGenerated()) {
    InlinedLocation IL;
    IL.markAutoGenerated();
    return IL;
  }
  llvm_unreachable("Cannot construct Inlined loc from the given location.");
}

MandatoryInlinedLocation
MandatoryInlinedLocation::getMandatoryInlinedLocation(SILLocation L) {
  if (Expr *E = L.getAsASTNode<Expr>())
    return MandatoryInlinedLocation(E, L.getSpecialFlags());
  if (Stmt *S = L.getAsASTNode<Stmt>())
    return MandatoryInlinedLocation(S, L.getSpecialFlags());
  if (Pattern *P = L.getAsASTNode<Pattern>())
    return MandatoryInlinedLocation(P, L.getSpecialFlags());
  if (Decl *D = L.getAsASTNode<Decl>())
    return MandatoryInlinedLocation(D, L.getSpecialFlags());

  if (L.isSILFile())
    return MandatoryInlinedLocation(L.Loc.SILFileLoc, L.getSpecialFlags());

  if (L.isInTopLevel())
    return MandatoryInlinedLocation::getModuleLocation(L.getSpecialFlags());

  llvm_unreachable("Cannot construct Inlined loc from the given location.");
}

CleanupLocation CleanupLocation::get(SILLocation L) {
  if (Expr *E = L.getAsASTNode<Expr>())
    return CleanupLocation(E, L.getSpecialFlags());
  if (Stmt *S = L.getAsASTNode<Stmt>())
    return CleanupLocation(S, L.getSpecialFlags());
  if (Pattern *P = L.getAsASTNode<Pattern>())
    return CleanupLocation(P, L.getSpecialFlags());
  if (Decl *D = L.getAsASTNode<Decl>())
    return CleanupLocation(D, L.getSpecialFlags());
  if (L.isNull())
    return CleanupLocation();
  if (L.isSILFile())
    return CleanupLocation();
  llvm_unreachable("Cannot construct Cleanup loc from the "
                   "given location.");
}
