Skip to content

Commit 80c8bf0

Browse files
Merge pull request #85655 from adrian-prantl/161134092
[Debug Info] Represent type alias existantials in debug info
2 parents a994527 + 45547be commit 80c8bf0

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "llvm/IR/Module.h"
7070
#include "llvm/Support/Casting.h"
7171
#include "llvm/Support/CommandLine.h"
72+
#include "llvm/Support/Compiler.h"
7273
#include "llvm/Support/Debug.h"
7374
#include "llvm/Support/FileSystem.h"
7475
#include "llvm/Support/MemoryBuffer.h"
@@ -1730,6 +1731,21 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17301731
llvm::dwarf::DW_LANG_Swift, nullptr);
17311732
}
17321733

1734+
/// Create struct with a single member, used for Swift types that do not yet
1735+
/// have specialized DIDerivedTypes.
1736+
llvm::DIType *createSingleMemberStruct(
1737+
llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
1738+
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1739+
StringRef MangledName, StringRef MemberName, llvm::DIType *MemberType) {
1740+
llvm::Metadata *Elements[] = {
1741+
DBuilder.createMemberType(Scope, MemberName, File, 0, SizeInBits,
1742+
AlignInBits, 0, Flags, MemberType)};
1743+
return DBuilder.createStructType(
1744+
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1745+
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
1746+
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName, nullptr, 0);
1747+
}
1748+
17331749
llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
17341750
unsigned SizeInBits, unsigned AlignInBits,
17351751
llvm::DINode::DIFlags Flags,
@@ -2062,18 +2078,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
20622078
SpecificationOf);
20632079
}
20642080

2065-
case TypeKind::Protocol: {
2066-
auto *ProtocolTy = BaseTy->castTo<ProtocolType>();
2067-
auto *Decl = ProtocolTy->getDecl();
2068-
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
2069-
auto L = getFileAndLocation(Decl);
2070-
unsigned FwdDeclLine = 0;
2071-
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
2072-
L.File, FwdDeclLine, SizeInBits, AlignInBits,
2073-
Flags, MangledName);
2081+
case TypeKind::Existential: {
2082+
auto *ExistentialTy = BaseTy->castTo<ExistentialType>();
2083+
Type ConstraintTy = ExistentialTy->getConstraintType();
2084+
TypeBase *TyPtr = ConstraintTy.getPointer();
2085+
if (!isa<ProtocolType>(TyPtr) && !isa<ProtocolCompositionType>(TyPtr) &&
2086+
!isa<ParameterizedProtocolType>(TyPtr)) {
2087+
// This could be an alias type, which we need to anchor in DWARF.
2088+
auto *Decl = DbgTy.getDecl();
2089+
auto L = getFileAndLocation(Decl);
2090+
unsigned FwdDeclLine = 0;
2091+
return createSingleMemberStruct(
2092+
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
2093+
SizeInBits, AlignInBits, Flags, MangledName, "$swift.constraint",
2094+
getOrCreateType(ConstraintTy));
2095+
}
2096+
// If the existential is just a protocol type it shares its mangled name
2097+
// with it, so we can just represent it directly as a protocol.
2098+
BaseTy = TyPtr;
20742099
}
2100+
LLVM_FALLTHROUGH;
20752101

2076-
case TypeKind::Existential:
2102+
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
2103+
case TypeKind::Protocol:
20772104
case TypeKind::ProtocolComposition:
20782105
case TypeKind::ParameterizedProtocol: {
20792106
auto *Decl = DbgTy.getDecl();

test/DebugInfo/Inputs/Alias.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
public protocol ProtocolFromModule {}
2+
public typealias AliasFromModule = ProtocolFromModule
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -emit-module-path %t/Alias.swiftmodule %S/Inputs/Alias.swift
2+
// RUN: %target-swift-frontend %s -emit-ir -parse-as-library -module-name a -I%t -g -o - | %FileCheck %s
3+
import Alias
4+
public final class C {
5+
public func use(a: AliasFromModule) {}
6+
}
7+
8+
let c = C()
9+
10+
11+
// CHECK-DAG: !DILocalVariable(name: "a", arg: 1, {{.*}}, type: ![[CONST_TY:[0-9]+]])
12+
// CHECK-DAG: ![[CONST_TY]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[EXIST_TY:[0-9]+]])
13+
// CHECK-DAG: ![[EXIST_TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "ProtocolFromModule", {{.*}}, elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, identifier: "$s5Alias0A10FromModuleaD")
14+
// CHECK-DAG: ![[ELTS]] = !{![[INNER:[0-9]+]]}
15+
// CHECK-DAG: ![[INNER]] = !DIDerivedType(tag: DW_TAG_member, name: "$swift.constraint", {{.*}}, baseType: ![[TYPEDEF:[0-9]+]]
16+
// CHECK-DAG: ![[TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s5Alias0A10FromModuleaD", {{.*}}, baseType: ![[PROTO_TY:[0-9]+]])
17+
// CHECK-DAG: ![[PROTO_TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "ProtocolFromModule", {{.*}}, identifier: "$s5Alias18ProtocolFromModule_pD")

0 commit comments

Comments
 (0)