Skip to content

[DebugInfo] Handle types with @_originallyDefinedIn in DebugInfo #77290

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1792,6 +1792,28 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
return InternalType;
}

llvm::DIType *SpecificationOf = nullptr;
if (auto *TypeDecl = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
// If this is 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 declaraation. 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).
if (auto Attribute =
TypeDecl->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
Attribute->OriginalModuleName);

void *Key = (void *)Identifier.get();
auto InnerScope =
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
SpecificationOf = DBuilder.createForwardDecl(
llvm::dwarf::DW_TAG_structure_type, TypeDecl->getNameStr(),
InnerScope, File, 0, llvm::dwarf::DW_LANG_Swift, 0, 0);
}
}

// Here goes!
switch (BaseTy->getKind()) {
case TypeKind::BuiltinUnboundGeneric:
Expand Down Expand Up @@ -1894,7 +1916,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, L.File,
FwdDeclLine, llvm::dwarf::DW_LANG_Swift, 0, AlignInBits);
return createOpaqueStruct(Scope, Name, L.File, FwdDeclLine, SizeInBits,
AlignInBits, Flags, MangledName);
AlignInBits, Flags, MangledName, {},
SpecificationOf);
}

case TypeKind::Class: {
Expand Down Expand Up @@ -1931,7 +1954,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
return DIType;
}
return createPointerSizedStruct(Scope, Decl->getNameStr(), L.File,
FwdDeclLine, Flags, MangledName);
FwdDeclLine, Flags, MangledName,
SpecificationOf);
}

case TypeKind::Protocol: {
Expand Down Expand Up @@ -1977,11 +2001,11 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
return createSpecializedStructOrClassType(
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
Flags, MangledName);

return createOpaqueStructWithSizedContainer(
Scope, Decl ? Decl->getNameStr() : "", L.File, FwdDeclLine,
SizeInBits, AlignInBits, Flags, MangledName,
collectGenericParams(StructTy));
collectGenericParams(StructTy), SpecificationOf);
}

case TypeKind::BoundGenericClass: {
Expand All @@ -1999,9 +2023,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
// attribute accordingly.
assert(SizeInBits ==
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default));
return createPointerSizedStruct(Scope,
Decl ? Decl->getNameStr() : MangledName,
L.File, FwdDeclLine, Flags, MangledName);
return createPointerSizedStruct(
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
Flags, MangledName, SpecificationOf);
}

case TypeKind::Pack:
Expand Down Expand Up @@ -2122,7 +2146,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
}
return createOpaqueStruct(Scope, Decl->getName().str(), L.File,
FwdDeclLine, SizeInBits, AlignInBits, Flags,
MangledName);
MangledName, {}, SpecificationOf);
}

case TypeKind::BoundGenericEnum: {
Expand All @@ -2142,7 +2166,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
}
return createOpaqueStructWithSizedContainer(
Scope, Decl->getName().str(), L.File, FwdDeclLine, SizeInBits,
AlignInBits, Flags, MangledName, collectGenericParams(EnumTy));
AlignInBits, Flags, MangledName, collectGenericParams(EnumTy),
SpecificationOf);
}

case TypeKind::BuiltinVector: {
Expand Down Expand Up @@ -2322,7 +2347,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
}
}

llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy,
llvm::DIScope *Scope = nullptr) {
// Is this an empty type?
if (DbgTy.isNull())
// We can't use the empty type as an index into DenseMap.
Expand Down Expand Up @@ -2354,7 +2380,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
//
// FIXME: Builtin and qualified types in LLVM have no parent
// scope. TODO: This can be fixed by extending DIBuilder.
llvm::DIScope *Scope = nullptr;
// Make sure to retrieve the context of the type alias, not the pointee.
DeclContext *Context = nullptr;
const Decl *TypeDecl = nullptr;
Expand Down
14 changes: 14 additions & 0 deletions test/DebugInfo/originally_defined_in.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s

@_originallyDefinedIn(
module: "Other", iOS 2.0, macOS 2.0, tvOS 2.0, watchOS 2.0)
@available(iOS 1.0, macOS 1.0, tvOS 1.0, watchOS 1.0, *)
public struct A {
let i = 10
}

// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A",{{.*}}identifier: "$s21originally_defined_in1AVD",{{.*}}specification_of: ![[S1:[0-9]+]]
// CHECK: [[S1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "A", scope: ![[S2:[0-9]+]]
// CHECK: [[S2]] = !DIModule({{.*}}name: "Other"

let a = A()