diff options
author | Theophile Ranquet <ranquet@lrde.epita.fr> | 2013-01-28 18:26:04 +0100 |
---|---|---|
committer | Theophile Ranquet <ranquet@lrde.epita.fr> | 2013-01-29 11:37:04 +0100 |
commit | ee9cf8c4a6bf34fe291ed860e0d7779d78a5bcb0 (patch) | |
tree | 6cef07b46225ce7e27938da526966612579f91d3 /data/variant.hh | |
parent | 858666c44302b355ff0cad76b457d57659306d6f (diff) | |
download | bison-ee9cf8c4a6bf34fe291ed860e0d7779d78a5bcb0.tar.gz |
m4: generate a basic_symbol constructor for each symbol type
Recently, there was a slightly vicious bug hidden in the make_ functions:
parser::symbol_type
parser::make_TEXT (const ::std::string& v)
{
return symbol_type (token::TOK_TEXT, v);
}
The constructor for symbol_type doesn't take an ::std::string& as
argument, but a constant variant. However, because there is a variant
constructor which takes an ::std::string&, this caused the implicit
construction of a built variant. Considering that the variant argument
for the symbol_type constructor was cv-qualified, this temporary variant
was never destroyed.
As a temporary solution, the symbol was built in two stages:
symbol_type res (token::TOK_TEXT);
res.value.build< ::std::string&> (v);
return res;
However, the solution introduced in this patch contributes to letting
the symbols handle themselves, by supplying them with constructors that
take a non-variant value and build the symbol's own variant with that
value.
* data/variant.hh (b4_symbol_constructor_define_): Use the new
constructors rather than building in a temporary symbol.
(b4_basic_symbol_constructor_declare,
b4_basic_symbol_constructor_define): New macros generating the
constructors.
* data/c++.m4 (basic_symbol): Invoke the macros here.
Diffstat (limited to 'data/variant.hh')
-rw-r--r-- | data/variant.hh | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/data/variant.hh b/data/variant.hh index 84ea7798..3b21329c 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -311,15 +311,43 @@ m4_define([b4_symbol_constructor_define_], b4_parser_class_name::make_[]b4_symbol_([$1], [id]) (dnl b4_join(b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]), - b4_locations_if([const location_type& l])))[ + b4_locations_if([const location_type& l]))) { - symbol_type res (token::]b4_symbol([$1], [id])[]b4_locations_if([, l])[); - ]b4_symbol_if([$1], [has_type], [res.value.build (v); - ])[return res; + return symbol_type (b4_join([token::b4_symbol([$1], [id])], + b4_symbol_if([$1], [has_type], [v]), + b4_locations_if([l]))); + } -]])])]) +])])]) + +# b4_basic_symbol_constructor_declare +# ---------------------------------- +# Generate a constructor declaration for basic_symbol from given type. +m4_define([b4_basic_symbol_constructor_declare], +[[ + 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]))[); +]]) + +# 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> + ]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) + , value (]b4_symbol_if([$1], [has_type], [v])[)]b4_locations_if([ + , location (l)])[ + {} +]]) # b4_symbol_constructor_define # ---------------------------- |