Skip to content

Commit

Permalink
Use a token stream instead of a re-imported macro to fix #241
Browse files Browse the repository at this point in the history
  • Loading branch information
mmastrac committed Oct 19, 2022
1 parent cd0fd89 commit 27656d9
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions ctor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,25 @@ extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;
use proc_macro::{TokenStream};

/// Attributes required to mark a function as a constructor. This may be exposed in the future if we determine
/// it to be stable.
#[doc(hidden)]
#[proc_macro_attribute]
pub fn __ctor_internal_decorator_attributes(
_attribute: TokenStream,
function: TokenStream,
) -> TokenStream {
let mut attrs: TokenStream = quote!(
#[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".init_array")]
#[cfg_attr(target_os = "freebsd", link_section = ".init_array")]
#[cfg_attr(target_os = "netbsd", link_section = ".init_array")]
#[cfg_attr(target_os = "openbsd", link_section = ".init_array")]
#[cfg_attr(target_os = "dragonfly", link_section = ".init_array")]
#[cfg_attr(target_os = "illumos", link_section = ".init_array")]
#[cfg_attr(target_os = "haiku", link_section = ".init_array")]
#[cfg_attr(any(target_os = "macos", target_os = "ios"), link_section = "__DATA,__mod_init_func")]
#[cfg_attr(windows, link_section = ".CRT$XCU")]
).into();
attrs.extend(function);
attrs
macro_rules! ctor_attributes {
() => {
quote!(
#[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".init_array")]
#[cfg_attr(target_os = "freebsd", link_section = ".init_array")]
#[cfg_attr(target_os = "netbsd", link_section = ".init_array")]
#[cfg_attr(target_os = "openbsd", link_section = ".init_array")]
#[cfg_attr(target_os = "dragonfly", link_section = ".init_array")]
#[cfg_attr(target_os = "illumos", link_section = ".init_array")]
#[cfg_attr(target_os = "haiku", link_section = ".init_array")]
#[cfg_attr(any(target_os = "macos", target_os = "ios"), link_section = "__DATA,__mod_init_func")]
#[cfg_attr(windows, link_section = ".CRT$XCU")]
)
};
}

/// Marks a function or static variable as a library/executable constructor.
Expand Down Expand Up @@ -172,6 +168,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
syn::parse_str::<syn::Ident>(format!("{}___rust_ctor___ctor", ident).as_ref())
.expect("Unable to create identifier");

let tokens = ctor_attributes!();
let output = quote!(
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "illumos", target_os = "haiku", target_os = "macos", target_os = "ios", windows)))]
compile_error!("#[ctor] is not supported on the current target");
Expand All @@ -182,7 +179,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
#[used]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[ctor::__ctor_internal_decorator_attributes]
#tokens
static #ctor_ident
:
unsafe extern "C" fn() =
Expand Down Expand Up @@ -228,6 +225,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
syn::parse_str::<syn::Ident>(format!("{}___rust_ctor___storage", ident).as_ref())
.expect("Unable to create identifier");

let tokens = ctor_attributes!();
let output = quote!(
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "illumos", target_os = "haiku", target_os = "macos", target_os = "ios", windows)))]
compile_error!("#[ctor] is not supported on the current target");
Expand Down Expand Up @@ -257,7 +255,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {

#[used]
#[allow(non_upper_case_globals)]
#[ctor::__ctor_internal_decorator_attributes]
#tokens
static #ctor_ident
:
unsafe extern "C" fn() = {
Expand Down Expand Up @@ -321,6 +319,7 @@ pub fn dtor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
let dtor_ident = syn::parse_str::<syn::Ident>(format!("{}___rust_dtor___dtor", ident).as_ref())
.expect("Unable to create identifier");

let tokens = ctor_attributes!();
let output = quote!(
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "illumos", target_os = "haiku", target_os = "macos", target_os = "ios", windows)))]
compile_error!("#[dtor] is not supported on the current target");
Expand Down Expand Up @@ -355,7 +354,7 @@ pub fn dtor(_attribute: TokenStream, function: TokenStream) -> TokenStream {

#[used]
#[allow(non_upper_case_globals)]
#[ctor::__ctor_internal_decorator_attributes]
#tokens
static __dtor_export
:
unsafe extern "C" fn() =
Expand Down

0 comments on commit 27656d9

Please sign in to comment.