Skip to content
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

Target modifiers (special marked options) are recorded in metainfo #133138

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Top level option group enums are generated by macro
  • Loading branch information
azhogin committed Dec 22, 2024
commit a084519cd11d698d2bc564be362487500f4ec84a
134 changes: 94 additions & 40 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,19 @@ macro_rules! tmod_push {

macro_rules! gather_tmods {
($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
[SUBSTRUCT], [TMOD]) => {
[SUBSTRUCT], [TARGET_MODIFIER]) => {
compile_error!("SUBSTRUCT can't be target modifier");
};
($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
[UNTRACKED], [TMOD]) => {
[UNTRACKED], [TARGET_MODIFIER]) => {
tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
};
($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
[TRACKED], [TMOD]) => {
[TRACKED], [TARGET_MODIFIER]) => {
tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
};
($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
[TRACKED_NO_CRATE_HASH], [TMOD]) => {
[TRACKED_NO_CRATE_HASH], [TARGET_MODIFIER]) => {
tmod_push!($struct_name, $tmod_enum_name, $opt_name, $mods, $tmod_vals)
};
($struct_name:ident, $tmod_enum_name:ident, $opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr,
Expand All @@ -130,31 +130,101 @@ macro_rules! gather_tmods {
}

macro_rules! gather_tmods_top_level {
($_opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [SUBSTRUCT], [TMOD]) => {
compile_error!("SUBSTRUCT can't be target modifier");
($_opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [SUBSTRUCT $substruct_enum:ident]) => {
$opt_expr.gather_target_modifiers($mods, $tmod_vals);
};
($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [UNTRACKED], [TMOD]) => {
($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [$non_substruct:ident TARGET_MODIFIER]) => {
compile_error!("Top level option can't be target modifier");
};
($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [TRACKED], [TMOD]) => {
compile_error!("Top level option can't be target modifier");
($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [$non_substruct:ident]) => {};
}

// Macro for generating OptionsTargetsModifiers top-level enum with impl.
// Will generate something like:
// pub enum OptionsTargetModifiers {
// CodegenOptions(CodegenOptionsTargetModifiers),
// UnstableOptions(UnstableOptionsTargetModifiers),
// }
// impl OptionsTargetModifiers {
// pub fn reparse(&self, user_value: &str) -> ExtendedTargetModifierInfo {
// match self {
// Self::CodegenOptions(v) => v.reparse(user_value),
// Self::UnstableOptions(v) => v.reparse(user_value),
// }
// }
// }

macro_rules! top_level_tmod_enum {
($( {$($optinfo:tt)*} ),* $(,)*) => {
top_level_tmod_enum! { @parse {}, (user_value){}; $($($optinfo)*|)* }
};
($opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [TRACKED_NO_CRATE_HASH], [TMOD]) => {
compile_error!("Top level option can't be target modifier");
// Termination
(
@parse
{$($eout:tt)*},
($user_value:ident){$($pout:tt)*};
) => {
#[allow(non_camel_case_types)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
pub enum OptionsTargetModifiers {
$($eout)*
}
impl OptionsTargetModifiers {
#[allow(unused_variables)]
pub fn reparse(&self, $user_value: &str) -> ExtendedTargetModifierInfo {
#[allow(unreachable_patterns)]
match self {
$($pout)*
_ => panic!("unknown target modifier option: {:?}", *self)
}
}
}
};
($_opt_name:ident, $opt_expr:expr, $mods:expr, $tmod_vals:expr, [SUBSTRUCT], []) => {
$opt_expr.gather_target_modifiers($mods, $tmod_vals);
// Adding SUBSTRUCT option group into $eout
(
@parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
[SUBSTRUCT $substruct_enum:ident $variant:ident] |
$($tail:tt)*
) => {
top_level_tmod_enum! {
@parse
{
$($eout)*
$variant($substruct_enum),
},
($puser_value){
$($pout)*
Self::$variant(v) => v.reparse($puser_value),
};
$($tail)*
}
};
// Skipping non-target-modifier and non-substruct
(
@parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
[$non_substruct:ident] |
$($tail:tt)*
) => {
top_level_tmod_enum! {
@parse
{
$($eout)*
},
($puser_value){
$($pout)*
};
$($tail)*
}
};
($_opt_name:ident, $_opt_expr:expr, $_mods:expr, $_tmod_vals:expr, [UNTRACKED], []) => {{}};
($_opt_name:ident, $_opt_expr:expr, $_mods:expr, $_tmod_vals:expr, [TRACKED], []) => {{}};
($_opt_name:ident, $_opt_expr:expr, $_mods:expr, $_tmod_vals:expr, [TRACKED_NO_CRATE_HASH], []) => {{}};
}

macro_rules! top_level_options {
( $( #[$top_level_attr:meta] )* pub struct Options { $(
$( #[$attr:meta] )*
$opt:ident : $t:ty [$dep_tracking_marker:ident $( $tmod:ident )?],
$opt:ident : $t:ty [$dep_tracking_marker:ident $( $tmod:ident $variant:ident )?],
)* } ) => (
top_level_tmod_enum!( {$([$dep_tracking_marker $($tmod $variant),*])|*} );

#[derive(Clone)]
$( #[$top_level_attr] )*
pub struct Options {
Expand Down Expand Up @@ -196,7 +266,7 @@ macro_rules! top_level_options {
$({
gather_tmods_top_level!($opt,
&self.$opt, &mut mods, &self.target_modifiers,
[$dep_tracking_marker], [$($tmod),*]);
[$dep_tracking_marker $($tmod),*]);
})*
mods.sort_by(|a, b| a.opt.cmp(&b.opt));
mods
Expand All @@ -205,22 +275,6 @@ macro_rules! top_level_options {
);
}

/// Update if new options group will be added
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
pub enum OptionsTargetModifiers {
CodegenOptions(CodegenOptionsTargetModifiers),
UnstableOptions(UnstableOptionsTargetModifiers),
}

impl OptionsTargetModifiers {
pub fn reparse(&self, user_value: &str) -> ExtendedTargetModifierInfo {
match self {
Self::CodegenOptions(v) => v.reparse(user_value),
Self::UnstableOptions(v) => v.reparse(user_value),
}
}
}

top_level_options!(
/// The top-level command-line options struct.
///
Expand Down Expand Up @@ -284,9 +338,9 @@ top_level_options!(
#[rustc_lint_opt_deny_field_access("should only be used via `Config::hash_untracked_state`")]
untracked_state_hash: Hash64 [TRACKED_NO_CRATE_HASH],

unstable_opts: UnstableOptions [SUBSTRUCT],
unstable_opts: UnstableOptions [SUBSTRUCT UnstableOptionsTargetModifiers UnstableOptions],
prints: Vec<PrintRequest> [UNTRACKED],
cg: CodegenOptions [SUBSTRUCT],
cg: CodegenOptions [SUBSTRUCT CodegenOptionsTargetModifiers CodegenOptions],
externs: Externs [UNTRACKED],
crate_name: Option<String> [TRACKED],
/// Indicates how the compiler should treat unstable features.
Expand Down Expand Up @@ -385,7 +439,7 @@ macro_rules! tmod_enum {
(
$tmod_enum_name:ident, $prefix:expr,
@parse {$($eout:tt)*}, ($puser_value:ident){$($pout:tt)*};
$opt:ident, $parse:ident, $t:ty, [TMOD] |
$opt:ident, $parse:ident, $t:ty, [TARGET_MODIFIER] |
$($tail:tt)*
) => {
tmod_enum! {
Expand Down Expand Up @@ -444,7 +498,7 @@ macro_rules! options {
$($( #[$attr:meta] )* $opt:ident : $t:ty = (
$init:expr,
$parse:ident,
[$dep_tracking_marker:ident $( $tmod:ident )*],
[$dep_tracking_marker:ident $( $tmod:ident )?],
$desc:expr)
),* ,) =>
(
Expand Down Expand Up @@ -2221,10 +2275,10 @@ options! {
"enable queries of the dependency graph for regression testing (default: no)"),
randomize_layout: bool = (false, parse_bool, [TRACKED],
"randomize the layout of types (default: no)"),
reg_struct_return: bool = (false, parse_bool, [TRACKED TMOD],
reg_struct_return: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
"On x86-32 targets, it overrides the default ABI to return small structs in registers.
It is UNSOUND to link together crates that use different values for this flag!"),
regparm: Option<u32> = (None, parse_opt_number, [TRACKED TMOD],
regparm: Option<u32> = (None, parse_opt_number, [TRACKED TARGET_MODIFIER],
"On x86-32 targets, setting this to N causes the compiler to pass N arguments \
in registers EAX, EDX, and ECX instead of on the stack for\
\"C\", \"cdecl\", and \"stdcall\" fn.\
Expand Down
Loading