mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +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
|
Satya Kiran Popuri satyakiran@gmail.com
|
||||||
Sebastian Setzer sebastian.setzer.ext@siemens.com
|
Sebastian Setzer sebastian.setzer.ext@siemens.com
|
||||||
Sebastien Fricker sebastien.fricker@gmail.com
|
Sebastien Fricker sebastien.fricker@gmail.com
|
||||||
|
Sébastien Villemot sebastien@debian.org
|
||||||
Sergei Steshenko sergstesh@yahoo.com
|
Sergei Steshenko sergstesh@yahoo.com
|
||||||
Shura debil_urod@ngs.ru
|
Shura debil_urod@ngs.ru
|
||||||
Simon Sobisch simonsobisch@web.de
|
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.
|
# Generate a constructor declaration for basic_symbol from given type.
|
||||||
m4_define([b4_basic_symbol_constructor_declare],
|
m4_define([b4_basic_symbol_constructor_declare],
|
||||||
[[ basic_symbol (]b4_join(
|
[[# if 201103L <= YY_CPLUSPLUS
|
||||||
|
basic_symbol (]b4_join(
|
||||||
[typename Base::kind_type t],
|
[typename Base::kind_type t],
|
||||||
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
|
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
|
||||||
b4_locations_if([YY_RVREF (location_type) l]))[);
|
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
|
# b4_basic_symbol_constructor_define
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Generate a constructor implementation for basic_symbol from given type.
|
# Generate a constructor implementation for basic_symbol from given type.
|
||||||
m4_define([b4_basic_symbol_constructor_define],
|
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(
|
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
|
||||||
[typename Base::kind_type t],
|
[typename Base::kind_type t],
|
||||||
b4_symbol_if([$1], [has_type], [YY_RVREF (b4_symbol([$1], [type])) v]),
|
b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]),
|
||||||
b4_locations_if([YY_RVREF (location_type) l]))[)
|
b4_locations_if([location_type&& l]))[)
|
||||||
: Base (t)]b4_symbol_if([$1], [has_type], [
|
: Base (t)]b4_symbol_if([$1], [has_type], [
|
||||||
, value (YY_MOVE (v))])[]b4_locations_if([
|
, value (std::move (v))])[]b4_locations_if([
|
||||||
, location (YY_MOVE (l))])[
|
, 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
|
# 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");],
|
AT_VAL.build<std::string> ("two");],
|
||||||
[10, 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.
|
# Move-only types.
|
||||||
AT_TEST([%skeleton "]b4_skel["
|
AT_TEST([%skeleton "]b4_skel["
|
||||||
%code requires { #include <memory> }
|
%code requires { #include <memory> }
|
||||||
|
|||||||
Reference in New Issue
Block a user