@@ -370,7 +370,7 @@ impl Passes {
370370 }
371371}
372372
373- /// Declare a macro that will define all CodegenOptions fields and parsers all
373+ /// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
374374/// at once. The goal of this macro is to define an interface that can be
375375/// programmatically used by the option parser in order to initialize the struct
376376/// without hardcoding field names all over the place.
@@ -380,23 +380,67 @@ impl Passes {
380380/// cgsetters module which is a bunch of generated code to parse an option into
381381/// its respective field in the struct. There are a few hand-written parsers for
382382/// parsing specific types of values in this module.
383- macro_rules! cgoptions {
384- ( $( $opt: ident : $t: ty = ( $init: expr, $parse: ident, $desc: expr) ) ,* , ) =>
383+ macro_rules! options {
384+ ( $struct_name: ident, $setter_name: ident, $defaultfn: ident,
385+ $buildfn: ident, $prefix: expr, $outputname: expr,
386+ $stat: ident, $mod_desc: ident, $mod_set: ident,
387+ $( $opt: ident : $t: ty = ( $init: expr, $parse: ident, $desc: expr) ) ,* , ) =>
385388(
386389 #[ derive( Clone ) ]
387- pub struct CodegenOptions { $( pub $opt: $t) ,* }
390+ pub struct $struct_name { $( pub $opt: $t) ,* }
388391
389- pub fn basic_codegen_options ( ) -> CodegenOptions {
390- CodegenOptions { $( $opt: $init) ,* }
392+ pub fn $defaultfn ( ) -> $struct_name {
393+ $struct_name { $( $opt: $init) ,* }
391394 }
392395
393- pub type CodegenSetter = fn ( & mut CodegenOptions , v: Option <& str >) -> bool ;
394- pub const CG_OPTIONS : & ' static [ ( & ' static str , CodegenSetter ,
396+ pub fn $buildfn( matches: & getopts:: Matches ) -> $struct_name
397+ {
398+ let mut op = $defaultfn( ) ;
399+ for option in matches. opt_strs( $prefix) . into_iter( ) {
400+ let mut iter = option. splitn( 1 , '=' ) ;
401+ let key = iter. next( ) . unwrap( ) ;
402+ let value = iter. next( ) ;
403+ let option_to_lookup = key. replace( "-" , "_" ) ;
404+ let mut found = false ;
405+ for & ( candidate, setter, opt_type_desc, _) in $stat. iter( ) {
406+ if option_to_lookup != candidate { continue }
407+ if !setter( & mut op, value) {
408+ match ( value, opt_type_desc) {
409+ ( Some ( ..) , None ) => {
410+ early_error( format!( "{} option `{}` takes no \
411+ value", $outputname, key) [ ] )
412+ }
413+ ( None , Some ( type_desc) ) => {
414+ early_error( format!( "{0} option `{1}` requires \
415+ {2} ({3} {1}=<value>)",
416+ $outputname, key, type_desc, $prefix) [ ] )
417+ }
418+ ( Some ( value) , Some ( type_desc) ) => {
419+ early_error( format!( "incorrect value `{}` for {} \
420+ option `{}` - {} was expected",
421+ value, $outputname, key, type_desc) [ ] )
422+ }
423+ ( None , None ) => unreachable!( )
424+ }
425+ }
426+ found = true ;
427+ break ;
428+ }
429+ if !found {
430+ early_error( format!( "unknown codegen option: `{}`" ,
431+ key) [ ] ) ;
432+ }
433+ }
434+ return op;
435+ }
436+
437+ pub type $setter_name = fn ( & mut $struct_name, v: Option <& str >) -> bool ;
438+ pub const $stat: & ' static [ ( & ' static str , $setter_name,
395439 Option <& ' static str >, & ' static str ) ] =
396- & [ $( ( stringify!( $opt) , cgsetters :: $opt, cg_type_descs :: $parse, $desc) ) ,* ] ;
440+ & [ $( ( stringify!( $opt) , $mod_set :: $opt, $mod_desc :: $parse, $desc) ) ,* ] ;
397441
398442 #[ allow( non_upper_case_globals) ]
399- mod cg_type_descs {
443+ mod $mod_desc {
400444 pub const parse_bool: Option <& ' static str > = None ;
401445 pub const parse_opt_bool: Option <& ' static str > = None ;
402446 pub const parse_string: Option <& ' static str > = Some ( "a string" ) ;
@@ -410,11 +454,11 @@ macro_rules! cgoptions {
410454 Some ( "a number" ) ;
411455 }
412456
413- mod cgsetters {
414- use super :: { CodegenOptions , Passes , SomePasses , AllPasses } ;
457+ mod $mod_set {
458+ use super :: { $struct_name , Passes , SomePasses , AllPasses } ;
415459
416460 $(
417- pub fn $opt( cg: & mut CodegenOptions , v: Option <& str >) -> bool {
461+ pub fn $opt( cg: & mut $struct_name , v: Option <& str >) -> bool {
418462 $parse( & mut cg. $opt, v)
419463 }
420464 ) *
@@ -506,7 +550,9 @@ macro_rules! cgoptions {
506550 }
507551) }
508552
509- cgoptions ! {
553+ options ! { CodegenOptions , CodegenSetter , basic_codegen_options,
554+ build_codegen_options, "C" , "codegen" ,
555+ CG_OPTIONS , cg_type_desc, cgsetters,
510556 ar: Option <String > = ( None , parse_opt_string,
511557 "tool to assemble archives with" ) ,
512558 linker: Option <String > = ( None , parse_opt_string,
@@ -562,47 +608,6 @@ cgoptions! {
562608 "Optimize with possible levels 0-3" ) ,
563609}
564610
565- pub fn build_codegen_options ( matches : & getopts:: Matches ) -> CodegenOptions
566- {
567- let mut cg = basic_codegen_options ( ) ;
568- for option in matches. opt_strs ( "C" ) . into_iter ( ) {
569- let mut iter = option. splitn ( 1 , '=' ) ;
570- let key = iter. next ( ) . unwrap ( ) ;
571- let value = iter. next ( ) ;
572- let option_to_lookup = key. replace ( "-" , "_" ) ;
573- let mut found = false ;
574- for & ( candidate, setter, opt_type_desc, _) in CG_OPTIONS . iter ( ) {
575- if option_to_lookup != candidate { continue }
576- if !setter ( & mut cg, value) {
577- match ( value, opt_type_desc) {
578- ( Some ( ..) , None ) => {
579- early_error ( & format ! ( "codegen option `{}` takes no \
580- value", key) [ ] )
581- }
582- ( None , Some ( type_desc) ) => {
583- early_error ( & format ! ( "codegen option `{0}` requires \
584- {1} (-C {0}=<value>)",
585- key, type_desc) [ ] )
586- }
587- ( Some ( value) , Some ( type_desc) ) => {
588- early_error ( & format ! ( "incorrect value `{}` for codegen \
589- option `{}` - {} was expected",
590- value, key, type_desc) [ ] )
591- }
592- ( None , None ) => unreachable ! ( )
593- }
594- }
595- found = true ;
596- break ;
597- }
598- if !found {
599- early_error ( & format ! ( "unknown codegen option: `{}`" ,
600- key) [ ] ) ;
601- }
602- }
603- return cg;
604- }
605-
606611pub fn default_lib_output ( ) -> CrateType {
607612 CrateTypeRlib
608613}
0 commit comments