diff --git a/SwiftCompilerSources/Sources/SIL/Location.swift b/SwiftCompilerSources/Sources/SIL/Location.swift index d3b2e62320e..bc6e72058fb 100644 --- a/SwiftCompilerSources/Sources/SIL/Location.swift +++ b/SwiftCompilerSources/Sources/SIL/Location.swift @@ -12,11 +12,24 @@ import SILBridging -public struct Location { +public struct Location: Equatable, CustomStringConvertible { let bridged: swift.SILDebugLocation - + + public var description: String { + let stdString = SILLocation_debugDescription(bridged) + return String(_cxxString: stdString) + } + /// Keeps the debug scope but marks it as auto-generated. public var autoGenerated: Location { Location(bridged: SILLocation_getAutogeneratedLocation(bridged)) } + + public static func ==(lhs: Location, rhs: Location) -> Bool { + SILLocation_equal(lhs.bridged, rhs.bridged) + } + + public func hasSameSourceLocation(as other: Location) -> Bool { + SILLocation_hasSameSourceLocation(bridged, other.bridged) + } } diff --git a/include/swift/SIL/SILBridging.h b/include/swift/SIL/SILBridging.h index 239360e0a65..b46fb36a081 100644 --- a/include/swift/SIL/SILBridging.h +++ b/include/swift/SIL/SILBridging.h @@ -337,8 +337,11 @@ llvm::StringRef SILType_getNominalFieldName(BridgedType type, SwiftInt index); SwiftInt SILType_getCaseIdxOfEnumType(BridgedType type, llvm::StringRef caseName); +std::string SILLocation_debugDescription(swift::SILDebugLocation loc); swift::SILDebugLocation SILLocation_getAutogeneratedLocation(swift::SILDebugLocation loc); +bool SILLocation_equal(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs); +bool SILLocation_hasSameSourceLocation(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs); BridgedBasicBlock SILArgument_getParent(BridgedArgument argument); BridgedArgumentConvention SILArgument_getConvention(BridgedArgument argument); diff --git a/include/swift/SIL/SILLocation.h b/include/swift/SIL/SILLocation.h index 8c9557b7780..603aad409b0 100644 --- a/include/swift/SIL/SILLocation.h +++ b/include/swift/SIL/SILLocation.h @@ -427,6 +427,7 @@ public: /// Pretty-print the value. void dump() const; void print(raw_ostream &OS, const SourceManager &SM) const; + void print(raw_ostream &OS) const; inline bool operator==(const SILLocation& R) const { return kindAndFlags.packedKindAndFlags == R.kindAndFlags.packedKindAndFlags @@ -435,6 +436,15 @@ public: inline bool operator!=(const SILLocation &R) const { return !(*this == R); } + bool hasSameSourceLocation(const SILLocation &rhs) { + if (*this == rhs) + return true; + if (isASTNode() && rhs.isASTNode()) { + return getSourceLoc(getPrimaryASTNode()) == rhs.getSourceLoc(rhs.getPrimaryASTNode()); + } + return false; + } + friend llvm::hash_code hash_value(const SILLocation &); }; diff --git a/lib/SIL/IR/SILLocation.cpp b/lib/SIL/IR/SILLocation.cpp index 93abd1fd841..976116db280 100644 --- a/lib/SIL/IR/SILLocation.cpp +++ b/lib/SIL/IR/SILLocation.cpp @@ -151,17 +151,17 @@ SILLocation::FilenameAndLocation *SILLocation::getCompilerGeneratedLoc() { return &compilerGenerated; } -static void dumpSourceLoc(SourceLoc loc) { +static void printSourceLoc(SourceLoc loc, raw_ostream &OS) { if (!loc.isValid()) { - llvm::dbgs() << ""; + OS << ""; return; } const char *srcPtr = (const char *)loc.getOpaquePointerValue(); unsigned len = strnlen(srcPtr, 20); if (len < 20) { - llvm::dbgs() << '"' << StringRef(srcPtr, len) << '"'; + OS << '"' << StringRef(srcPtr, len) << '"'; } else { - llvm::dbgs() << '"' << StringRef(srcPtr, 20) << "[...]\""; + OS << '"' << StringRef(srcPtr, 20) << "[...]\""; } } @@ -182,7 +182,7 @@ void SILLocation::dump() const { if (isFilenameAndLocation()) { getFilenameAndLocation()->dump(); } else { - dumpSourceLoc(getSourceLoc()); + printSourceLoc(getSourceLoc(), llvm::dbgs()); } if (isAutoGenerated()) llvm::dbgs() << ":auto"; @@ -191,7 +191,7 @@ void SILLocation::dump() const { if (isSILFile()) llvm::dbgs() << ":sil"; if (hasASTNodeForDebugging()) { llvm::dbgs() << ":debug["; - dumpSourceLoc(getSourceLocForDebugging()); + printSourceLoc(getSourceLocForDebugging(), llvm::dbgs()); llvm::dbgs() << "]\n"; } } @@ -206,6 +206,18 @@ void SILLocation::print(raw_ostream &OS, const SourceManager &SM) const { } } +void SILLocation::print(raw_ostream &OS) const { + if (isNull()) { + OS << ""; + } else if (isFilenameAndLocation()) { + getFilenameAndLocation()->print(OS); + } else if (DeclContext *dc = getAsDeclContext()){ + getSourceLoc().print(OS, dc->getASTContext().SourceMgr); + } else { + printSourceLoc(getSourceLoc(), OS); + } +} + RegularLocation::RegularLocation(Stmt *S, Pattern *P, SILModule &Module) : SILLocation(new (Module) ExtendedASTNodeLoc(S, P), RegularKind) {} diff --git a/lib/SIL/Utils/SILBridging.cpp b/lib/SIL/Utils/SILBridging.cpp index a958e9394ee..5bdc2c61057 100644 --- a/lib/SIL/Utils/SILBridging.cpp +++ b/lib/SIL/Utils/SILBridging.cpp @@ -623,12 +623,39 @@ SwiftInt SILType_getCaseIdxOfEnumType(BridgedType type, // SILLocation //===----------------------------------------------------------------------===// +std::string SILLocation_debugDescription(swift::SILDebugLocation dloc) { + std::string str; + llvm::raw_string_ostream os(str); + SILLocation loc = dloc.getLocation(); + loc.print(os); +#ifndef NDEBUG + if (const SILDebugScope *scope = dloc.getScope()) { + if (DeclContext *dc = loc.getAsDeclContext()) { + os << ", scope="; + scope->print(dc->getASTContext().SourceMgr, os, /*indent*/ 2); + } else { + os << ", scope=?"; + } + } +#endif + return str; +} + SILDebugLocation SILLocation_getAutogeneratedLocation(SILDebugLocation loc) { SILDebugLocation autoGenLoc(RegularLocation::getAutoGeneratedLocation(), loc.getScope()); return autoGenLoc; } +bool SILLocation_equal(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs) { + return lhs.getLocation() == rhs.getLocation() && lhs.getScope() == rhs.getScope(); +} + +bool SILLocation_hasSameSourceLocation(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs) { + return lhs.getLocation().hasSameSourceLocation(rhs.getLocation()) && + lhs.getScope() == rhs.getScope(); +} + //===----------------------------------------------------------------------===// // SILGlobalVariable //===----------------------------------------------------------------------===//