]> git.saurik.com Git - bison.git/blobdiff - data/c++.m4
regen
[bison.git] / data / c++.m4
index 2d45bc82de5b3709759feed1103d49c97a83db6d..be12c0a2feb75814f2917c87f1012f0724349d42 100644 (file)
@@ -25,6 +25,12 @@ m4_include(b4_pkgdatadir/[c.m4])
 m4_define([b4_comment],
 [b4_comment_([$1], [$2// ], [$2// ])])
 
+## -------- ##
+## Checks.  ##
+## -------- ##
+
+b4_percent_define_check_kind([api.namespace], [code], [deprecated])
+b4_percent_define_check_kind([parser_class_name], [code], [deprecated])
 
 ## ---------------- ##
 ## Default values.  ##
@@ -38,6 +44,7 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
 # b4_percent_define_default([[api.location.type]], [[location]])
 
 b4_percent_define_default([[filename_type]], [[std::string]])
+# Make it a warning for those who used betas of Bison 3.0.
 b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
 
 b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
@@ -54,8 +61,8 @@ b4_percent_define_default([[define_location_comparison]],
 m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
 
 
-# Don't permit an empty b4_namespace_ref.  Any `::parser::foo' appended to it
-# would compile as an absolute reference with `parser' in the global namespace.
+# Don't permit an empty b4_namespace_ref.  Any '::parser::foo' appended to it
+# would compile as an absolute reference with 'parser' in the global namespace.
 # b4_namespace_open would open an anonymous namespace and thus establish
 # internal linkage.  This would compile.  However, it's cryptic, and internal
 # linkage for the parser would be specified in all translation units that
@@ -112,19 +119,24 @@ m4_define([b4_token_enums],
 ## Semantic Values.  ##
 ## ----------------- ##
 
-# b4_semantic_type_declare
-# ------------------------
+
+
+# b4_value_type_declare
+# ---------------------
 # Declare semantic_type.
-m4_define([b4_semantic_type_declare],
+m4_define([b4_value_type_declare],
+[b4_value_type_setup[]dnl
 [    /// Symbol semantic values.
-m4_ifdef([b4_stype],
-[    union semantic_type
+]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+[code],
+[[    typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
+[m4_bmatch(b4_percent_define_get([[api.value.type]]),
+[union\|union-directive],
+[[    union semantic_type
     {
-b4_user_stype
-    };],
-[m4_if(b4_tag_seen_flag, 0,
-[[    typedef int semantic_type;]],
-[[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
+    ]b4_user_union_members[
+    };]])])dnl
+])
 
 
 # b4_public_types_declare
@@ -133,7 +145,7 @@ b4_user_stype
 # Depending on %define token_lex, may be output in the header or source file.
 m4_define([b4_public_types_declare],
 [[#ifndef ]b4_api_PREFIX[STYPE
-]b4_semantic_type_declare[
+]b4_value_type_declare[
 #else
     typedef ]b4_api_PREFIX[STYPE semantic_type;
 #endif]b4_locations_if([
@@ -154,9 +166,15 @@ m4_define([b4_public_types_declare],
       ]b4_token_enums[
     };
 
-    /// Token type.
+    /// (External) token type, as returned by yylex.
     typedef token::yytokentype token_type;
 
+    /// Internal symbol number.
+    typedef int symbol_number_type;
+
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef ]b4_int_type_for([b4_translate])[ token_number_type;
+
     /// A complete symbol.
     ///
     /// Expects its Base type to provide access to the symbol type
@@ -166,61 +184,72 @@ m4_define([b4_public_types_declare],
     template <typename Base>
     struct basic_symbol : Base
     {
+      /// Alias to Base.
+      typedef Base super_type;
+
       /// Default constructor.
-      inline basic_symbol ();
-]b4_locations_if([
-      /// Constructor.
-      inline basic_symbol (const location_type& l);])[
+      basic_symbol ();
 
       /// Copy constructor.
-      inline basic_symbol (const basic_symbol& other);
-
+      basic_symbol (const basic_symbol& other);
+]b4_variant_if([[
+      /// Constructor for valueless symbols, and symbols from each type.
+]b4_type_foreach([b4_basic_symbol_constructor_declare])], [[
       /// Constructor for valueless symbols.
-      inline basic_symbol (]b4_join(
-        [typename Base::value_type t],
-        b4_locations_if([const location_type& l]))[);
+      basic_symbol (typename Base::kind_type t]b4_locations_if([,
+                    const location_type& l])[);]])[
 
       /// Constructor for symbols with semantic value.
-      inline basic_symbol (]b4_join(
-        [typename Base::value_type t],
-        [const semantic_type& v],
-        b4_locations_if([const location_type& l]))[);
+      basic_symbol (typename Base::kind_type t,
+                    const semantic_type& v]b4_locations_if([,
+                    const location_type& l])[);
 
-      /// Assignment operator.
-      inline basic_symbol& operator= (const basic_symbol& other);
+      ~basic_symbol ();
 
-      /// Destructive move, \a s is emptied.
-      inline void move (basic_symbol& s);
+      /// Destructive move, \a s is emptied into this.
+      void move (basic_symbol& s);
 
       /// The semantic value.
       semantic_type value;]b4_locations_if([
 
       /// The location.
       location_type location;])[
+
+    private:
+      /// Assignment operator.
+      basic_symbol& operator= (const basic_symbol& other);
     };
 
     /// Type access provider for token (enum) based symbols.
     struct by_type
     {
       /// Default constructor.
-      inline by_type ();
+      by_type ();
 
       /// Copy constructor.
-      inline by_type (const by_type& other);
+      by_type (const by_type& other);
 
-      /// Constructor.
-      inline by_type (token_type t);
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
 
-      /// The symbol type.
-      int type;
+      /// Constructor from (external) token numbers.
+      by_type (kind_type t);
 
-      /// The type (corresponding to \a type).
-      inline int type_get () const;
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
+
+      /// The (internal) type number (corresponding to \a type).
+      /// -1 when this symbol is empty.
+      symbol_number_type type_get () const;
 
       /// The token.
-      inline token_type token () const;
+      token_type token () const;
+
+      enum { empty = 0 };
 
-      typedef token_type value_type;
+      /// The symbol type.
+      /// -1 when this symbol is empty.
+      token_number_type type;
     };
 
     /// "External" symbols: returned by the scanner.
@@ -241,24 +270,13 @@ m4_define([b4_public_types_define],
 
   // basic_symbol.
   template <typename Base>
+  inline
   ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()
     : value ()
   {}
-]b4_locations_if([
-  template <typename Base>
-  ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const location_type& l)
-    : value ()
-    , location (l)
-  {}])[
-
-  template <typename Base>
-  ]b4_parser_class_name[::basic_symbol<Base>&
-  ]b4_parser_class_name[::basic_symbol<Base>::operator= (const basic_symbol&)
-  {
-    abort ();
-  }
 
   template <typename Base>
+  inline
   ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
     : Base (other)
     , value ()]b4_locations_if([
@@ -271,60 +289,93 @@ m4_define([b4_public_types_define],
 
 
   template <typename Base>
+  inline
   ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
-          [typename Base::value_type t],
+          [typename Base::kind_type t],
           [const semantic_type& v],
           b4_locations_if([const location_type& l]))[)
     : Base (t)
-    , value ()]b4_locations_if([
+    , value (]b4_variant_if([], [v])[)]b4_locations_if([
     , location (l)])[
-  {
-    // FIXME: The YYUSE macro is only available in the .cc skeleton files.  It
-    // is not available in .hh files, where this code is when using %defines.
+  {]b4_variant_if([[
     (void) v;
-    ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [copy],
-                                      [v])],
-                   [value = v;])[
-  }
+    ]b4_symbol_variant([this->type_get ()], [value], [copy], [v])])[}
 
+]b4_variant_if([[
+  // Implementation of basic_symbol constructor for each type.
+]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
+  /// Constructor for valueless symbols.
   template <typename Base>
+  inline
   ]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
-          [typename Base::value_type t],
+          [typename Base::kind_type t],
           b4_locations_if([const location_type& l]))[)
-    : Base (t)]b4_locations_if([
+    : Base (t)
+    , value ()]b4_locations_if([
     , location (l)])[
-  {}
+  {}]])[
 
   template <typename Base>
+  inline
+  ]b4_parser_class_name[::basic_symbol<Base>::~basic_symbol ()
+  {]b4_variant_if([[
+    // User destructor.
+    symbol_number_type yytype = this->type_get ();
+    switch (yytype)
+    {
+]b4_symbol_foreach([b4_symbol_destructor])dnl
+[   default:
+      break;
+    }
+
+    // Type destructor.
+  ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
+  }
+
+  template <typename Base>
+  inline
   void
   ]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s)
   {
-    this->type = s.type_get ();]b4_locations_if([
-    location = s.location;])[
-    ]b4_variant_if([b4_symbol_variant([s.type_get ()], [value], [move],
+    super_type::move(s);
+    ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
                                       [s.value])],
-                   [value = s.value;])[
+                   [value = s.value;])[]b4_locations_if([
+    location = s.location;])[
   }
 
   // by_type.
+  inline
   ]b4_parser_class_name[::by_type::by_type ()
-     : type ()
+     : type (empty)
   {}
 
+  inline
   ]b4_parser_class_name[::by_type::by_type (const by_type& other)
     : type (other.type)
   {}
 
+  inline
   ]b4_parser_class_name[::by_type::by_type (token_type t)
     : type (yytranslate_ (t))
   {}
 
+  inline
+  void
+  ]b4_parser_class_name[::by_type::move (by_type& that)
+  {
+    type = that.type;
+    that.type = empty;
+  }
+
+  inline
   int
   ]b4_parser_class_name[::by_type::type_get () const
   {
     return type;
   }
 ]b4_token_ctor_if([[
+  inline
   ]b4_parser_class_name[::token_type
   ]b4_parser_class_name[::by_type::token () const
   {
@@ -357,6 +408,7 @@ m4_define([b4_symbol_constructor_define], [])
 # sometimes in the cc file.
 m4_define([b4_yytranslate_define],
 [[  // Symbol number corresponding to token number t.
+  inline
   ]b4_parser_class_name[::token_number_type
   ]b4_parser_class_name[::yytranslate_ (]b4_token_ctor_if([token_type],
                                                           [int])[ t)
@@ -480,3 +532,13 @@ m4_define([b4_yylloc_default_define],
     while (/*CONSTCOND*/ false)
 # endif
 ]])
+
+## -------- ##
+## Checks.  ##
+## -------- ##
+
+b4_token_ctor_if([b4_variant_if([],
+  [b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
+               [cannot use '%s' without '%s'],
+               [%define api.token.constructor],
+               [%define api.value.type variant]))])])