Skip to content

Commit b4d3059

Browse files
committed
Debug Info: Unique forward declarations generated for scopes and types.
This is mostly a cleanup and results slightly more efficient debug info. rdar://problem/25965038
1 parent e837d88 commit b4d3059

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,18 +545,21 @@ llvm::DIScope *IRGenDebugInfo::getOrCreateContext(DeclContext *DC) {
545545
return getOrCreateContext(DC->getParent());
546546
case DeclContextKind::GenericTypeDecl: {
547547
auto *TyDecl = cast<GenericTypeDecl>(DC);
548-
if (auto *DITy = getTypeOrNull(TyDecl->getDeclaredType().getPointer()))
548+
auto *Ty = TyDecl->getDeclaredType().getPointer();
549+
if (auto *DITy = getTypeOrNull(Ty))
549550
return DITy;
550551

551552
// Create a Forward-declared type.
552553
auto Loc = getDebugLoc(SM, TyDecl);
553554
auto File = getOrCreateFile(Loc.Filename);
554555
auto Line = Loc.Line;
555-
auto FwdDecl = DBuilder.createForwardDecl(
556+
auto FwdDecl = DBuilder.createReplaceableCompositeType(
556557
llvm::dwarf::DW_TAG_structure_type, TyDecl->getName().str(),
557558
getOrCreateContext(DC->getParent()), File, Line,
558559
llvm::dwarf::DW_LANG_Swift, 0, 0);
559-
560+
ReplaceMap.emplace_back(
561+
std::piecewise_construct, std::make_tuple(Ty),
562+
std::make_tuple(static_cast<llvm::Metadata *>(FwdDecl)));
560563
return FwdDecl;
561564
}
562565
}
@@ -1792,6 +1795,17 @@ llvm::DIType *IRGenDebugInfo::getOrCreateType(DebugTypeInfo DbgTy) {
17921795
void IRGenDebugInfo::finalize() {
17931796
assert(LocationStack.empty() && "Mismatch of pushLoc() and popLoc().");
17941797

1798+
// Finalize all replaceable forward declarations.
1799+
for (auto &Ty : ReplaceMap) {
1800+
llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(Ty.second));
1801+
llvm::Metadata *Replacement;
1802+
if (auto *FullType = getTypeOrNull(Ty.first))
1803+
Replacement = FullType;
1804+
else
1805+
Replacement = Ty.second;
1806+
DBuilder.replaceTemporary(std::move(FwdDecl),
1807+
cast<llvm::MDNode>(Replacement));
1808+
}
17951809
// Finalize the DIBuilder.
17961810
DBuilder.finalize();
17971811
}

lib/IRGen/IRGenDebugInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class IRGenDebugInfo {
7070
std::vector<std::pair<const SILDebugScope *, llvm::TrackingMDNodeRef>>
7171
LastInlineChain;
7272

73+
/// A list of replaceable fwddecls that need to be RAUWed at the end.
74+
std::vector<std::pair<TypeBase *, llvm::TrackingMDRef>> ReplaceMap;
75+
7376
llvm::BumpPtrAllocator DebugInfoNames;
7477
StringRef CWDName; /// The current working directory.
7578
llvm::DICompileUnit *TheCU = nullptr; /// The current compilation unit.

test/DebugInfo/parent-scope.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -g -emit-ir %s | FileCheck %s
2+
3+
public protocol P {
4+
associatedtype AT;
5+
}
6+
7+
// A generic declcontext cannot be shared, so we expect a
8+
// forward-declared type.
9+
// CHECK-GEN: ![[FWD:.*]] = !DICompositeType({{.*}}, name: "Generic",
10+
// CHECK-GEN-SAME: flags: DIFlagFwdDecl
11+
// CHECK-GEN: linkageName: "_TFV4main7Generic3setfwx2ATT_", scope: ![[FWD]],
12+
public struct Generic<T : P> {
13+
public func get() -> T.AT? {
14+
return nil
15+
}
16+
public func set(_ t: T.AT) {}
17+
}
18+
19+
// But only one concrete type is expected.
20+
// CHECK: !DISubprogram({{.*}}linkageName: "_TFV4main8Concrete3getfT_GSqSi_",
21+
// CHECK-SAME: scope: ![[CONC:[0-9]+]],
22+
// CHECK: ![[CONC]] = !DICompositeType({{.*}}, name: "Concrete",
23+
// CHECK-SAME-NOT: DIFlagFwdDecl
24+
public struct Concrete {
25+
public func get() -> Int? {
26+
return nil
27+
}
28+
public func set(_ t: Int) {}
29+
}
30+
31+
public func getConcrete() -> Concrete? { return nil; }

0 commit comments

Comments
 (0)