From 7e8eea4a595d558087060189c97b3a7879d6e696 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 11 Sep 2024 15:24:58 +1200 Subject: [PATCH] [perl] Fix C++11 enum class wrapping with -const Fixes #630 --- CHANGES.current | 4 ++++ .../cpp11_strongly_typed_enumerations.i | 11 +++++++++ ...1_strongly_typed_enumerations_perl_const.i | 3 +++ Examples/test-suite/perl5/Makefile.in | 5 +++- ...gly_typed_enumerations_perl_const_runme.pl | 8 +++++++ ...cpp11_strongly_typed_enumerations_runme.pl | 4 +++- Source/Modules/perl5.cxx | 23 +++++++++++++++---- 7 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 Examples/test-suite/cpp11_strongly_typed_enumerations_perl_const.i create mode 100644 Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_perl_const_runme.pl diff --git a/CHANGES.current b/CHANGES.current index 97b779e64..4f7f9eae3 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.3.0 (in progress) =========================== +2024-09-11: olly + [Perl] #630 Fix wrapping of C++11 enum class when -const command line + option is specified. + 2024-09-07: wsfulton #2875 Fix swig-4.1.0 regression using the %interface family of macros for multiple inheritance and common bases. diff --git a/Examples/test-suite/cpp11_strongly_typed_enumerations.i b/Examples/test-suite/cpp11_strongly_typed_enumerations.i index d08f077da..ce1af4b4f 100644 --- a/Examples/test-suite/cpp11_strongly_typed_enumerations.i +++ b/Examples/test-suite/cpp11_strongly_typed_enumerations.i @@ -263,3 +263,14 @@ private: Val2 = 1172, }; %} + +// Test handling of %rename of enum class and an enumerator. +%rename(Enum18) QEnum18; +%rename(Val1) QVal1; +%inline %{ + enum class QEnum18 + { + QVal1 = 1181, + Val2 = 1182, + }; +%} diff --git a/Examples/test-suite/cpp11_strongly_typed_enumerations_perl_const.i b/Examples/test-suite/cpp11_strongly_typed_enumerations_perl_const.i new file mode 100644 index 000000000..6b4004f13 --- /dev/null +++ b/Examples/test-suite/cpp11_strongly_typed_enumerations_perl_const.i @@ -0,0 +1,3 @@ +%module cpp11_strongly_typed_enumerations_perl_const + +%include "cpp11_strongly_typed_enumerations.i" diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in index 688b985ac..43c30ed15 100644 --- a/Examples/test-suite/perl5/Makefile.in +++ b/Examples/test-suite/perl5/Makefile.in @@ -23,6 +23,9 @@ CPP_TEST_CASES += \ memberin1 \ director_nestedmodule \ +CPP11_TEST_CASES += \ + cpp11_strongly_typed_enumerations_perl_const + C_TEST_CASES += \ li_cstring \ li_cdata_carrays \ @@ -34,7 +37,7 @@ include $(srcdir)/../common.mk # none! # Custom tests - tests with additional commandline options -# none! +cpp11_strongly_typed_enumerations_perl_const.cpptest: SWIGOPT += -const # Rules for the different types of tests %.cpptest: diff --git a/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_perl_const_runme.pl b/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_perl_const_runme.pl new file mode 100644 index 000000000..0a8ccdc1d --- /dev/null +++ b/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_perl_const_runme.pl @@ -0,0 +1,8 @@ +use strict; +use warnings; +use Test::More tests => 4; +BEGIN { use_ok('cpp11_strongly_typed_enumerations_perl_const') } +require_ok('cpp11_strongly_typed_enumerations_perl_const'); + +is(cpp11_strongly_typed_enumerations_perl_const::Enum18::Val1, 1181); +is(cpp11_strongly_typed_enumerations_perl_const::Enum18::Val2, 1182); diff --git a/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_runme.pl b/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_runme.pl index db19bbfa6..5d3bd5220 100644 --- a/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_runme.pl +++ b/Examples/test-suite/perl5/cpp11_strongly_typed_enumerations_runme.pl @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 78; +use Test::More tests => 80; BEGIN { use_ok('cpp11_strongly_typed_enumerations') } require_ok('cpp11_strongly_typed_enumerations'); @@ -166,3 +166,5 @@ enumCheck(cpp11_strongly_typed_enumerations::globalTest1($cpp11_strongly_typed_e enumCheck(cpp11_strongly_typed_enumerations::globalTest2($cpp11_strongly_typed_enumerations::Class1::Enum12_Val5c), 1121); #enumCheck(cpp11_strongly_typed_enumerations::globalTest3($cpp11_strongly_typed_enumerations::Class1::Struct1::Enum12_Val5f), 3121); +$val = enumCheck($cpp11_strongly_typed_enumerations::Enum18_Val1, 1181); +$val = enumCheck($cpp11_strongly_typed_enumerations::Enum18_Val2, 1182); diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index 43ea6a612..f7f59034a 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -107,7 +107,7 @@ static String *pcode = 0; /* Perl code associated with each class */ static int member_func = 0; /* Set to 1 when wrapping a member function */ static String *func_stubs = 0; /* Function stubs */ static String *const_stubs = 0; /* Constant stubs */ -static int num_consts = 0; /* Number of constants */ +static Node *const_stubs_enum_class = 0; /* Node for enum class if we're currently generating one */ static String *var_stubs = 0; /* Variable stubs */ static String *exported = 0; /* Exported symbols */ static String *pragma_include = 0; @@ -585,10 +585,9 @@ public: /* Emit package code for different classes */ Printf(f_pm, "%s", pm); - if (num_consts > 0) { + if (Len(const_stubs) > 0) { /* Emit constant stubs */ Printf(f_pm, "\n# ------- CONSTANT STUBS -------\n\n"); - Printf(f_pm, "package %s;\n\n", namespace_module); Printf(f_pm, "%s", const_stubs); } @@ -1120,8 +1119,22 @@ public: "tie %__", iname, "_hash,\"", is_shadow(type), "\", $", cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(type), ";\n", NIL); } else if (do_constants) { - Printv(const_stubs, "sub ", name, " () { $", cmodule, "::", name, " }\n", NIL); - num_consts++; + char *dcolon = Strstr(name, "::"); + if (!dcolon) { + if (Len(const_stubs) == 0 || const_stubs_enum_class != NULL) { + Printf(const_stubs, "package %s;\n", namespace_module); + const_stubs_enum_class = NULL; + } + Printv(const_stubs, "sub ", iname, " () { $", cmodule, "::", iname, " }\n", NIL); + } else { + // C++11 strongly-typed enum. + Node *parent = Getattr(n, "parentNode"); + if (const_stubs_enum_class != parent) { + Printf(const_stubs, "package %s::%s;\n", namespace_module, Getattr(parent, "sym:name")); + const_stubs_enum_class = parent; + } + Printv(const_stubs, "sub ", Getattr(n, "enumvalueDeclaration:sym:name"), " () { $", cmodule, "::", iname, " }\n", NIL); + } } else { Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); }