blob: b3152724e51cf7b1c7d68ca2c5b448863e07c44e [file] [log] [blame]
Lukasz Anforowicz41e578a2022-10-21 07:53:38 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5//! This crate is used as a test input for `cc_bindings_from_rs` and the
6//! generated C++ bindings are then tested via `functions_test.cc`.
7
Lukasz Anforowiczf0f37dd2023-01-05 11:22:06 -08008/// APIs for testing various function calling conventions and linking options:
9/// - `#[no_mangle]`
10/// - `#[export_name = ...]`
11/// - `extern "C"` vs default/Rust ABI
12/// - etc.
13pub mod fn_abi_tests {
Lukasz Anforowiczf04bc522022-11-04 09:19:51 -070014
Lukasz Anforowiczf0f37dd2023-01-05 11:22:06 -080015 /// Testing one of simpler function bindings:
16 /// - `extern "C"` means that no thunk is required
17 /// - `#[no_mangle]` means that the function is already exposed with the
18 /// desired, public name (and just needs to be redeclared in C++).
19 #[no_mangle]
20 pub extern "C" fn get_42_as_f64_via_no_mangle_extern_c() -> f64 {
21 42.0
22 }
23
24 /// Testing `#[export_name = ...]` - the generated bindings need to
25 /// forward/proxy the call into a function with a different name.
26 #[export_name = "custom_export_name_for_add_i32"]
27 pub extern "C" fn add_i32_via_extern_c_with_export_name(x: i32, y: i32) -> i32 {
28 x + y
29 }
30
31 /// Testing bindings for an `extern "C"` function (no thunk required) with a
32 /// mangled name. This test verifies that:
33 /// * `cc_bindings_from_rs` can correctly discover mangled names that
34 /// `rustc` produces
35 /// * Bazel support for `cc_bindings_from_rs` invokes it with the same
36 /// command line flags as the ones used when invoking `rustc` when
37 /// building the `functions` crate.
38 ///
39 /// TODO(b/262904507): Bazel integration is currently broken and the
40 /// coresponding test is commented out in `functions_test.cc`.
41 pub extern "C" fn add_i32_via_extern_c_with_mangling(x: i32, y: i32) -> i32 {
42 x + y
43 }
44
45 /// Testing the default / Rust ABI (one used in absence of `extern "C"`).
46 pub fn add_i32_via_rust_abi(x: i32, y: i32) -> i32 {
47 x + y
48 }
Lukasz Anforowicz41e578a2022-10-21 07:53:38 -070049}
Lukasz Anforowicz903fc632022-10-25 08:55:33 -070050
Lukasz Anforowiczf0f37dd2023-01-05 11:22:06 -080051/// APIs for testing various kinds of function parameter types.
52pub mod fn_param_ty_tests {
53 /// Testing a type that maps to a built-in C++ type (spelled with a
54 /// keyword). `float` is one such example.
55 pub fn add_f64(x: f64, y: f64) -> f64 {
56 x + y
57 }
58
59 /// Testing a type that requires `#include`ing a standard C++ header.
60 /// `std::int32_t` is one such example - it requires `#include <cstdint>`.
61 pub fn add_i32(x: i32, y: i32) -> i32 {
62 x + y
63 }
Lukasz Anforowiczeb58a492023-01-07 08:25:48 -080064
65 pub fn add_i32_via_ptr(x: *const i32, y: *const i32, sum: *mut i32) {
66 #![allow(clippy::not_unsafe_ptr_arg_deref)]
67 unsafe {
68 *sum = *x + *y;
69 }
70 }
Lukasz Anforowicza782bda2023-01-17 14:04:50 -080071
Lukasz Anforowiczb06e0812023-03-02 15:54:32 -080072 pub fn char_to_ascii_lowercase(c: char) -> char {
73 // This function used to return unmodified `c` value, but (as we learned when
74 // authoring `rs_bindings_from_cc/test/struct/abi_class` tests) making
75 // some simple calculations below helps to exercise the ABI
76 // compatibility between Rust `char` and C++ `rs_std::rs_char`.
77 c.to_ascii_lowercase()
Lukasz Anforowicza782bda2023-01-17 14:04:50 -080078 }
Lukasz Anforowicz5c1b3ad2023-04-13 17:05:00 -070079
80 pub fn apply_binary_i32_op(x: i32, y: i32, f: extern "C" fn(i32, i32) -> i32) -> i32 {
81 f(x, y)
82 }
Lukasz Anforowiczaa2de7e2023-06-15 11:32:05 -070083
84 pub fn get_ref_to_smaller_int<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
85 if *x < *y { x } else { y }
86 }
87
88 pub fn get_identical_ref_with_inferred_lifetime(x: &'_ i32) -> &'_ i32 {
89 x
90 }
91
92 pub fn set_mut_ref_to_sum_of_ints(sum: &mut i32, x: i32, y: i32) {
93 *sum = x + y;
94 }
Lukasz Anforowicz903fc632022-10-25 08:55:33 -070095}
Lukasz Anforowiczed17d052022-11-02 12:07:28 -070096
Lukasz Anforowiczf0f37dd2023-01-05 11:22:06 -080097/// APIs for testing functions that return the unit / `()` / `void` type.
98pub mod unit_ret_ty_tests {
99 use std::sync::Mutex;
100
101 static G_I32: Mutex<i32> = Mutex::new(0);
102
103 // Presence of the API below tests how bindings handle functions returning
104 // `void`.
105 #[export_name = "custom_export_name_for_get_global_i32"]
106 pub extern "C" fn set_global_i32_via_extern_c_with_export_name(x: i32) {
107 *G_I32.lock().unwrap() = x;
108 }
109
110 #[no_mangle]
111 pub extern "C" fn get_global_i32_via_extern_c_with_export_name() -> i32 {
112 *G_I32.lock().unwrap()
113 }
Lukasz Anforowiczed17d052022-11-02 12:07:28 -0700114}
Lukasz Anforowiczf04bc522022-11-04 09:19:51 -0700115
Lukasz Anforowiczf0f37dd2023-01-05 11:22:06 -0800116pub mod other_fn_param_tests {
117 pub fn add_i32_via_rust_abi_with_duplicated_param_names(x: i32, y: i32, _: i32, _: i32) -> i32 {
118 x + y
119 }
Lukasz Anforowiczf04bc522022-11-04 09:19:51 -0700120}
Devin Jeanpierred63080a2023-12-20 17:59:22 -0800121
Googler6b395312024-04-22 17:09:02 -0700122pub mod fn_attribute_tests {
123 #[deprecated(since = "1.2.3", note = "★ Deprecated note for add_i32 ★")]
124 pub fn add_i32(x: i32, y: i32) -> i32 {
125 x + y
126 }
127}
128
Devin Jeanpierred63080a2023-12-20 17:59:22 -0800129pub mod unsafe_fn_tests {
130 /// # Safety
131 ///
132 /// This function has no safety requirements - it is only marked as `unsafe`
133 /// to facilitate minimal testing of bindings generated for such functions.
134 pub unsafe fn unsafe_add(x: i32, y: i32) -> i32 {
135 x + y
136 }
137}
Googler208c1ad2024-04-22 15:39:30 -0700138
139// Tests the use of the #[must_use] attribute
140pub mod fn_must_use_tests {
141 #[must_use]
142 pub fn no_msg_add(x: i32, y: i32) -> i32 {
143 x + y
144 }
145
146 #[must_use = "woohoo"]
147 pub fn msg_add(x: i32, y: i32) -> i32 {
148 x + y
149 }
150}