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
|
package CParse::Declarator::Function;
use 5.6.0;
use strict;
use warnings;
use CDecl;
use CType::Function;
sub new
{
my $this = shift;
my $class = ref($this) || $this;
my $params = shift;
my $variadic = shift;
my $self = {declarator => undef,
params => $params,
variadic => $variadic,
};
if (scalar @{$self->{params}} == 1
and scalar @{$self->{params}[0]->specifiers} == 1
and $self->{params}[0]->specifiers->[0]->isa('CParse::TypeSpecifier')
and $self->{params}[0]->specifiers->[0]->name eq 'void')
{
# We have precisely one argument, which is just a single
# 'void'. That's really 'no arguments'.
$self->{params} = [];
}
bless $self, $class;
return $self;
}
sub set_declarator
{
my $self = shift;
$self->{declarator} = shift;
}
sub dump_c
{
my $self = shift;
my $declarator = $self->{declarator} ? $self->{declarator}->dump_c : '';
my $params = join(', ', map {$_->dump_c} @{$self->{params}});
if ($self->{variadic})
{
if (length $params)
{
$params .= ", ...";
}
else
{
$params = "...";
}
}
unless (length $params)
{
$params = 'void';
}
if ($self->{declarator} and $self->{declarator}->isa('CParse::Declarator') and $self->{declarator}->pointer)
{
return "($declarator)($params)"
}
else
{
return "$declarator($params)"
}
}
sub get_identifier
{
my $self = shift;
return undef unless $self->{declarator};
return $self->{declarator}->get_identifier;
}
sub get_type
{
my $self = shift;
my $namespace = shift;
my $base_type = shift;
my $attributes = shift;
my @arg_types = map {new CDecl 'param', $_->get_identifier, $_->get_type($namespace)} @{$self->{params}};
my $type = new CType::Function $base_type, \@arg_types, $attributes, $self->{variadic};
if ($self->{declarator})
{
$type = $self->{declarator}->get_type($namespace, $type, []);
}
return $type;
}
1;
|