//===--- SILLocation.cpp - Location information for SIL nodes -------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://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; return getSourceLoc(Loc.ASTNode.Primary); } SourceLoc SILLocation::getSourceLoc(ASTNodeTy N) const { if (N.isNull()) return SourceLoc(); if (alwaysPointsToStart() || alwaysPointsToEnd() || is() || is()) return getEndSourceLoc(N); // Use the start location for the ReturnKind. if (is()) return getStartSourceLoc(N); if (auto *decl = N.dyn_cast()) return decl->getLoc(); if (auto *expr = N.dyn_cast()) return expr->getLoc(); if (auto *stmt = N.dyn_cast()) return stmt->getStartLoc(); if (auto *patt = N.dyn_cast()) 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()) { if (isa(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(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()) return decl->getStartLoc(); if (auto *expr = N.dyn_cast()) return expr->getStartLoc(); if (auto *stmt = N.dyn_cast()) return stmt->getStartLoc(); if (auto *patt = N.dyn_cast()) 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()) return decl->getEndLoc(); if (auto expr = N.dyn_cast()) return expr->getEndLoc(); if (auto stmt = N.dyn_cast()) return stmt->getEndLoc(); if (auto patt = N.dyn_cast()) 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()) llvm::errs() << Decl::getKindName(D->getKind()) << "Decl @ "; if (auto E = getAsASTNode()) llvm::errs() << Expr::getKindName(E->getKind()) << "Expr @ "; if (auto S = getAsASTNode()) llvm::errs() << Stmt::getKindName(S->getKind()) << "Stmt @ "; if (auto P = getAsASTNode()) 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 << ""; getSourceLoc().print(OS, SM); } InlinedLocation InlinedLocation::getInlinedLocation(SILLocation L) { if (Expr *E = L.getAsASTNode()) return InlinedLocation(E, L.getSpecialFlags()); if (Stmt *S = L.getAsASTNode()) return InlinedLocation(S, L.getSpecialFlags()); if (Pattern *P = L.getAsASTNode()) return InlinedLocation(P, L.getSpecialFlags()); if (Decl *D = L.getAsASTNode()) 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()) return MandatoryInlinedLocation(E, L.getSpecialFlags()); if (Stmt *S = L.getAsASTNode()) return MandatoryInlinedLocation(S, L.getSpecialFlags()); if (Pattern *P = L.getAsASTNode()) return MandatoryInlinedLocation(P, L.getSpecialFlags()); if (Decl *D = L.getAsASTNode()) 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()) return CleanupLocation(E, L.getSpecialFlags()); if (Stmt *S = L.getAsASTNode()) return CleanupLocation(S, L.getSpecialFlags()); if (Pattern *P = L.getAsASTNode()) return CleanupLocation(P, L.getSpecialFlags()); if (Decl *D = L.getAsASTNode()) 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."); }