Skip to content

Commit da690d6

Browse files
committed
[DebugInfo] Handle types with @_originallyDefinedIn in DebugInfo
When processing a nominal type that has the @_originallyDefinedIn attribute, IRGenDebugInfo emits a forward declaration of the type as a child of the original module, and the type with a specification pointing to the forward declaration. We do this so LLDB has enough information to both find the type in reflection metadata (the parent module name) and find it in the swiftmodule (the module name in the type mangled name). rdar://137146961
1 parent 560fe75 commit da690d6

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,28 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
17921792
return InternalType;
17931793
}
17941794

1795+
llvm::DIType *SpecificationOf = nullptr;
1796+
if (auto *TypeDecl = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
1797+
// If this is a nominal type that has the @_originallyDefinedIn attribute,
1798+
// IRGenDebugInfo emits a forward declaration of the type as a child
1799+
// of the original module, and the type with a specification pointing to
1800+
// the forward declaraation. We do this so LLDB has enough information to
1801+
// both find the type in reflection metadata (the parent module name) and
1802+
// find it in the swiftmodule (the module name in the type mangled name).
1803+
if (auto Attribute =
1804+
TypeDecl->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
1805+
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
1806+
Attribute->OriginalModuleName);
1807+
1808+
void *Key = (void *)Identifier.get();
1809+
auto InnerScope =
1810+
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
1811+
SpecificationOf = DBuilder.createForwardDecl(
1812+
llvm::dwarf::DW_TAG_structure_type, TypeDecl->getNameStr(),
1813+
InnerScope, File, 0, llvm::dwarf::DW_LANG_Swift, 0, 0);
1814+
}
1815+
}
1816+
17951817
// Here goes!
17961818
switch (BaseTy->getKind()) {
17971819
case TypeKind::BuiltinUnboundGeneric:
@@ -1894,7 +1916,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
18941916
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, L.File,
18951917
FwdDeclLine, llvm::dwarf::DW_LANG_Swift, 0, AlignInBits);
18961918
return createOpaqueStruct(Scope, Name, L.File, FwdDeclLine, SizeInBits,
1897-
AlignInBits, Flags, MangledName);
1919+
AlignInBits, Flags, MangledName, {},
1920+
SpecificationOf);
18981921
}
18991922

19001923
case TypeKind::Class: {
@@ -1931,7 +1954,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
19311954
return DIType;
19321955
}
19331956
return createPointerSizedStruct(Scope, Decl->getNameStr(), L.File,
1934-
FwdDeclLine, Flags, MangledName);
1957+
FwdDeclLine, Flags, MangledName,
1958+
SpecificationOf);
19351959
}
19361960

19371961
case TypeKind::Protocol: {
@@ -1977,11 +2001,11 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
19772001
return createSpecializedStructOrClassType(
19782002
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
19792003
Flags, MangledName);
1980-
2004+
19812005
return createOpaqueStructWithSizedContainer(
19822006
Scope, Decl ? Decl->getNameStr() : "", L.File, FwdDeclLine,
19832007
SizeInBits, AlignInBits, Flags, MangledName,
1984-
collectGenericParams(StructTy));
2008+
collectGenericParams(StructTy), SpecificationOf);
19852009
}
19862010

19872011
case TypeKind::BoundGenericClass: {
@@ -1999,9 +2023,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
19992023
// attribute accordingly.
20002024
assert(SizeInBits ==
20012025
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default));
2002-
return createPointerSizedStruct(Scope,
2003-
Decl ? Decl->getNameStr() : MangledName,
2004-
L.File, FwdDeclLine, Flags, MangledName);
2026+
return createPointerSizedStruct(
2027+
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
2028+
Flags, MangledName, SpecificationOf);
20052029
}
20062030

20072031
case TypeKind::Pack:
@@ -2122,7 +2146,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
21222146
}
21232147
return createOpaqueStruct(Scope, Decl->getName().str(), L.File,
21242148
FwdDeclLine, SizeInBits, AlignInBits, Flags,
2125-
MangledName);
2149+
MangledName, {}, SpecificationOf);
21262150
}
21272151

21282152
case TypeKind::BoundGenericEnum: {
@@ -2142,7 +2166,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
21422166
}
21432167
return createOpaqueStructWithSizedContainer(
21442168
Scope, Decl->getName().str(), L.File, FwdDeclLine, SizeInBits,
2145-
AlignInBits, Flags, MangledName, collectGenericParams(EnumTy));
2169+
AlignInBits, Flags, MangledName, collectGenericParams(EnumTy),
2170+
SpecificationOf);
21462171
}
21472172

21482173
case TypeKind::BuiltinVector: {
@@ -2322,7 +2347,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23222347
}
23232348
}
23242349

2325-
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
2350+
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy,
2351+
llvm::DIScope *Scope = nullptr) {
23262352
// Is this an empty type?
23272353
if (DbgTy.isNull())
23282354
// We can't use the empty type as an index into DenseMap.
@@ -2354,7 +2380,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23542380
//
23552381
// FIXME: Builtin and qualified types in LLVM have no parent
23562382
// scope. TODO: This can be fixed by extending DIBuilder.
2357-
llvm::DIScope *Scope = nullptr;
23582383
// Make sure to retrieve the context of the type alias, not the pointee.
23592384
DeclContext *Context = nullptr;
23602385
const Decl *TypeDecl = nullptr;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s
2+
3+
@_originallyDefinedIn(
4+
module: "Other", iOS 2.0, macOS 2.0, tvOS 2.0, watchOS 2.0)
5+
@available(iOS 1.0, macOS 1.0, tvOS 1.0, watchOS 1.0, *)
6+
public struct A {
7+
let i = 10
8+
}
9+
10+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A",{{.*}}identifier: "$s21originally_defined_in1AVD",{{.*}}specification_of: ![[S1:[0-9]+]]
11+
// CHECK: [[S1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "A", scope: ![[S2:[0-9]+]]
12+
// CHECK: [[S2]] = !DIModule({{.*}}name: "Other"
13+
14+
let a = A()

0 commit comments

Comments
 (0)