Skip to content

[interop] do not synthesize special members for C++ records with inco… #68478

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
Sep 15, 2023
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
29 changes: 25 additions & 4 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,26 @@ ImportedType findOptionSetType(clang::QualType type,
return importedType;
}

static bool areRecordFieldsComplete(const clang::CXXRecordDecl *decl) {
for (const auto *f : decl->fields()) {
auto *fieldRecord = f->getType()->getAsCXXRecordDecl();
if (fieldRecord) {
if (!fieldRecord->isCompleteDefinition()) {
return false;
}
if (!areRecordFieldsComplete(fieldRecord))
return false;
}
}
for (const auto base : decl->bases()) {
if (auto *baseRecord = base.getType()->getAsCXXRecordDecl()) {
if (!areRecordFieldsComplete(baseRecord))
return false;
}
}
return true;
}

namespace {
/// Customized llvm::DenseMapInfo for storing borrowed APSInts.
struct APSIntRefDenseMapInfo {
Expand Down Expand Up @@ -2663,10 +2683,11 @@ namespace {
auto &clangSema = Impl.getClangSema();
// Make Clang define any implicit constructors it may need (copy,
// default). Make sure we only do this if the class has been fully defined
// and we're not in a dependent context (this is equivalent to the logic
// in CanDeclareSpecialMemberFunction in Clang's SemaLookup.cpp).
// TODO: I suspect this if-statement does not need to be here.
if (!decl->isBeingDefined() && !decl->isDependentContext()) {
// with complete fields, and we're not in a dependent context(this is
// equivalent to the logic in CanDeclareSpecialMemberFunction in Clang's
// SemaLookup.cpp).
if (!decl->isBeingDefined() && !decl->isDependentContext() &&
areRecordFieldsComplete(decl)) {
if (decl->needsImplicitDefaultConstructor()) {
clang::CXXConstructorDecl *ctor =
clangSema.DeclareImplicitDefaultConstructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
// CHECK: func mutateIt(_: Empty)

// CHECK: class IntPair {
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: func test() -> Int32
// CHECK: class func create() -> IntPair!
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: IntPair!)
22 changes: 11 additions & 11 deletions test/Interop/Cxx/foreign-reference/pod-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,60 +20,60 @@

// CHECK: class IntPair {
// CHECK-NOT: init
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> IntPair
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: IntPair)
// CHECK-NOT: func passThroughByValue(_ x: IntPair) -> IntPair

// CHECK: class RefHoldingPair {
// CHECK-NOT: init
// CHECK-NOT: pair
// CHECK: var otherValue: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> RefHoldingPair
// CHECK: var otherValue: Int32
// CHECK: }

// CHECK: class RefHoldingPairRef {
// CHECK-NOT: init
// CHECK: var pair: IntPair
// CHECK: var otherValue: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> RefHoldingPairRef
// CHECK: var pair: IntPair
// CHECK: var otherValue: Int32
// CHECK: }

// CHECK: class RefHoldingPairPtr {
// CHECK-NOT: init
// CHECK: var pair: IntPair
// CHECK: var otherValue: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> RefHoldingPairPtr
// CHECK: var pair: IntPair
// CHECK: var otherValue: Int32
// CHECK: }

// CHECK: struct ValueHoldingPair {
// CHECK-NOT: init
// CHECK-NOT: pair
// CHECK: init()
// CHECK: var otherValue: Int32
// CHECK: func test() -> Int32
// CHECK: mutating func testMutable() -> Int32
// CHECK: static func create() -> UnsafeMutablePointer<ValueHoldingPair>
// CHECK: var otherValue: Int32
// CHECK: }

// CHECK: class BigType {
// CHECK-NOT: init
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: var buffer:
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> BigType
// CHECK: var a: Int32
// CHECK: var b: Int32
// CHECK: var buffer:
// CHECK: }
// CHECK: func mutateIt(_ x: BigType)
// CHECK-NOT: func passThroughByValue(_ x: BigType) -> BigType
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,36 @@

// CHECK: class DeletedDtor {
// CHECK-NOT: init
// CHECK: var value: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> DeletedDtor
// CHECK: var value: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: DeletedDtor)

// CHECK: class PrivateDtor {
// CHECK-NOT: init
// CHECK: var value: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> PrivateDtor
// CHECK: var value: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: PrivateDtor)

// CHECK: class DeletedSpecialMembers {
// CHECK-NOT: init
// CHECK: var value: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> DeletedSpecialMembers
// CHECK: var value: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: DeletedSpecialMembers)

// CHECK: class PrivateSpecialMembers {
// CHECK-NOT: init
// CHECK: var value: Int32
// CHECK: func test() -> Int32
// CHECK: func testMutable() -> Int32
// CHECK: class func create() -> PrivateSpecialMembers
// CHECK: var value: Int32
// CHECK: }
// CHECK: func mutateIt(_ x: PrivateSpecialMembers)