mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
c++: using macros around user types breaks when they include comma
We may generate code such as
basic_symbol (typename Base::kind_type t, YY_RVREF (std::pair<int,int>) v);
which, of course, breaks, because YY_RVREF sees two arguments. Let's
not play tricks with _VA_ARGS__, I'm unsure about it portability.
Anyway, I plan to change more things in this area.
Reported by Sébastien Villemot.
http://lists.gnu.org/archive/html/bug-bison/2018-11/msg00014.html
* data/variant.hh (b4_basic_symbol_constructor_declare)
(b4_basic_symbol_constructor_define): Don't use macro on user types.
* tests/types.at: Check that we support pairs.
This commit is contained in:
1
THANKS
1
THANKS
@@ -151,6 +151,7 @@ Roland Levillain roland@lrde.epita.fr
|
||||
Satya Kiran Popuri satyakiran@gmail.com
|
||||
Sebastian Setzer sebastian.setzer.ext@siemens.com
|
||||
Sebastien Fricker sebastien.fricker@gmail.com
|
||||
Sébastien Villemot sebastien@debian.org
|
||||
Sergei Steshenko sergstesh@yahoo.com
|
||||
Shura debil_urod@ngs.ru
|
||||
Simon Sobisch simonsobisch@web.de
|
||||
|
||||
@@ -379,26 +379,44 @@ b4_join(b4_symbol_if([$1], [has_type],
|
||||
# -----------------------------------
|
||||
# Generate a constructor declaration for basic_symbol from given type.
|
||||
m4_define([b4_basic_symbol_constructor_declare],
|
||||
[[ basic_symbol (]b4_join(
|
||||
[[# if 201103L <= YY_CPLUSPLUS
|
||||
basic_symbol (]b4_join(
|
||||
[typename Base::kind_type t],
|
||||
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
|
||||
b4_locations_if([YY_RVREF (location_type) l]))[);
|
||||
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
|
||||
b4_locations_if([location_type&& l]))[);
|
||||
#else
|
||||
basic_symbol (]b4_join(
|
||||
[typename Base::kind_type t],
|
||||
b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]),
|
||||
b4_locations_if([const location_type& l]))[);
|
||||
#endif
|
||||
]])
|
||||
|
||||
# b4_basic_symbol_constructor_define
|
||||
# ----------------------------------
|
||||
# Generate a constructor implementation for basic_symbol from given type.
|
||||
m4_define([b4_basic_symbol_constructor_define],
|
||||
[[ template <typename Base>
|
||||
[[# if 201103L <= YY_CPLUSPLUS
|
||||
template <typename Base>
|
||||
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
|
||||
[typename Base::kind_type t],
|
||||
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
|
||||
b4_locations_if([YY_RVREF (location_type) l]))[)
|
||||
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
|
||||
b4_locations_if([location_type&& l]))[)
|
||||
: Base (t)]b4_symbol_if([$1], [has_type], [
|
||||
, value (YY_MOVE (v))])[]b4_locations_if([
|
||||
, location (YY_MOVE (l))])[
|
||||
, value (std::move (v))])[]b4_locations_if([
|
||||
, location (std::move (l))])[
|
||||
{}
|
||||
|
||||
#else
|
||||
template <typename Base>
|
||||
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
|
||||
[typename Base::kind_type t],
|
||||
b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]),
|
||||
b4_locations_if([const location_type& l]))[)
|
||||
: Base (t)]b4_symbol_if([$1], [has_type], [
|
||||
, value (v)])[]b4_locations_if([
|
||||
, location (l)])[
|
||||
{}
|
||||
#endif
|
||||
]])
|
||||
|
||||
# b4_symbol_constructor_define
|
||||
|
||||
@@ -270,6 +270,24 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
AT_VAL.build<std::string> ("two");],
|
||||
[10, two])
|
||||
|
||||
# Test a regression where we passed user types (we can include
|
||||
# commas) to a CPP macro.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type variant],
|
||||
[%token <std::pair<int, int>> '1';
|
||||
%token <std::pair<std::string, std::string>> '2';],
|
||||
['1' '2'
|
||||
{
|
||||
std::cout << $1.first << ':' << $1.second << ", "
|
||||
<< $2.first << ':' << $2.second << '\n';
|
||||
}],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.build (std::make_pair (10, 11));
|
||||
else if (res == '2')
|
||||
AT_VAL.build (std::make_pair<std::string, std::string> ("two", "deux"));],
|
||||
[10:11, two:deux])
|
||||
|
||||
# Move-only types.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%code requires { #include <memory> }
|
||||
|
||||
Reference in New Issue
Block a user