# C++ skeleton for Bison
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 2002-2012 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
])])
-# b4_variant_definition
-# ---------------------
+# b4_variant_includes
+# -------------------
+# The needed includes for variants support.
+m4_define([b4_variant_includes],
+[b4_parse_assert_if([[#include <typeinfo>]])[
+#include <cstdlib> // abort
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+]])
+
+# b4_variant_define
+# -----------------
# Define "variant".
-m4_define([b4_variant_definition],
-[[
- /// A char[S] buffer to store and retrieve objects.
+m4_define([b4_variant_define],
+[[ /// A char[S] buffer to store and retrieve objects.
///
/// Sort of a variant, but does not keep track of the nature
/// of the stored data, since that knowledge is available
/// via the current state.
template <size_t S>
struct variant
- {]b4_assert_if([
- /// Whether something is contained.
- bool built;
-])[
+ {
+ /// Type of *this.
+ typedef variant<S> self_type;
+
/// Empty construction.
inline
- variant ()]b4_assert_if([
- : built (false)])[
+ variant ()]b4_parse_assert_if([
+ : built (false)
+ , tname (YY_NULL)])[
{}
/// Instantiate a \a T in here.
template <typename T>
inline T&
build ()
- {]b4_assert_if([
- assert (!built);
- built = true;])[
+ {]b4_parse_assert_if([
+ YYASSERT (!built);
+ YYASSERT (!tname);
+ YYASSERT (sizeof (T) <= S);
+ built = true;
+ tname = typeid (T).name ();])[
return *new (buffer.raw) T;
}
template <typename T>
inline T&
build (const T& t)
- {]b4_assert_if([
- assert(!built);
- built = true;])[
- return *new (buffer.raw) T(t);
+ {]b4_parse_assert_if([
+ YYASSERT (!built);
+ YYASSERT (!tname);
+ YYASSERT (sizeof (T) <= S);
+ built = true;
+ tname = typeid (T).name ();])[
+ return *new (buffer.raw) T (t);
}
/// Construct and fill.
template <typename T>
inline
- variant (const T& t)]b4_assert_if([
- : built (true)])[
+ variant (const T& t)]b4_parse_assert_if([
+ : built (true)
+ , tname (typeid (T).name ())])[
{
- new (buffer.raw) T(t);
+ YYASSERT (sizeof (T) <= S);
+ new (buffer.raw) T (t);
}
/// Accessor to a built \a T.
template <typename T>
inline T&
as ()
- {]b4_assert_if([
- assert (built);])[
- return reinterpret_cast<T&>(buffer.raw);
+ {]b4_parse_assert_if([
+ YYASSERT (built);
+ YYASSERT (tname == typeid (T).name ());
+ YYASSERT (sizeof (T) <= S);])[
+ return reinterpret_cast<T&> (buffer.raw);
}
/// Const accessor to a built \a T (for %printer).
template <typename T>
inline const T&
as () const
- {]b4_assert_if([
- assert(built);])[
- return reinterpret_cast<const T&>(buffer.raw);
+ {]b4_parse_assert_if([
+ YYASSERT (built);
+ YYASSERT (tname == typeid (T).name ());
+ YYASSERT (sizeof (T) <= S);])[
+ return reinterpret_cast<const T&> (buffer.raw);
}
- /// Swap the content with \a other.
+ /// Swap the content with \a other, of same type.
template <typename T>
inline void
swap (variant<S>& other)
- {
- std::swap (as<T>(), other.as<T>());
+ {]b4_parse_assert_if([
+ YYASSERT (tname == other.tname);])[
+ std::swap (as<T>(), other.as<T>());]b4_parse_assert_if([
+ std::swap (built, other.built);
+ std::swap (tname, other.tname);])[
}
/// Assign the content of \a other to this.
other.destroy<T>();
}
+ /// Copy the content of \a other to this.
+ /// Destroys \a other.
+ template <typename T>
+ inline void
+ copy (const variant<S>& other)
+ {
+ build<T> (other.as<T> ());
+ }
+
/// Destroy the stored \a T.
template <typename T>
inline void
destroy ()
{
- as<T>().~T();]b4_assert_if([
- built = false;])[
+ as<T> ().~T ();]b4_parse_assert_if([
+ built = false;
+ tname = YY_NULL;])[
}
+ /// Prohibit blind copies.
+ // private:
+ self_type& operator=(const self_type&)
+ {
+ abort ();
+ }
+
+ private:
/// A buffer large enough to store any of the semantic values.
/// Long double is chosen as it has the strongest alignment
/// constraints.
{
long double align_me;
char raw[S];
- } buffer;
+ } buffer;]b4_parse_assert_if([
+ /// Whether something is contained.
+ bool built;
+ /// If defined, the name of the stored type.
+ const char* tname;])[
};
]])
{]b4_type_foreach([b4_char_sizeof])[};
/// Symbol semantic values.
- typedef variant<sizeof(union_type)> semantic_type;])
+ typedef variant<sizeof(union_type)> semantic_type;dnl
+])
# How the semantic value is extracted when using variants.
[m4_ifval([$2],
[$1.template as< $2 >()],
[$1])])
+
+
+
+## ------------- ##
+## make_SYMBOL. ##
+## ------------- ##
+
+
+# b4_symbol_constructor_declare_(SYMBOL-NUMBER)
+# ---------------------------------------------
+# Declare the overloaded version of make_symbol for the (common) type of
+# these SYMBOL-NUMBERS. Use at class-level.
+m4_define([b4_symbol_constructor_declare_],
+[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
+[ static inline
+ symbol_type
+ 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_symbol_constructor_declare
+# -----------------------------
+# Declare symbol constructors for all the value types.
+# Use at class-level.
+m4_define([b4_symbol_constructor_declare],
+[ // Symbol constructors declarations.
+b4_symbol_foreach([b4_symbol_constructor_declare_])])
+
+
+
+# b4_symbol_constructor_define_(SYMBOL-NUMBER)
+# --------------------------------------------
+# Define symbol constructor for this SYMBOL-NUMBER.
+m4_define([b4_symbol_constructor_define_],
+[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
+[ b4_parser_class_name::symbol_type
+ 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])))
+ {
+ return symbol_type (b4_join([token::b4_symbol([$1], [id])],
+ b4_symbol_if([$1], [has_type], [v]),
+ b4_locations_if([l])));
+ }
+
+])])])
+
+
+# b4_symbol_constructor_define
+# ----------------------------
+# Define the overloaded versions of make_symbol for all the value types.
+m4_define([b4_symbol_constructor_define],
+[ // Implementation of make_symbol for each symbol type.
+b4_symbol_foreach([b4_symbol_constructor_define_])])