@@ -2,7 +2,7 @@ package ExtUtils::ParseXS::Node;
22use strict;
33use warnings;
44
5- our $VERSION = ' 3.59 ' ;
5+ our $VERSION = ' 3.60 ' ;
66
77=head1 NAME
88
593593 | dXSI32;
594594EOF
595595
596- print ExtUtils::ParseXS::Q(<<"EOF" ) if $self -> {seen_INTERFACE };
597- | dXSFUNCTION($self ->{decl}{return_type}{type});
596+ if ($self -> {seen_INTERFACE }) {
597+ my $type = $self -> {decl }{return_type }{type };
598+ $type =~ tr / :/ _/
599+ unless $pxs -> {config_RetainCplusplusHierarchicalTypes };
600+ print ExtUtils::ParseXS::Q(<<"EOF" ) if $self -> {seen_INTERFACE };
601+ | dXSFUNCTION($type );
598602EOF
603+ }
599604
600605
601606 {
@@ -2564,14 +2569,18 @@ sub usage_string {
25642569
25652570# $self->C_func_signature():
25662571#
2567- # return a string containing the arguments to pass to an autocall C
2568- # function, e.g. 'a, &b, c'.
2572+ # return two arrays
2573+ # the first contains the arguments to pass to an autocall C
2574+ # function, e.g. ['a', '&b', 'c'];
2575+ # the second contains the types of those args, for use in declaring
2576+ # a function pointer type, e.g. ['int', 'char*', 'long'].
25692577
25702578sub C_func_signature {
25712579 my __PACKAGE__ $self = shift ;
25722580 my ExtUtils::ParseXS $pxs = shift ;
25732581
25742582 my @args ;
2583+ my @types ;
25752584 for my $param (@{$self -> {kids }}) {
25762585 next if $param -> {is_synthetic } # THIS/CLASS/RETVAL
25772586 # if a synthetic RETVAL has acquired an arg_num, then
@@ -2581,6 +2590,7 @@ sub C_func_signature {
25812590
25822591 if ($param -> {is_length }) {
25832592 push @args , " XSauto_length_of_$param ->{len_name}" ;
2593+ push @types , $param -> {type };
25842594 next ;
25852595 }
25862596
@@ -2601,9 +2611,11 @@ sub C_func_signature {
26012611 my $a = $param -> {var };
26022612 $a = " &$a " if $param -> {is_addr } or $io =~ / OUT/ ;
26032613 push @args , $a ;
2614+ my $t = $param -> {type };
2615+ push @types , defined $t ? $t : ' void*' ;
26042616 }
26052617
2606- return join ( " , " , @args ) ;
2618+ return \ @args , \ @types ;
26072619}
26082620
26092621
@@ -3320,7 +3332,8 @@ package ExtUtils::ParseXS::Node::autocall;
33203332# name
33213333
33223334BEGIN { $build_subclass -> (
3323- ' args' , # Str: text to use for auto function call arguments
3335+ ' args' , # Str: text to use for auto function call arguments
3336+ ' types' , # Str: text to use for auto function type declaration
33243337)};
33253338
33263339
@@ -3335,10 +3348,35 @@ sub parse {
33353348 $xbody -> {seen_autocall } = 1;
33363349
33373350 my $ioparams = $xbody -> {ioparams };
3338- my $args = $ioparams -> {auto_function_sig_override }; # C_ARGS
3339- $args = $ioparams -> C_func_signature($pxs )
3340- unless defined $args ;
3341- $self -> {args } = $args ;
3351+ my ($args , $types );
3352+ $args = $ioparams -> {auto_function_sig_override }; # C_ARGS
3353+ if (defined $args ) {
3354+ # Try to determine the C_ARGS types; for example, with
3355+ #
3356+ # foo(short s, int i, long l)
3357+ # C_ARGS: s, l
3358+ #
3359+ # set $types to ['short', 'long']. May give the wrong results if
3360+ # C_ARGS isn't just a simple list of parameter names
3361+ for my $var (split /,/, $args ) {
3362+ $var =~ s / ^\s +// ;
3363+ $var =~ s /\s +$// ;
3364+ my $param = $ioparams -> {names }{$var };
3365+ # 'void*' is a desperate guess if no such parameter
3366+ push @$types , ($param && defined $param -> {type })
3367+ ? $param -> {type } : ' void*' ;
3368+ }
3369+ $self -> {args } = $args ;
3370+ }
3371+ else {
3372+ ($args , $types ) = $ioparams -> C_func_signature($pxs );
3373+ $self -> {args } = join ' , ' , @$args ;
3374+ }
3375+
3376+ unless ($pxs -> {config_RetainCplusplusHierarchicalTypes }) {
3377+ s / :/ _/ g for @$types ;
3378+ }
3379+ $self -> {types } = join ' , ' , @$types ;
33423380
33433381 1;
33443382}
@@ -3370,7 +3408,8 @@ sub as_code {
33703408
33713409 print " \n\t " ;
33723410
3373- if ($xsub -> {decl }{return_type }{type } ne " void" ) {
3411+ my $ret_type = $xsub -> {decl }{return_type }{type };
3412+ if ($ret_type ne " void" ) {
33743413 print " RETVAL = " ;
33753414 }
33763415
@@ -3399,9 +3438,13 @@ sub as_code {
33993438 $name =~ s / ^\Q $strip//
34003439 if defined $strip ;
34013440
3402- $name = ' XSFUNCTION'
3403- if $xsub -> {seen_INTERFACE }
3404- or $xsub -> {seen_INTERFACE_MACRO };
3441+ if ( $xsub -> {seen_INTERFACE }
3442+ or $xsub -> {seen_INTERFACE_MACRO })
3443+ {
3444+ $ret_type =~ s / :/ _/ g
3445+ unless $pxs -> {config_RetainCplusplusHierarchicalTypes };
3446+ $name = " (($ret_type (*)($self ->{types}))(XSFUNCTION))" ;
3447+ }
34053448
34063449 print " $name ($self ->{args});\n " ;
34073450
@@ -3724,8 +3767,11 @@ sub as_code {
37243767 my $macro = $xsub -> {interface_macro };
37253768 $macro = ' XSINTERFACE_FUNC' unless defined $macro ;
37263769
3770+ my $type = $xsub -> {decl }{return_type }{type };
3771+ $type =~ tr / :/ _/
3772+ unless $pxs -> {config_RetainCplusplusHierarchicalTypes };
37273773 print <<"EOF" ;
3728- XSFUNCTION = $macro ($xsub ->{decl}{return_type}{ type} ,cv,XSANY.any_dptr);
3774+ XSFUNCTION = $macro ($type ,cv,XSANY.any_dptr);
37293775EOF
37303776}
37313777
0 commit comments