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
This commit is contained in:
Adrian Prantl
2021-10-20 17:49:33 -07:00
parent 22aa3c5dbe
commit b2109ab4db
2 changed files with 33 additions and 0 deletions

View File

@@ -30,6 +30,7 @@
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsCommon.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/Expr.h"
#include "swift/AST/ForeignErrorConvention.h"
#include "swift/AST/GenericEnvironment.h"
@@ -1031,6 +1032,16 @@ SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty,
Optional<SILDebugVariable> DbgVar;
if (auto *VD = loc.getAsASTNode<VarDecl>())
DbgVar = SILDebugVariable(VD->isLet(), 0);
// Recognize "catch let errorvar" bindings.
if (auto *DRE = loc.getAsASTNode<DeclRefExpr>())
if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
if (!isa<ParamDecl>(VD) && VD->isImplicit() &&
(VD->getType()->is<ProtocolType>() ||
VD->getType()->is<ProtocolCompositionType>()) &&
VD->getType()->getExistentialLayout().isErrorExistential()) {
DbgVar = SILDebugVariable(VD->isLet(), 0);
loc = SILLocation(VD);
}
auto alloc = B.createAllocStack(loc, ty, DbgVar, hasDynamicLifetime);
enterDeallocStackCleanup(alloc);
return alloc;

View File

@@ -0,0 +1,22 @@
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
enum MyError : Error {
case Yikes
}
func throwing() throws -> () {
throw MyError.Yikes
}
func use<T>(_ t: T) {}
public func foo() {
do {
try throwing()
}
catch let error {
// CHECK: call void @llvm.dbg.declare(metadata %swift.error** %{{.*}}, metadata ![[ERROR:[0-9]+]],
// CHECK: ![[ERROR]] = !DILocalVariable(name: "error"
use(error)
}
}
foo();