Skip to content

IRGen: We need to make not of any parent decl in nested type decls #16135

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
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
17 changes: 17 additions & 0 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,8 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
IGM.addObjCClass(var,
classDecl->getAttrs().hasAttribute<ObjCNonLazyRealizationAttr>());
}

IGM.IRGen.noteUseOfAnyParentTypeMetadata(classDecl);
}

llvm::Value *IRGenFunction::emitInvariantLoad(Address address,
Expand Down Expand Up @@ -2820,6 +2822,19 @@ void irgen::emitStructMetadata(IRGenModule &IGM, StructDecl *structDecl) {

IGM.defineTypeMetadata(declaredType, isIndirect, isPattern,
canBeConstant, init.finishAndCreateFuture());

IGM.IRGen.noteUseOfAnyParentTypeMetadata(structDecl);
}

void IRGenerator::noteUseOfAnyParentTypeMetadata(NominalTypeDecl *type) {
// If this is a nested type we also potentially might need the outer types.
auto *declCtxt = type->getDeclContext();
auto *parentNominalDecl =
declCtxt->getAsNominalTypeOrNominalTypeExtensionContext();
if (!parentNominalDecl)
return;

noteUseOfTypeMetadata(parentNominalDecl);
}

// Enums
Expand Down Expand Up @@ -3024,6 +3039,8 @@ void irgen::emitEnumMetadata(IRGenModule &IGM, EnumDecl *theEnum) {

IGM.defineTypeMetadata(declaredType, isIndirect, isPattern,
canBeConstant, init.finishAndCreateFuture());

IGM.IRGen.noteUseOfAnyParentTypeMetadata(theEnum);
}

llvm::Value *IRGenFunction::emitObjCSelectorRefLoad(StringRef selector) {
Expand Down
2 changes: 2 additions & 0 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ class IRGenerator {
noteUseOfTypeGlobals(type, false, requireMetadata);
}

void noteUseOfAnyParentTypeMetadata(NominalTypeDecl *type);

private:
void noteUseOfTypeGlobals(NominalTypeDecl *type,
bool isUseOfMetadata,
Expand Down
20 changes: 20 additions & 0 deletions test/multifile/Inputs/nested_types_defs.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
struct Outer {
struct Inner {
}
}

struct Outer2 {
enum InnerE {
}
}

struct Outer3 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some tests involving extensions.

class InnerC {
}
}

struct Outer4 {}

extension Outer4 {
struct InnerExtension {}
}
24 changes: 24 additions & 0 deletions test/multifile/nested_types.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// RUN: %target-build-swift -module-name test -wmo -O -emit-ir -Xfrontend -num-threads -Xfrontend 0 %s %S/Inputs/nested_types_defs.swift -o - | %FileCheck %s

// Make sure we generate the outer metadata.

// CHECK-DAG: @"$S4test5OuterVMf" = internal constant {{.*}} @"$SytWV"{{.*}}@"$S4test5OuterVMn"
// CHECK-DAG: @"$S4test6Outer2VMf" = internal constant {{.*}} @"$SytWV"{{.*}}@"$S4test6Outer2VMn"
// CHECK-DAG: @"$S4test6Outer3VMf" = internal constant {{.*}} @"$SytWV"{{.*}}@"$S4test6Outer3VMn"
// CHECK-DAG: @"$S4test6Outer4VMf" = internal constant {{.*}} @"$SytWV"{{.*}}@"$S4test6Outer4VMn"

class C<T> { }

struct Y {
let x:C<Outer.Inner>
let y:C<Outer2.InnerE>
let z:C<Outer3.InnerC>
let w:C<Outer4.InnerExtension>
}

public func test() {
var c = Y(x: C<Outer.Inner>(), y: C<Outer2.InnerE>(), z: C<Outer3.InnerC>(),
w: C<Outer4.InnerExtension>())

print("a \(c)")
}
21 changes: 21 additions & 0 deletions test/multifile/nested_types/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -wmo -O %s %S/../Inputs/nested_types_defs.swift -o %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s

class C<T> { }

struct Y {
let x:C<Outer.Inner>
let y:C<Outer2.InnerE>
let z:C<Outer3.InnerC>
let w:C<Outer4.InnerExtension>
}

func test() {
var c = Y(x: C<Outer.Inner>(), y: C<Outer2.InnerE>(), z: C<Outer3.InnerC>(), w: C<Outer4.InnerExtension>())

print("a \(c)")
}

// CHECK: a Y(x: a.C<a.Outer.Inner>, y: a.C<a.Outer2.InnerE>, z: a.C<a.Outer3.InnerC>, w: a.C<a.Outer4.InnerExtension>)
test()