Skip to content

[CxxInterop] Add tests for extern vars #31093

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 23 commits into from
Apr 22, 2020
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
21 changes: 21 additions & 0 deletions test/Interop/Cxx/extern-var/Inputs/extern-var.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
int counter = 12;

int getCounterFromCxx() {
return counter;
}

void setCounterFromCxx(int c) {
counter = c;
}

namespace Namespaced {
int counter = 12;

int getCounterFromCxx() {
return counter;
}

void setCounterFromCxx(int c) {
counter = c;
}
}
11 changes: 11 additions & 0 deletions test/Interop/Cxx/extern-var/Inputs/extern-var.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extern int counter;

int getCounterFromCxx();
void setCounterFromCxx(int);

namespace Namespaced {
extern int counter;

int getCounterFromCxx();
void setCounterFromCxx(int);
}
3 changes: 3 additions & 0 deletions test/Interop/Cxx/extern-var/Inputs/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module ExternVar {
header "extern-var.h"
}
49 changes: 49 additions & 0 deletions test/Interop/Cxx/extern-var/extern-var-irgen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s

import ExternVar

public func getCounter() -> CInt {
return counter
}

// CHECK: @{{counter|"\?counter@@3HA"}} = external {{(dso_local )?}}global i32, align 4

// CHECK: define {{(protected |dllexport )?}}swiftcc i32 @"$s4main10getCounters5Int32VyF"() #0
// CHECK: [[LOAD:%.*]] = load i32, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @{{counter|"\?counter@@3HA"}} to %Ts5Int32V*), i32 0, i32 0), align 4
// CHECK: ret i32 [[LOAD]]

public func setCounter(_ c: CInt) {
counter = c
}

// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main10setCounteryys5Int32VF"(i32 %0) #0
// CHECK: store i32 %0, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @{{counter|"\?counter@@3HA"}} to %Ts5Int32V*), i32 0, i32 0), align 4

public func getNamespacedCounter() -> CInt {
return Namespaced.counter
}

// CHECK: define {{(protected |dllexport )?}}swiftcc i32 @"$s4main20getNamespacedCounters5Int32VyF"() #0
//FIXME mangle non-top-level var names to prevent name collisions and check:
// load i32, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @Namespaced.counter to %Ts5Int32V*), i32 0, i32 0), align 4
// CHECK: ret i32 %1

public func setNamespacedCounter(_ c: CInt) {
Namespaced.counter = c
}

// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20setNamespacedCounteryys5Int32VF"(i32 %0) #0
//FIXME mangle non-top-level var names to prevent name collisions and check:
// store i32 %0, i32* getelementptr inbounds (%Ts5Int32V, %Ts5Int32V* bitcast (i32* @Namespaced.counter to %Ts5Int32V*), i32 0, i32 0), align 4

func modifyInout(_ c: inout CInt) {
c = 42
}

public func passingVarAsInout() {
modifyInout(&counter)
}

// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main17passingVarAsInoutyyF"() #0
// CHECK: call swiftcc void @"$s4main11modifyInoutyys5Int32VzF"(%Ts5Int32V* nocapture dereferenceable(4) bitcast (i32* @{{counter|"\?counter@@3HA"}} to %Ts5Int32V*))

59 changes: 59 additions & 0 deletions test/Interop/Cxx/extern-var/extern-var-silgen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// RUN: %target-swift-emit-sil %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s

import ExternVar

func getCounter() -> CInt {
return counter
}

// CHECK: sil_global @counter : $Int32

// CHECK: sil hidden @$s4main10getCounters5Int32VyF : $@convention(thin) () -> Int32
// CHECK: [[COUNTER:%.*]] = global_addr @counter : $*Int32
// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] [[COUNTER]] : $*Int32
// CHECK: [[LOAD:%.*]] = load [[ACCESS]] : $*Int32
// CHECK: return [[LOAD]] : $Int32

func setCounter(_ c: CInt) {
counter = c
}

// CHECK: sil hidden @$s4main10setCounteryys5Int32VF : $@convention(thin) (Int32) -> ()
// CHECK: [[COUNTER:%.*]] = global_addr @counter : $*Int32
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[COUNTER]] : $*Int32
// CHECK: store %0 to [[ACCESS]] : $*Int32

func getNamespacedCounter() -> CInt {
return Namespaced.counter
}

// sil hidden @$s4main20getNamespacedCounters5Int32VyF : $@convention(thin) () -> Int32
//FIXME mangle non-top-level var names to prevent name collisions
// %0 = global_addr @Namespaced.counter : $*Int32
// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] %0 : $*Int32
// CHECK: [[LOAD:%.*]] = load [[ACCESS]] : $*Int32
// CHECK: return [[LOAD]] : $Int32

func setNamespacedCounter(_ c: CInt) {
Namespaced.counter = c
}

// CHECK: sil hidden @$s4main20setNamespacedCounteryys5Int32VF : $@convention(thin) (Int32) -> ()
//FIXME mangle non-top-level var names to prevent name collisions
// %1 = global_addr @Namespaced.counter : $*Int32
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] %1 : $*Int32
// CHECK: store %0 to [[ACCESS]] : $*Int32

func modifyInout(_ c: inout CInt) {
c = 42
}

func passingVarAsInout() {
modifyInout(&counter)
}

// CHECK: sil hidden @$s4main17passingVarAsInoutyyF : $@convention(thin) () -> ()
// CHECK: [[COUNTER:%.*]] = global_addr @counter : $*Int32
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[COUNTER]] : $*Int32
// CHECK: [[FUNCTION:%.*]] = function_ref @$s4main11modifyInoutyys5Int32VzF : $@convention(thin) (@inout Int32) -> ()
// CHECK: apply [[FUNCTION]]([[ACCESS]]) : $@convention(thin) (@inout Int32) -> ()
48 changes: 48 additions & 0 deletions test/Interop/Cxx/extern-var/extern-var.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: %empty-directory(%t)
// RUN: %target-clang -c %S/Inputs/extern-var.cc -I %S/Inputs -o %t/extern-var.o
// RUN: %target-build-swift %s -I %S/Inputs -o %t/extern-var %t/extern-var.o -Xfrontend -enable-cxx-interop
// RUN: %target-codesign %t/extern-var
// RUN: %target-run %t/extern-var
//
// REQUIRES: executable_test

import ExternVar
import StdlibUnittest

var ExternVarTestSuite = TestSuite("ExternVarTestSuite")

ExternVarTestSuite.test("write-from-swift") {
counter = 42
expectEqual(42, counter)
expectEqual(42, getCounterFromCxx())
}

ExternVarTestSuite.test("write-from-cxx") {
setCounterFromCxx(84)
expectEqual(84, counter)
expectEqual(84, getCounterFromCxx())
}

//FIXME mangle non-top-level var names to prevent name collisions
// ExternVarTestSuite.test("namespaced-write-from-swift") {
// Namespaced.counter = 42
// expectEqual(42, Namespaced.counter)
// expectEqual(42, amespaced.getCounterFromCxx())
// }

//FIXME mangle non-top-level var names to prevent name collisions
// ExternVarTestSuite.test("namespaced-write-from-cxx") {
// Namespaced.setCounterFromCxx(84)
// expectEqual(84, Namespaced.counter)
// expectEqual(84, Namespaced.getCounterFromCxx())
// }

//FIXME mangle non-top-level var names to prevent name collisions
// ExternVarTestSuite.test("no-collisions") {
// counter = 12
// Namespaced.counter = 42
// expectEqual(12, counter)
// expectEqual(42, Namespaced.counter)
// }

runAllTests()
17 changes: 13 additions & 4 deletions test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,7 @@ elif run_os in ['windows-msvc']:
config.target_shared_library_suffix = '.dll'
config.target_sdk_name = 'windows'
config.target_runtime = 'native'
config.target_cc_options = ""

config.target_build_swift = \
('%r -target %s %s %s %s %s -libc %s' % \
Expand Down Expand Up @@ -1055,7 +1056,8 @@ elif run_os in ['windows-msvc']:
config.target_add_rpath = r''

config.target_clang = \
('clang++ -target %s %s -fobjc-runtime=ios-5.0' % (config.variant_triple, clang_mcp_opt))
('clang++ -target %s %s %s -fobjc-runtime=ios-5.0' % \
(config.variant_triple, clang_mcp_opt, config.target_cc_options))
config.target_ld = \
('%r -libpath:%s' % (config.link, os.path.join(test_resource_dir, \
config.target_sdk_name)))
Expand Down Expand Up @@ -1095,24 +1097,28 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows-
config.target_shared_library_prefix = 'lib'
config.target_shared_library_suffix = ".dll"
config.target_sdk_name = "cygwin"
config.target_cc_options = ""
elif run_os == 'windows-gnu':
lit_config.note("Testing MinGW " + config.variant_triple)
config.target_object_format = "coff"
config.target_shared_library_prefix = 'lib'
config.target_shared_library_suffix = ".dll"
config.target_sdk_name = "mingw"
config.target_cc_options = ""
elif run_os == 'freebsd':
lit_config.note("Testing FreeBSD " + config.variant_triple)
config.target_object_format = "elf"
config.target_shared_library_prefix = 'lib'
config.target_shared_library_suffix = ".so"
config.target_sdk_name = "freebsd"
config.target_cc_options = "-fPIE"
elif run_os == 'openbsd':
lit_config.note("Testing OpenBSD " + config.variant_triple)
config.target_object_format = "elf"
config.target_shared_library_prefix = 'lib'
config.target_shared_library_suffix = ".so"
config.target_sdk_name = "openbsd"
config.target_cc_options = "-fPIE"
elif kIsAndroid:
lit_config.note("Testing Android " + config.variant_triple)
config.target_object_format = "elf"
Expand All @@ -1122,12 +1128,14 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows-
# Needed by several ParseableInterface/swift_build_sdk_interfaces tests on
# Android
config.environment['ANDROID_DATA'] = os.environ['ANDROID_DATA']
config.target_cc_options = "-fPIE"
else:
lit_config.note("Testing Linux " + config.variant_triple)
config.target_object_format = "elf"
config.target_shared_library_prefix = 'lib'
config.target_shared_library_suffix = ".so"
config.target_sdk_name = "linux"
config.target_cc_options = "-fPIE"
config.target_runtime = "native"
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")

Expand Down Expand Up @@ -1185,8 +1193,8 @@ elif (run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'openbsd', 'windows-
'%s -emit-pcm -target %s' %
(config.swiftc, config.variant_triple))
config.target_clang = (
"clang++ -target %s %s -fobjc-runtime=ios-5.0" %
(config.variant_triple, clang_mcp_opt))
"clang++ -target %s %s %s -fobjc-runtime=ios-5.0" %
(config.variant_triple, clang_mcp_opt, config.target_cc_options))
config.target_ld = "ld -L%r" % (make_path(test_resource_dir, config.target_sdk_name))
elif run_os == 'linux-androideabi' or run_os == 'linux-android':
# The module triple for Android ARMv7 seems to be canonicalized in LLVM
Expand All @@ -1195,6 +1203,7 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android':
target_specific_module_triple = re.sub(r'androideabi', 'android',
target_specific_module_triple)
config.variant_triple = re.sub(r'androideabi', 'android', config.variant_triple)
config.target_cc_options = "-fPIE"
def get_architecture_value(**kwargs):
result = kwargs[run_cpu]
if result is None:
Expand Down Expand Up @@ -1315,7 +1324,7 @@ elif run_os == 'linux-androideabi' or run_os == 'linux-android':
'clang++',
'-target', config.variant_triple,
clang_mcp_opt, android_include_system_paths_opt,
'-fobjc-runtime=ios-5.0'])
config.target_cc_options, '-fobjc-runtime=ios-5.0'])
config.target_ld = ' '.join([
tools_directory,
'-L%s' % make_path(test_resource_dir, config.target_sdk_name)])
Expand Down