summaryrefslogtreecommitdiff
path: root/data/variant.hh
diff options
context:
space:
mode:
authorTheophile Ranquet <ranquet@lrde.epita.fr>2013-01-28 18:26:04 +0100
committerTheophile Ranquet <ranquet@lrde.epita.fr>2013-01-29 11:37:04 +0100
commitee9cf8c4a6bf34fe291ed860e0d7779d78a5bcb0 (patch)
tree6cef07b46225ce7e27938da526966612579f91d3 /data/variant.hh
parent858666c44302b355ff0cad76b457d57659306d6f (diff)
downloadbison-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.hh38
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
# ----------------------------