From f6a31e0483445aa4c368a08bb4a9ffd1a4f6ad7f Mon Sep 17 00:00:00 2001 From: zoecarver Date: Mon, 23 Nov 2020 00:14:25 -0800 Subject: [PATCH] [cxx-interop][nfc] Support forward declared records inside other records. The pattern: struct X { friend struct Y; }; struct Y {}; is fairly common. But before this commit we would crash while attempting to add "Y" as a child of "X". This commit simply checks if the child record is a declaration or definition. If the former, it bails (and the "child" record will be imported where it's defined). --- .../Interop/Cxx/class/Inputs/nested-records.h | 23 +++++++++++++++++++ .../nested-records-module-interface.swift | 19 +++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/test/Interop/Cxx/class/Inputs/nested-records.h b/test/Interop/Cxx/class/Inputs/nested-records.h index a31b9449e7c52..fce426e03ef89 100644 --- a/test/Interop/Cxx/class/Inputs/nested-records.h +++ b/test/Interop/Cxx/class/Inputs/nested-records.h @@ -65,4 +65,27 @@ struct HasForwardDeclaredTemplateChild { // TODO: Nested class templates (SR-13853). +namespace NestedDeclIsAFirstForwardDeclaration { + +struct ForwardDeclaresFriend { + friend struct ForwardDeclaredFriend; + friend void takesFriend(struct ForwardDeclaredFriend f); +}; + +struct ForwardDeclaredFriend { }; + +inline void takesFriend(ForwardDeclaredFriend b) { } + +struct HasNestedForwardDeclaration { + struct IsNestedForwardDeclaration; +}; + +struct HasNestedForwardDeclaration::IsNestedForwardDeclaration { + int a; +}; + +inline void takesHasNestedForwardDeclaration(HasNestedForwardDeclaration) { } + +} + #endif // TEST_INTEROP_CXX_CLASS_INPUTS_NESTED_RECORDS_H diff --git a/test/Interop/Cxx/class/nested-records-module-interface.swift b/test/Interop/Cxx/class/nested-records-module-interface.swift index 17017cd8616cb..896f217e861e8 100644 --- a/test/Interop/Cxx/class/nested-records-module-interface.swift +++ b/test/Interop/Cxx/class/nested-records-module-interface.swift @@ -74,3 +74,22 @@ // CHECK: } // CHECK: init() // CHECK: } + +// CHECK: extension NestedDeclIsAFirstForwardDeclaration { +// CHECK: struct ForwardDeclaresFriend { +// CHECK: init() +// CHECK: } +// CHECK: struct ForwardDeclaredFriend { +// CHECK: init() +// CHECK: } +// CHECK: static func takesFriend(_ b: NestedDeclIsAFirstForwardDeclaration.ForwardDeclaredFriend) +// CHECK: struct HasNestedForwardDeclaration { +// CHECK: struct IsNestedForwardDeclaration { +// CHECK: var a: Int32 +// CHECK: init() +// CHECK: init(a: Int32) +// CHECK: } +// CHECK: init() +// CHECK: } +// CHECK: static func takesHasNestedForwardDeclaration(_: NestedDeclIsAFirstForwardDeclaration.HasNestedForwardDeclaration) +// CHECK: }