File tree Expand file tree Collapse file tree 4 files changed +41
-8
lines changed Expand file tree Collapse file tree 4 files changed +41
-8
lines changed Original file line number Diff line number Diff line change @@ -7625,18 +7625,22 @@ static bool hasCopyTypeOperations(const clang::CXXRecordDecl *decl) {
7625
7625
if (decl->isInStdNamespace () && decl->getIdentifier () &&
7626
7626
decl->getName () == " _Optional_construct_base" )
7627
7627
return true ;
7628
+ // Hack for std::vector::const_iterator from libstdc++, which uses an extra
7629
+ // parameter on its copy constructor, which has a defaulted enable_if value.
7630
+ auto namespaceContext = dyn_cast_or_null<clang::NamespaceDecl>(
7631
+ decl->getEnclosingNamespaceContext ());
7632
+ if (namespaceContext && namespaceContext->getIdentifier () &&
7633
+ namespaceContext->getName () == " __gnu_cxx" && decl->getIdentifier () &&
7634
+ decl->getName () == " __normal_iterator" )
7635
+ return true ;
7628
7636
7629
7637
// If we have no way of copying the type we can't import the class
7630
7638
// at all because we cannot express the correct semantics as a swift
7631
7639
// struct.
7632
- if (llvm::any_of (decl->ctors (), [](clang::CXXConstructorDecl *ctor) {
7633
- return ctor->isCopyConstructor () &&
7634
- (ctor->isDeleted () || ctor->getAccess () != clang::AS_public);
7635
- }))
7636
- return false ;
7637
-
7638
- // TODO: this should probably check to make sure we actually have a copy ctor.
7639
- return true ;
7640
+ return llvm::any_of (decl->ctors (), [](clang::CXXConstructorDecl *ctor) {
7641
+ return ctor->isCopyConstructor () && !ctor->isDeleted () &&
7642
+ ctor->getAccess () == clang::AccessSpecifier::AS_public;
7643
+ });
7640
7644
}
7641
7645
7642
7646
static bool hasMoveTypeOperations (const clang::CXXRecordDecl *decl) {
Original file line number Diff line number Diff line change @@ -71,6 +71,25 @@ struct TemplatedConstructorWithExtraArg {
71
71
TemplatedConstructorWithExtraArg (T value, U other) { }
72
72
};
73
73
74
+ struct TemplatedCopyConstructor {
75
+ int x = 0 ;
76
+
77
+ TemplatedCopyConstructor (int x) : x(x) {}
78
+
79
+ template <class T >
80
+ TemplatedCopyConstructor (const T &value) : x(value.x) {}
81
+ };
82
+
83
+ struct TemplatedCopyConstructorWithExtraArg {
84
+ int x = 0 ;
85
+
86
+ TemplatedCopyConstructorWithExtraArg (int x) : x(x) {}
87
+
88
+ template <class T >
89
+ TemplatedCopyConstructorWithExtraArg (const T &value, int add = 0 )
90
+ : x(value.x + add) {}
91
+ };
92
+
74
93
struct __attribute__ ((swift_attr(" import_unsafe" )))
75
94
HasUserProvidedCopyConstructor {
76
95
int numCopies;
Original file line number Diff line number Diff line change 1
1
// RUN: %target-swift-ide-test -print-module -module-to-print=Constructors -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
2
2
3
+ // CHECK: struct TemplatedCopyConstructor
4
+ // CHECK: struct TemplatedCopyConstructorWithExtraArg
5
+
3
6
// Make sure we don't import non-copyable types because we will have no way to
4
7
// represent and copy/move these in swift with correct semantics.
5
8
// CHECK-NOT: DeletedCopyConstructor
Original file line number Diff line number Diff line change 2
2
3
3
import Constructors
4
4
5
+ func takesCopyable< T: Copyable > ( _ x: T . Type ) { }
6
+
5
7
let explicit = ExplicitDefaultConstructor ( )
6
8
7
9
let implicit = ImplicitDefaultConstructor ( )
@@ -12,3 +14,8 @@ let onlyCopyAndMove = CopyAndMoveConstructor() // expected-warning {{'init()' is
12
14
let deletedExplicitly = DefaultConstructorDeleted ( ) // expected-error {{missing argument for parameter 'a' in call}}
13
15
14
16
let withArg = ConstructorWithParam ( 42 )
17
+
18
+ let _ = TemplatedCopyConstructor ( 123 )
19
+ let _ = TemplatedCopyConstructorWithExtraArg ( 123 )
20
+ takesCopyable ( TemplatedCopyConstructor . self)
21
+ takesCopyable ( TemplatedCopyConstructorWithExtraArg . self)
You can’t perform that action at this time.
0 commit comments