Skip to content

Commit e561b6e

Browse files
committed
ParseXS: split out C++ class and const
An XSUB can be a C++ method if its name includes a class; it can also have an optional 'const' postfix modifier; e.g.: int X::Y::foo(...) const Before this commit, both the class of the XSUB and the const modifier were combined into a single string that was used in various places, suvh as to declare the type of the THIS variable, e.g. const X__Y THIS = ...; This commit splits the state into two separate fields during parsing, then these two fields are used later during code generation to Do the Right Thing. So before, the XSUB declaration above would, at parse time, have created an xsub_decl node which looked like: $xsub->{xsub_decl}{class} = 'const X::Y'; and which now looks like: $xsub->{xsub_decl}{class} = 'X::Y'; $xsub->{xsub_decl}{is_const} = TRUE; The three tests added by this commit all failed before this fix.
1 parent 43263bc commit e561b6e

File tree

2 files changed

+53
-11
lines changed

2 files changed

+53
-11
lines changed

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,12 @@ package ExtUtils::ParseXS::Node::xsub_decl;
836836
BEGIN { $build_subclass->(
837837
'return_type', # ReturnType object representing e.g "NO_OUTPUT char *"
838838
'params', # Params object representing e.g "a, int b, c=0"
839-
'class', # Str: the 'const Foo::Bar' part of the xsub's name
839+
'class', # Str: the 'Foo::Bar' part of an XSUB's name;
840+
# - if defined, this is a C++ method
840841
'name', # Str: the 'foo' XSUB name
841842
'full_perl_name', # Str: the 'Foo::Bar::foo' perl XSUB name
842843
'full_C_name', # Str: the 'Foo__Bar__foo' C XSUB name
844+
'is_const', # Bool: declaration had postfix C++ 'const' modifier
843845
)};
844846

845847

@@ -879,14 +881,9 @@ sub parse {
879881

880882
my ($class, $name, $params_text, $const) = ($1, $2, $3, $4);
881883

882-
if (defined $const) {
883-
if (defined $class) {
884-
$class = "$const $class";
885-
}
886-
else {
887-
$pxs->blurt("const modifier only allowed on XSUBs which are C++ methods");
888-
undef $const;
889-
}
884+
if (defined $const and !defined $class) {
885+
$pxs->blurt("const modifier only allowed on XSUBs which are C++ methods");
886+
undef $const;
890887
}
891888

892889
if ($return_type->{static} and !defined $class)
@@ -906,6 +903,7 @@ sub parse {
906903
if $ExtUtils::ParseXS::Is_VMS;
907904

908905
$self->{class} = $class;
906+
$self->{is_const} = defined $const;
909907
$self->{name} = $name;
910908
$self->{full_perl_name} = $full_pname;
911909
$self->{full_C_name} = $full_cname;
@@ -919,7 +917,8 @@ sub parse {
919917
# we should have:
920918
#
921919
# $self->{return_type} an object holding "int"
922-
# $self->{class} "const Some::Class"
920+
# $self->{class} "Some::Class"
921+
# $self->{is_const} TRUE
923922
# $self->{name} "foo_bar"
924923
# $self->{full_perl_name} "BAR::BAZ::bar"
925924
# $self->{full_C_name} "BAR__BAZ_bar"
@@ -2439,7 +2438,8 @@ sub parse {
24392438
or $xsub->{decl}{name} eq 'new'
24402439
)
24412440
? ('CLASS', "char *")
2442-
: ('THIS', "$xsub->{decl}{class} *");
2441+
: ('THIS', ($xsub->{decl}{is_const} ? "const " : "")
2442+
. "$xsub->{decl}{class} *");
24432443

24442444
my ExtUtils::ParseXS::Node::Param $param
24452445
= ExtUtils::ParseXS::Node::Param->new( {

dist/ExtUtils-ParseXS/t/001-basic.t

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,48 @@ EOF
12121212
"got expected err" ],
12131213
],
12141214

1215+
# autocall variants with const
1216+
1217+
[
1218+
"C++: static const",
1219+
[ Q(<<'EOF') ],
1220+
|static int
1221+
|X::Y::foo() const
1222+
EOF
1223+
[ 0, 0, qr/\QRETVAL = X::Y::foo()/,
1224+
"autocall doesn't have const" ],
1225+
],
1226+
1227+
[
1228+
"C++: static new const",
1229+
[ Q(<<'EOF') ],
1230+
|static int
1231+
|X::Y::new() const
1232+
EOF
1233+
[ 0, 0, qr/\QRETVAL = X::Y()/,
1234+
"autocall doesn't have const" ],
1235+
],
1236+
1237+
[
1238+
"C++: const",
1239+
[ Q(<<'EOF') ],
1240+
|int
1241+
|X::Y::foo() const
1242+
EOF
1243+
[ 0, 0, qr/\QRETVAL = THIS->foo()/,
1244+
"autocall doesn't have const" ],
1245+
],
1246+
1247+
[
1248+
"C++: new const",
1249+
[ Q(<<'EOF') ],
1250+
|int
1251+
|X::Y::new() const
1252+
EOF
1253+
[ 0, 0, qr/\QRETVAL = new X::Y()/,
1254+
"autocall doesn't have const" ],
1255+
],
1256+
12151257
[
12161258
"",
12171259
[

0 commit comments

Comments
 (0)