From e932580c8ea215c263e41084a4e12c759166a8c9 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 6 Feb 2020 17:33:47 -0800 Subject: [PATCH] Emit debug info for generic type aliases. Before comparing the potential sugared type for equality is needs to be mapped into the context to resolve generic type parameters to primary archetypes. --- lib/IRGen/DebugTypeInfo.cpp | 29 +++++++++++-------- lib/IRGen/IRGenSIL.cpp | 6 ++-- .../bound-generic-struct-extension.swift | 28 ++++++++++++++++++ test/DebugInfo/generic-typealias.swift | 19 ++++++++++++ 4 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 test/DebugInfo/bound-generic-struct-extension.swift create mode 100644 test/DebugInfo/generic-typealias.swift diff --git a/lib/IRGen/DebugTypeInfo.cpp b/lib/IRGen/DebugTypeInfo.cpp index 34fa19bd537f0..51e1868b76d66 100644 --- a/lib/IRGen/DebugTypeInfo.cpp +++ b/lib/IRGen/DebugTypeInfo.cpp @@ -60,20 +60,25 @@ DebugTypeInfo DebugTypeInfo::getFromTypeInfo(swift::Type Ty, DebugTypeInfo DebugTypeInfo::getLocalVariable(VarDecl *Decl, swift::Type Ty, const TypeInfo &Info) { - - auto DeclType = Decl->getInterfaceType(); - auto RealType = Ty; - - // DynamicSelfType is also sugar as far as debug info is concerned. - auto Sugared = DeclType; - if (auto DynSelfTy = DeclType->getAs()) - Sugared = DynSelfTy->getSelfType(); - // Prefer the original, potentially sugared version of the type if // the type hasn't been mucked with by an optimization pass. - auto *Type = Sugared->isEqual(RealType) ? DeclType.getPointer() - : RealType.getPointer(); - return getFromTypeInfo(Type, Info); + swift::Type DeclType = Decl->getInterfaceType(); + swift::Type RealType = Ty; + + swift::Type DebugType; + if (auto DynSelfTy = DeclType->getAs()) { + // DynamicSelfType is also sugar as far as debug info is concerned. + auto DesugaredSelf = DynSelfTy->getSelfType(); + DebugType = DesugaredSelf->isEqual(RealType) ? DynSelfTy : RealType; + } else { + // Map the sugared type into the context to resolve bound generics and + // generic type aliases. + DeclContext *DeclCtx = Decl->getDeclContext(); + swift::Type Sugared = + DeclCtx ? DeclCtx->mapTypeIntoContext(DeclType) : DeclType; + DebugType = Sugared->isEqual(RealType) ? Sugared : RealType; + } + return getFromTypeInfo(DebugType, Info); } DebugTypeInfo DebugTypeInfo::getMetadata(swift::Type Ty, llvm::Type *StorageTy, diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 7292f9e0160ca..81d885aaeac80 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -3660,7 +3660,7 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) { llvm::SmallVector Copy; emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), *VarInfo, IsAnonymous, Copy); - bindArchetypes(DbgTy.getType()); + bindArchetypes(RealTy); if (!IGM.DebugInfo) return; @@ -3691,7 +3691,7 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) { auto DbgTy = DebugTypeInfo::getLocalVariable( Decl, RealType, getTypeInfo(SILVal->getType())); - bindArchetypes(DbgTy.getType()); + bindArchetypes(RealType); if (!IGM.DebugInfo) return; @@ -3991,7 +3991,7 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i, auto RealType = SILTy.getASTType(); auto DbgTy = DebugTypeInfo::getLocalVariable(Decl, RealType, type); - bindArchetypes(DbgTy.getType()); + bindArchetypes(RealType); if (IGM.DebugInfo) emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, *VarInfo, Indirection); diff --git a/test/DebugInfo/bound-generic-struct-extension.swift b/test/DebugInfo/bound-generic-struct-extension.swift new file mode 100644 index 0000000000000..ec6e13aa235f2 --- /dev/null +++ b/test/DebugInfo/bound-generic-struct-extension.swift @@ -0,0 +1,28 @@ +// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s + +// Test that a bound generic type is fully resolved in the debug info. + +public protocol P {} + +public struct S : P { + var x: Int +} +// This is significant, it must be bound to S: main.BoundGeneric +// CHECK-DAG: ![[S:[0-9]+]] = !DICompositeType({{.*}}identifier: "$s4main12BoundGenericVyAA1SVGD") + +public extension BoundGeneric where T == S { + func f() { +// CHECK-DAG: !DILocalVariable(name: "self", arg: 1,{{.*}} line: [[@LINE-1]],{{.*}} type: ![[C_BGS:[0-9]+]], +// CHECK-DAG: ![[C_BGS]] = !DIDerivedType(tag: DW_TAG_const_type,{{.*}} baseType: ![[BGS:[0-9]+]]) +// CHECK-DAG: ![[BGS]] = !DICompositeType(tag: DW_TAG_structure_type,{{.*}} elements: ![[ELTS:[0-9]+]], +// CHECK-DAG: ![[ELTS]] = !{![[MEMBER:[0-9]+]]} +// CHECK-DAG: ![[MEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[S]], + } +} + +public struct BoundGeneric where T : P { + let x : T +} + +public let pat = BoundGeneric(x: S(x: 23)) +pat.f() diff --git a/test/DebugInfo/generic-typealias.swift b/test/DebugInfo/generic-typealias.swift new file mode 100644 index 0000000000000..3b4c4399e4008 --- /dev/null +++ b/test/DebugInfo/generic-typealias.swift @@ -0,0 +1,19 @@ +// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s + +// Test that a generic type alias is represented in the debug info. + +public struct S { + public typealias Alias = (T, T) + // CHECK: ![[T_T:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$sx_xtD" + public let member : Alias + public func f(t : Alias) -> Alias { return t } + // CHECK: !DILocalVariable(name: "t", arg: 1,{{.*}} line: [[@LINE-1]], + // CHECK-SAME: type: ![[C_ALIAS:[0-9]+]]) + // CHECK: ![[C_ALIAS]] = !DIDerivedType(tag: DW_TAG_const_type, + // CHECK-SAME: baseType: ![[ALIAS:[0-9]+]]) + // CHECK: ![[ALIAS]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$ + // CHECK-SAME: baseType: ![[T_T]]) + +} + +public let s = S(member: (4, 2))