1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
package CType::Function;
use 5.6.0;
use strict;
use warnings;
use CType;
no warnings 'recursion';
our @ISA = qw/CType/;
sub new
{
my $this = shift;
my $class = ref($this) || $this;
my $type = shift;
my $params = shift;
my $attributes = shift;
my $variadic = shift;
my $self = {type => $type,
params => $params,
attributes => $attributes,
variadic => $variadic,
};
bless $self, $class;
$self->process_attributes($attributes);
return $self;
}
sub set_inline
{
my $self = shift;
$self->{inline} = shift;
}
sub layout
{
my $self = shift;
my $accept_incomplete = shift;
my $namespace = shift;
$_->layout(0, $namespace) foreach @{$self->{params}};
}
sub describe
{
my $self = shift;
my $type = $self->{type}->describe;
my @params = map {$_->describe} @{$self->{params}};
if (scalar @params == 0)
{
return "function taking no arguments, returning $type";
}
else
{
return "function taking (" . join(', ', @params) . "), returning $type";
}
}
sub dump_c
{
my $self = shift;
my $skip_cpp = shift;
my $name = shift;
my $str = '';
my $declarator = $name || "";
my @params = map {$_->dump_c($skip_cpp)} @{$self->{params}};
unless (scalar @params)
{
@params = ('void');
}
my $params = join(', ', @params);
if ($self->{type}->capture_declarator)
{
$str .= $self->{type}->dump_c($skip_cpp, "$declarator($params)");
}
else
{
my $type = $self->{type}->dump_c($skip_cpp);
$str .= "$type $declarator($params)";
}
return $str;
}
sub capture_declarator
{
return 1;
}
sub _check_interface
{
my $self = shift;
my $other = shift;
return 'both' unless $other->isa('CType::Function');
my @ret;
push @ret, $self->{type}->check_interface($other->{type});
push @ret, 'both' if scalar @{$self->{params}} != scalar @{$other->{params}};
foreach my $i (0 .. scalar @{$self->{params}} - 1)
{
last if $i >= scalar @{$other->{params}};
push @ret, $self->{params}[$i]->check_interface($other->{params}[$i], 1);
}
return @ret;
}
sub get_refs
{
my $self = shift;
return ($self->{type}->get_refs, map {$_->get_refs} @{$self->{params}});
}
1;
|