@@ -25,6 +25,12 @@ macro_rules! public_test_dep {
2525/// platforms need and elsewhere in this library it just looks like normal Rust
2626/// code.
2727///
28+ /// When the weak-intrinsics feature is enabled, all intrinsics functions are
29+ /// marked with #[linkage = "weak"] so that they can be replaced by another
30+ /// implementation at link time. This is particularly useful for mixed Rust/C++
31+ /// binaries that want to use the C++ intrinsics, otherwise linking against the
32+ /// Rust stdlib will replace those from the compiler-rt library.
33+ ///
2834/// This macro is structured to be invoked with a bunch of functions that looks
2935/// like:
3036///
@@ -46,6 +52,10 @@ macro_rules! public_test_dep {
4652///
4753/// A quick overview of attributes supported right now are:
4854///
55+ /// * `weak` - indicates that the function should always be given weak linkage.
56+ /// This attribute must come before other attributes, as the other attributes
57+ /// will generate the final output function and need to have `weak` modify
58+ /// them.
4959/// * `maybe_use_optimized_c_shim` - indicates that the Rust implementation is
5060/// ignored if an optimized C version was compiled.
5161/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and
@@ -57,7 +67,6 @@ macro_rules! public_test_dep {
5767/// it's a normal ABI elsewhere for returning a 128 bit integer.
5868/// * `arm_aeabi_alias` - handles the "aliasing" of various intrinsics on ARM
5969/// their otherwise typical names to other prefixed ones.
60- ///
6170macro_rules! intrinsics {
6271 ( ) => ( ) ;
6372
@@ -89,6 +98,95 @@ macro_rules! intrinsics {
8998
9099 intrinsics!( $( $rest) * ) ;
91100 ) ;
101+ // Same as above but for unsafe.
102+ (
103+ #[ cfg_attr( $e: meta, $( $attr: tt) * ) ]
104+ $( #[ $( $attrs: tt) * ] ) *
105+ pub unsafe extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
106+ $( $body: tt) *
107+ }
108+ $( $rest: tt) *
109+ ) => (
110+ #[ cfg( $e) ]
111+ intrinsics! {
112+ #[ $( $attr) * ]
113+ $( #[ $( $attrs) * ] ) *
114+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
115+ $( $body) *
116+ }
117+ }
118+
119+ #[ cfg( not( $e) ) ]
120+ intrinsics! {
121+ $( #[ $( $attrs) * ] ) *
122+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
123+ $( $body) *
124+ }
125+ }
126+
127+ intrinsics!( $( $rest) * ) ;
128+ ) ;
129+
130+ // Explicit weak linkage gets dropped when weak-intrinsics is on since it
131+ // will be added unconditionally to all intrinsics and would conflict
132+ // otherwise.
133+ (
134+ #[ weak]
135+ $( #[ $( $attr: tt) * ] ) *
136+ pub extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
137+ $( $body: tt) *
138+ }
139+
140+ $( $rest: tt) *
141+ ) => (
142+ #[ cfg( feature = "weak-intrinsics" ) ]
143+ intrinsics! {
144+ $( #[ $( $attr) * ] ) *
145+ pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
146+ $( $body) *
147+ }
148+ }
149+
150+ #[ cfg( not( feature = "weak-intrinsics" ) ) ]
151+ intrinsics! {
152+ $( #[ $( $attr) * ] ) *
153+ #[ linkage = "weak" ]
154+ pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
155+ $( $body) *
156+ }
157+ }
158+
159+ intrinsics!( $( $rest) * ) ;
160+ ) ;
161+ // Same as above but for unsafe.
162+ (
163+ #[ weak]
164+ $( #[ $( $attr: tt) * ] ) *
165+ pub unsafe extern $abi: tt fn $name: ident( $( $argname: ident: $ty: ty) ,* ) $( -> $ret: ty) ? {
166+ $( $body: tt) *
167+ }
168+
169+ $( $rest: tt) *
170+ ) => (
171+ #[ cfg( feature = "weak-intrinsics" ) ]
172+ intrinsics! {
173+ $( #[ $( $attr) * ] ) *
174+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
175+ $( $body) *
176+ }
177+ }
178+
179+ #[ cfg( not( feature = "weak-intrinsics" ) ) ]
180+ intrinsics! {
181+ $( #[ $( $attr) * ] ) *
182+ #[ linkage = "weak" ]
183+ pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
184+ $( $body) *
185+ }
186+ }
187+
188+ intrinsics!( $( $rest) * ) ;
189+ ) ;
92190
93191 // Right now there's a bunch of architecture-optimized intrinsics in the
94192 // stock compiler-rt implementation. Not all of these have been ported over
@@ -112,6 +210,7 @@ macro_rules! intrinsics {
112210 $( $rest: tt) *
113211 ) => (
114212 #[ cfg( $name = "optimized-c" ) ]
213+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
115214 pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
116215 extern $abi {
117216 fn $name( $( $argname: $ty) ,* ) $( -> $ret) ?;
@@ -211,13 +310,15 @@ macro_rules! intrinsics {
211310 ) => (
212311 #[ cfg( all( any( windows, target_os = "uefi" ) , target_arch = "x86_64" ) ) ]
213312 $( #[ $( $attr) * ] ) *
313+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
214314 pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
215315 $( $body) *
216316 }
217317
218318 #[ cfg( all( any( windows, target_os = "uefi" ) , target_arch = "x86_64" ) ) ]
219319 pub mod $name {
220320 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
321+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
221322 pub extern $abi fn $name( $( $argname: $ty) ,* )
222323 -> :: macros:: win64_128bit_abi_hack:: U64x2
223324 {
@@ -258,6 +359,7 @@ macro_rules! intrinsics {
258359 #[ cfg( target_arch = "arm" ) ]
259360 pub mod $name {
260361 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
362+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
261363 pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
262364 super :: $name( $( $argname) ,* )
263365 }
@@ -266,7 +368,7 @@ macro_rules! intrinsics {
266368 #[ cfg( target_arch = "arm" ) ]
267369 pub mod $alias {
268370 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
269- #[ cfg_attr( all( not( windows) , not( target_vendor="apple" ) ) , linkage = "weak" ) ]
371+ #[ cfg_attr( any ( all( not( windows) , not( target_vendor="apple" ) , feature = "weak-intrinsics ") ) , linkage = "weak" ) ]
270372 pub extern "aapcs" fn $alias( $( $argname: $ty) ,* ) $( -> $ret) ? {
271373 super :: $name( $( $argname) ,* )
272374 }
@@ -302,6 +404,7 @@ macro_rules! intrinsics {
302404 pub mod $name {
303405 $( #[ $( $attr) * ] ) *
304406 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
407+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
305408 pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
306409 super :: $name( $( $argname) ,* )
307410 }
@@ -325,6 +428,7 @@ macro_rules! intrinsics {
325428 #[ naked]
326429 $( #[ $( $attr) * ] ) *
327430 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
431+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
328432 pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
329433 $( $body) *
330434 }
@@ -391,6 +495,7 @@ macro_rules! intrinsics {
391495 pub mod $name {
392496 $( #[ $( $attr) * ] ) *
393497 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
498+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
394499 pub extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
395500 super :: $name( $( $argname) ,* )
396501 }
@@ -416,6 +521,7 @@ macro_rules! intrinsics {
416521 pub mod $name {
417522 $( #[ $( $attr) * ] ) *
418523 #[ cfg_attr( not( feature = "mangled-names" ) , no_mangle) ]
524+ #[ cfg_attr( feature = "weak-intrinsics" , linkage = "weak" ) ]
419525 pub unsafe extern $abi fn $name( $( $argname: $ty) ,* ) $( -> $ret) ? {
420526 super :: $name( $( $argname) ,* )
421527 }
0 commit comments