Skip to content

[cxx-interop] Implicitly import Cxx module #60603

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 2 commits into from
Oct 20, 2022
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
24 changes: 11 additions & 13 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3274,19 +3274,6 @@ static void getImportDecls(ClangModuleUnit *ClangUnit, const clang::Module *M,
auto *ID = createImportDecl(Ctx, ClangUnit, ImportedMod, Exported);
Results.push_back(ID);
}

if (Ctx.LangOpts.EnableCXXInterop && requiresCPlusPlus(M)) {
// Try to load the Cxx module. We don't use it directly here, but we need to
// make sure that ASTContext has loaded this module.
auto *cxxModule = Ctx.getModuleByIdentifier(Ctx.Id_Cxx);
if (cxxModule) {
ImportPath::Builder builder(Ctx.Id_Cxx);
auto *importCxx =
ImportDecl::create(Ctx, ClangUnit, SourceLoc(), ImportKind::Module,
SourceLoc(), builder.get());
Results.push_back(importCxx);
}
}
}

void ClangModuleUnit::getDisplayDecls(SmallVectorImpl<Decl*> &results, bool recursive) const {
Expand Down Expand Up @@ -3923,6 +3910,17 @@ void ClangModuleUnit::getImportedModulesForLookup(
} else {
clangModule->getExportedModules(imported);
topLevel = clangModule->getTopLevelModule();

// If this is a C++ module, implicitly import the Cxx module, which contains
// definitions of Swift protocols that C++ types might conform to, such as
// CxxSequence.
if (owner.SwiftContext.LangOpts.EnableCXXInterop &&
requiresCPlusPlus(clangModule) && clangModule->Name != "CxxShim") {
auto *cxxModule =
owner.SwiftContext.getModuleByIdentifier(owner.SwiftContext.Id_Cxx);
if (cxxModule)
imports.push_back({ImportPath::Access(), cxxModule});
}
}

if (imported.empty()) {
Expand Down
4 changes: 4 additions & 0 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
this->addLinkLibrary(LinkLibrary("c++", LibraryKind::Library));
else if (Context.LangOpts.Target.isOSLinux())
this->addLinkLibrary(LinkLibrary("stdc++", LibraryKind::Library));

// Do not try to link Cxx with itself.
if (!getSwiftModule()->getName().is("Cxx"))
this->addLinkLibrary(LinkLibrary("swiftCxx", LibraryKind::Library));
}

// FIXME: It'd be better to have the driver invocation or build system that
Expand Down
26 changes: 26 additions & 0 deletions test/Interop/Cxx/class/constructors-copy-irgen-android.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Target-specific tests for C++ copy constructor code generation.

// 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

// REQUIRES: OS=linux-android || OS=linux-androideabi

// REQUIRES: CODEGENERATOR=X86
// REQUIRES: CODEGENERATOR=ARM

import Constructors
import TypeClassification

// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03HascdeF0V_ACtACF"
// ITANIUM_ARM-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
// ITANIUM_ARM: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_ARM: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_ARM: call %struct.HasUserProvidedCopyConstructor* @_ZN30HasUserProvidedCopyConstructorC2ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// ITANIUM_ARM: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_ARM: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_ARM: call %struct.HasUserProvidedCopyConstructor* @_ZN30HasUserProvidedCopyConstructorC2ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// ITANIUM_ARM: ret void

public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
return (x, x)
}
27 changes: 27 additions & 0 deletions test/Interop/Cxx/class/constructors-copy-irgen-macosx.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Target-specific tests for C++ copy constructor code generation.

// 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

// REQUIRES: OS=macosx

// REQUIRES: CODEGENERATOR=X86
// REQUIRES: CODEGENERATOR=ARM


import Constructors
import TypeClassification

// ITANIUM_X64-LABEL: define swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03Has{{cdeF0V_ACtACF|efgH0V_ADtADF}}"
// ITANIUM_X64-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
// ITANIUM_X64: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_X64: call void @_ZN30HasUserProvidedCopyConstructorC1ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// ITANIUM_X64: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// ITANIUM_X64: call void @_ZN30HasUserProvidedCopyConstructorC1ERKS_(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// ITANIUM_X64: ret void

public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
return (x, x)
}
27 changes: 27 additions & 0 deletions test/Interop/Cxx/class/constructors-copy-irgen-windows.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Target-specific tests for C++ copy constructor code generation.

// 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

// REQUIRES: OS=windows-msvc

// REQUIRES: CODEGENERATOR=X86
// REQUIRES: CODEGENERATOR=ARM


import Constructors
import TypeClassification

// MICROSOFT_X64-LABEL: define dllexport swiftcc void @"$s7MySwift35copyWithUserProvidedCopyConstructorySo03Has{{efgH0V_ADtADF|cdeF0V_ACtACF}}"
// MICROSOFT_X64-SAME: (%TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG0:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG1:%.*]], %TSo30HasUserProvidedCopyConstructorV* {{.*}}[[ARG2:%.*]])
// MICROSOFT_X64: [[ARG0_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG0]] to %struct.HasUserProvidedCopyConstructor*
// MICROSOFT_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// MICROSOFT_X64: call %struct.HasUserProvidedCopyConstructor* @"??0HasUserProvidedCopyConstructor@@QEAA@AEBU0@@Z"(%struct.HasUserProvidedCopyConstructor* [[ARG0_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// MICROSOFT_X64: [[ARG1_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG1]] to %struct.HasUserProvidedCopyConstructor*
// MICROSOFT_X64: [[ARG2_AS_STRUCT:%.*]] = bitcast %TSo30HasUserProvidedCopyConstructorV* [[ARG2]] to %struct.HasUserProvidedCopyConstructor*
// MICROSOFT_X64: call %struct.HasUserProvidedCopyConstructor* @"??0HasUserProvidedCopyConstructor@@QEAA@AEBU0@@Z"(%struct.HasUserProvidedCopyConstructor* [[ARG1_AS_STRUCT]], %struct.HasUserProvidedCopyConstructor* [[ARG2_AS_STRUCT]])
// MICROSOFT_X64: ret void

public func copyWithUserProvidedCopyConstructor(_ x: HasUserProvidedCopyConstructor)
-> (HasUserProvidedCopyConstructor, HasUserProvidedCopyConstructor) {
return (x, x)
}
50 changes: 0 additions & 50 deletions test/Interop/Cxx/class/constructors-copy-irgen.swift

This file was deleted.

57 changes: 57 additions & 0 deletions test/Interop/Cxx/class/constructors-irgen-android.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Target-specific tests for C++ constructor call code generation.

// 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

// REQUIRES: OS=linux-android || OS=linux-androideabi

// REQUIRES: CODEGENERATOR=X86
// REQUIRES: CODEGENERATOR=ARM

import Constructors
import TypeClassification

public func createHasVirtualBase() -> HasVirtualBase {
// ITANIUM_ARM: define protected swiftcc void @"$s7MySwift20createHasVirtualBaseSo0bcD0VyF"(%TSo14HasVirtualBaseV* noalias nocapture sret({{.*}}) %0)
// To verify that the thunk is inlined, make sure there's no intervening
// `define`, i.e. the call to the C++ constructor happens in
// createHasVirtualBase(), not some later function.
// ITANIUM_ARM-NOT: define
// Note `this` return type.
// ITANIUM_ARM: call %struct.HasVirtualBase* @_ZN14HasVirtualBaseC1E7ArgType(%struct.HasVirtualBase* %{{[0-9]+}}, [1 x i32] %{{[0-9]+}})
return HasVirtualBase(ArgType())
}

public func createImplicitDefaultConstructor() -> ImplicitDefaultConstructor {
// ITANIUM_ARM: define protected swiftcc i32 @"$s7MySwift32createImplicitDefaultConstructorSo0bcD0VyF"()
// ITANIUM_ARM-NOT: define
// Note `this` return type.
// ITANIUM_ARM: call %struct.ImplicitDefaultConstructor* @_ZN26ImplicitDefaultConstructorC2Ev(%struct.ImplicitDefaultConstructor* %{{[0-9]+}})
return ImplicitDefaultConstructor()
}

public func createStructWithSubobjectCopyConstructorAndValue() {
// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift48createStructWithSubobjectCopyConstructorAndValueyyF"()
// ITANIUM_ARM: [[MEMBER:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
// ITANIUM_ARM: [[OBJ:%.*]] = alloca %TSo42StructWithSubobjectCopyConstructorAndValueV
// ITANIUM_ARM: [[TMP:%.*]] = alloca %TSo33StructWithCopyConstructorAndValueV
// ITANIUM_ARM: [[MEMBER_AS_STRUCT:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[MEMBER]] to %struct.StructWithCopyConstructorAndValue*
// ITANIUM_ARM: call %struct.StructWithCopyConstructorAndValue* @_ZN33StructWithCopyConstructorAndValueC2Ev(%struct.StructWithCopyConstructorAndValue* [[MEMBER_AS_STRUCT]])
// ITANIUM_ARM: [[TMP_STRUCT:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[TMP]] to %struct.StructWithCopyConstructorAndValue*
// ITANIUM_ARM: [[MEMBER_AS_STRUCT_2:%.*]] = bitcast %TSo33StructWithCopyConstructorAndValueV* [[MEMBER]] to %struct.StructWithCopyConstructorAndValue*
// ITANIUM_ARM: call %struct.StructWithCopyConstructorAndValue* @_ZN33StructWithCopyConstructorAndValueC2ERKS_(%struct.StructWithCopyConstructorAndValue* [[TMP_STRUCT]], %struct.StructWithCopyConstructorAndValue* [[MEMBER_AS_STRUCT_2]])
// ITANIUM_ARM: ret void
let member = StructWithCopyConstructorAndValue()
let obj = StructWithSubobjectCopyConstructorAndValue(member: member)
}

public func createTemplatedConstructor() {
// ITANIUM_ARM-LABEL: define protected swiftcc void @"$s7MySwift26createTemplatedConstructoryyF"()
// ITANIUM_ARM: [[OBJ:%.*]] = alloca %TSo20TemplatedConstructorV
// ITANIUM_ARM: [[IVAL:%.*]] = load [1 x i32], [1 x i32]*
// ITANIUM_ARM: [[OBJ_AS_STRUCT:%.*]] = bitcast %TSo20TemplatedConstructorV* [[OBJ]] to %struct.TemplatedConstructor*
// ITANIUM_ARM: call %struct.TemplatedConstructor* @_ZN20TemplatedConstructorC2I7ArgTypeEET_(%struct.TemplatedConstructor* [[OBJ_AS_STRUCT]], [1 x i32] [[IVAL]])
// ITANIUM_ARM: ret void

// ITANIUM_ARM-LABEL: define {{.*}}%struct.TemplatedConstructor* @_ZN20TemplatedConstructorC2I7ArgTypeEET_(%struct.TemplatedConstructor* {{.*}}, [1 x i32] {{.*}})
let templated = TemplatedConstructor(ArgType())
}
Loading