Skip to content

Commit 510c9c9

Browse files
authored
Merge pull request #60603 from apple/egorzhdan/implicit-cxx
[cxx-interop] Implicitly import `Cxx` module
2 parents e7090e3 + 5a3bb14 commit 510c9c9

14 files changed

+258
-191
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3274,19 +3274,6 @@ static void getImportDecls(ClangModuleUnit *ClangUnit, const clang::Module *M,
32743274
auto *ID = createImportDecl(Ctx, ClangUnit, ImportedMod, Exported);
32753275
Results.push_back(ID);
32763276
}
3277-
3278-
if (Ctx.LangOpts.EnableCXXInterop && requiresCPlusPlus(M)) {
3279-
// Try to load the Cxx module. We don't use it directly here, but we need to
3280-
// make sure that ASTContext has loaded this module.
3281-
auto *cxxModule = Ctx.getModuleByIdentifier(Ctx.Id_Cxx);
3282-
if (cxxModule) {
3283-
ImportPath::Builder builder(Ctx.Id_Cxx);
3284-
auto *importCxx =
3285-
ImportDecl::create(Ctx, ClangUnit, SourceLoc(), ImportKind::Module,
3286-
SourceLoc(), builder.get());
3287-
Results.push_back(importCxx);
3288-
}
3289-
}
32903277
}
32913278

32923279
void ClangModuleUnit::getDisplayDecls(SmallVectorImpl<Decl*> &results, bool recursive) const {
@@ -3923,6 +3910,17 @@ void ClangModuleUnit::getImportedModulesForLookup(
39233910
} else {
39243911
clangModule->getExportedModules(imported);
39253912
topLevel = clangModule->getTopLevelModule();
3913+
3914+
// If this is a C++ module, implicitly import the Cxx module, which contains
3915+
// definitions of Swift protocols that C++ types might conform to, such as
3916+
// CxxSequence.
3917+
if (owner.SwiftContext.LangOpts.EnableCXXInterop &&
3918+
requiresCPlusPlus(clangModule) && clangModule->Name != "CxxShim") {
3919+
auto *cxxModule =
3920+
owner.SwiftContext.getModuleByIdentifier(owner.SwiftContext.Id_Cxx);
3921+
if (cxxModule)
3922+
imports.push_back({ImportPath::Access(), cxxModule});
3923+
}
39263924
}
39273925

39283926
if (imported.empty()) {

lib/IRGen/GenDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
474474
this->addLinkLibrary(LinkLibrary("c++", LibraryKind::Library));
475475
else if (Context.LangOpts.Target.isOSLinux())
476476
this->addLinkLibrary(LinkLibrary("stdc++", LibraryKind::Library));
477+
478+
// Do not try to link Cxx with itself.
479+
if (!getSwiftModule()->getName().is("Cxx"))
480+
this->addLinkLibrary(LinkLibrary("swiftCxx", LibraryKind::Library));
477481
}
478482

479483
// FIXME: It'd be better to have the driver invocation or build system that
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Target-specific tests for C++ copy constructor code generation.
2+
3+
// RUN: %swift -module-name MySwift -target armv7-none-linux-androideabi -dump-clang-diagnostics -I %S/Inputs -enable-experimental-cxx-interop -emit-ir %s -parse-stdlib -parse-as-library -disable-legacy-type-info | %FileCheck %s -check-prefix=ITANIUM_ARM
4+
5+
// REQUIRES: OS=linux-android || OS=linux-androideabi
6+
7+
// REQUIRES: CODEGENERATOR=X86
8+
// REQUIRES: CODEGENERATOR=ARM
9+
10+
import Constructors
11+
import TypeClassification
12+
13+
// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03HascdeF0V_ACtACF"
14+
// ITANIUM_ARM-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
15+
// ITANIUM_ARM: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
16+
// ITANIUM_ARM: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
17+
// ITANIUM_ARM: call %struct.HasUserProvidedCopyConstructor* @_ZN30HasUserProvidedCopyConstructorC2ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
18+
// ITANIUM_ARM: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
19+
// ITANIUM_ARM: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
20+
// ITANIUM_ARM: call %struct.HasUserProvidedCopyConstructor* @_ZN30HasUserProvidedCopyConstructorC2ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
21+
// ITANIUM_ARM: ret void
22+
23+
public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
24+
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
25+
return (x, x)
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Target-specific tests for C++ copy constructor code generation.
2+
3+
// RUN: %swift -module-name MySwift -target x86_64-apple-macosx10.9 -dump-clang-diagnostics -I %S/Inputs -enable-experimental-cxx-interop -emit-ir %s -parse-stdlib -parse-as-library -disable-legacy-type-info | %FileCheck %s -check-prefix=ITANIUM_X64
4+
5+
// REQUIRES: OS=macosx
6+
7+
// REQUIRES: CODEGENERATOR=X86
8+
// REQUIRES: CODEGENERATOR=ARM
9+
10+
11+
import Constructors
12+
import TypeClassification
13+
14+
// ITANIUM_X64-LABEL: define swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03Has{{cdeF0V_ACtACF|efgH0V_ADtADF}}"
15+
// ITANIUM_X64-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
16+
// ITANIUM_X64: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
17+
// ITANIUM_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
18+
// ITANIUM_X64: call void @_ZN30HasUserProvidedCopyConstructorC1ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
19+
// ITANIUM_X64: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
20+
// ITANIUM_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
21+
// ITANIUM_X64: call void @_ZN30HasUserProvidedCopyConstructorC1ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
22+
// ITANIUM_X64: ret void
23+
24+
public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
25+
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
26+
return (x, x)
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Target-specific tests for C++ copy constructor code generation.
2+
3+
// RUN: %swift -module-name MySwift -target x86_64-unknown-windows-msvc -dump-clang-diagnostics -I %S/Inputs -enable-experimental-cxx-interop -emit-ir %s -parse-stdlib -parse-as-library -disable-legacy-type-info | %FileCheck %s -check-prefix=MICROSOFT_X64
4+
5+
// REQUIRES: OS=windows-msvc
6+
7+
// REQUIRES: CODEGENERATOR=X86
8+
// REQUIRES: CODEGENERATOR=ARM
9+
10+
11+
import Constructors
12+
import TypeClassification
13+
14+
// MICROSOFT_X64-LABEL: define dllexport swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03Has{{efgH0V_ADtADF|cdeF0V_ACtACF}}"
15+
// MICROSOFT_X64-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
16+
// MICROSOFT_X64: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
17+
// MICROSOFT_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
18+
// MICROSOFT_X64: call %struct.HasUserProvidedCopyConstructor* @"??0HasUserProvidedCopyConstructor@@QEAA@AEBU0@@Z"(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
19+
// MICROSOFT_X64: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
20+
// MICROSOFT_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
21+
// MICROSOFT_X64: call %struct.HasUserProvidedCopyConstructor* @"??0HasUserProvidedCopyConstructor@@QEAA@AEBU0@@Z"(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
22+
// MICROSOFT_X64: ret void
23+
24+
public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
25+
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
26+
return (x, x)
27+
}

test/Interop/Cxx/class/constructors-copy-irgen.swift

Lines changed: 0 additions & 50 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Target-specific tests for C++ constructor call code generation.
2+
3+
// RUN: %swift -module-name MySwift -target armv7-unknown-linux-androideabi -dump-clang-diagnostics -I %S/Inputs -enable-experimental-cxx-interop -emit-ir %s -parse-stdlib -parse-as-library -disable-legacy-type-info | %FileCheck %s -check-prefix=ITANIUM_ARM
4+
5+
// REQUIRES: OS=linux-android || OS=linux-androideabi
6+
7+
// REQUIRES: CODEGENERATOR=X86
8+
// REQUIRES: CODEGENERATOR=ARM
9+
10+
import Constructors
11+
import TypeClassification
12+
13+
public func createHasVirtualBase() -> HasVirtualBase {
14+
// ITANIUM_ARM: define protected swiftcc void @"$s7MySwift20createHasVirtualBaseSo0bcD0VyF"(%TSo14HasVirtualBaseV* noalias nocapture sret({{.*}}) %0)
15+
// To verify that the thunk is inlined, make sure there's no intervening
16+
// `define`, i.e. the call to the C++ constructor happens in
17+
// createHasVirtualBase(), not some later function.
18+
// ITANIUM_ARM-NOT: define
19+
// Note `this` return type.
20+
// ITANIUM_ARM: call %struct.HasVirtualBase* @_ZN14HasVirtualBaseC1E7ArgType(%struct.HasVirtualBase* %{{[0-9]+}}, [1 x i32] %{{[0-9]+}})
21+
return HasVirtualBase(ArgType())
22+
}
23+
24+
public func createImplicitDefaultConstructor() -> ImplicitDefaultConstructor {
25+
// ITANIUM_ARM: define protected swiftcc i32 @"$s7MySwift32createImplicitDefaultConstructorSo0bcD0VyF"()
26+
// ITANIUM_ARM-NOT: define
27+
// Note `this` return type.
28+
// ITANIUM_ARM: call %struct.ImplicitDefaultConstructor* @_ZN26ImplicitDefaultConstructorC2Ev(%struct.ImplicitDefaultConstructor* %{{[0-9]+}})
29+
return ImplicitDefaultConstructor()
30+
}
31+
32+
public func createStructWithSubobjectCopyConstructorAndValue() {
33+
// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift48createStructWithSubobjectCopyConstructorAndValueyyF"()
34+
// ITANIUM_ARM: [[MEMBER:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
35+
// ITANIUM_ARM: [[OBJ:%.*]] = alloca %TSo42StructWithSubobjectCopyConstructorAndValueV
36+
// ITANIUM_ARM: [[TMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
37+
// ITANIUM_ARM: [[MEMBER_AS_STRUCT:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[MEMBER]] to %struct.StructWithCopyConstructorAndValue*
38+
// ITANIUM_ARM: call %struct.StructWithCopyConstructorAndValue* @_ZN33StructWithCopyConstructorAndValueC2Ev(%struct.StructWithCopyConstructorAndValue* [[MEMBER_AS_STRUCT]])
39+
// ITANIUM_ARM: [[TMP_STRUCT:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[TMP]] to %struct.StructWithCopyConstructorAndValue*
40+
// ITANIUM_ARM: [[MEMBER_AS_STRUCT_2:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[MEMBER]] to %struct.StructWithCopyConstructorAndValue*
41+
// ITANIUM_ARM: call %struct.StructWithCopyConstructorAndValue* @_ZN33StructWithCopyConstructorAndValueC2ERKS_(%struct.StructWithCopyConstructorAndValue* [[TMP_STRUCT]], %struct.StructWithCopyConstructorAndValue* [[MEMBER_AS_STRUCT_2]])
42+
// ITANIUM_ARM: ret void
43+
let member = StructWithCopyConstructorAndValue()
44+
let obj = StructWithSubobjectCopyConstructorAndValue(member: member)
45+
}
46+
47+
public func createTemplatedConstructor() {
48+
// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift26createTemplatedConstructoryyF"()
49+
// ITANIUM_ARM: [[OBJ:%.*]] = alloca %TSo20TemplatedConstructorV
50+
// ITANIUM_ARM: [[IVAL:%.*]] = load [1 x i32], [1 x i32]*
51+
// ITANIUM_ARM: [[OBJ_AS_STRUCT:%.*]] = bitcast %TSo20TemplatedConstructorV* [[OBJ]] to %struct.TemplatedConstructor*
52+
// ITANIUM_ARM: call %struct.TemplatedConstructor* @_ZN20TemplatedConstructorC2I7ArgTypeEET_(%struct.TemplatedConstructor* [[OBJ_AS_STRUCT]], [1 x i32] [[IVAL]])
53+
// ITANIUM_ARM: ret void
54+
55+
// ITANIUM_ARM-LABEL: define {{.*}}%struct.TemplatedConstructor* @_ZN20TemplatedConstructorC2I7ArgTypeEET_(%struct.TemplatedConstructor* {{.*}}, [1 x i32] {{.*}})
56+
let templated = TemplatedConstructor(ArgType())
57+
}

0 commit comments

Comments
 (0)