Skip to content

Commit b2109ab

Browse files
committed
Emit debug info for catch let errorvar error variables.
This implementation adds the debug info emission to SILGenFunction::emitTemporaryAllocation() which may not be the optimal place to do this. It may be better to change SILGen to unconditionally emit an alloc_stack instead of relying on a temporary alloca to be requested. rdar://75499821
1 parent 22aa3c5 commit b2109ab

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/CanTypeVisitor.h"
3131
#include "swift/AST/Decl.h"
3232
#include "swift/AST/DiagnosticsCommon.h"
33+
#include "swift/AST/ExistentialLayout.h"
3334
#include "swift/AST/Expr.h"
3435
#include "swift/AST/ForeignErrorConvention.h"
3536
#include "swift/AST/GenericEnvironment.h"
@@ -1031,6 +1032,16 @@ SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty,
10311032
Optional<SILDebugVariable> DbgVar;
10321033
if (auto *VD = loc.getAsASTNode<VarDecl>())
10331034
DbgVar = SILDebugVariable(VD->isLet(), 0);
1035+
// Recognize "catch let errorvar" bindings.
1036+
if (auto *DRE = loc.getAsASTNode<DeclRefExpr>())
1037+
if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
1038+
if (!isa<ParamDecl>(VD) && VD->isImplicit() &&
1039+
(VD->getType()->is<ProtocolType>() ||
1040+
VD->getType()->is<ProtocolCompositionType>()) &&
1041+
VD->getType()->getExistentialLayout().isErrorExistential()) {
1042+
DbgVar = SILDebugVariable(VD->isLet(), 0);
1043+
loc = SILLocation(VD);
1044+
}
10341045
auto alloc = B.createAllocStack(loc, ty, DbgVar, hasDynamicLifetime);
10351046
enterDeallocStackCleanup(alloc);
10361047
return alloc;

test/DebugInfo/catch_let.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
2+
enum MyError : Error {
3+
case Yikes
4+
}
5+
6+
func throwing() throws -> () {
7+
throw MyError.Yikes
8+
}
9+
10+
func use<T>(_ t: T) {}
11+
12+
public func foo() {
13+
do {
14+
try throwing()
15+
}
16+
catch let error {
17+
// CHECK: call void @llvm.dbg.declare(metadata %swift.error** %{{.*}}, metadata ![[ERROR:[0-9]+]],
18+
// CHECK: ![[ERROR]] = !DILocalVariable(name: "error"
19+
use(error)
20+
}
21+
}
22+
foo();

0 commit comments

Comments
 (0)