bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] C++: fix uses of `inline`


From: Akim Demaille
Subject: [PATCH 3/3] C++: fix uses of `inline`
Date: Thu, 10 May 2018 17:45:23 +0200

Sometimes `inline` would be used in *.cc files on symbols that are not
exported (useless but harmless), and sometimes on exported symbols
such as the constructor of syntax_error (harmful: linking fails).

Reported several times, including:

- by Dennis T
  http://lists.gnu.org/archive/html/bug-bison/2016-03/msg00002.html
- by Frank Heckenbach
  https://savannah.gnu.org/patch/?9616

* data/c++.m4 (b4_inline): New: expands to `inline` or nothing.
Use it where appropriate.
* data/lalr1.cc: Use it where appropriate.

* tests/c++.at (Syntax error as exception): Put the scanner in another
compilation unit to exercise the constructor of syntax_error.
---
 data/c++.m4   | 49 +++++++++++++++++++++++++------------------------
 data/lalr1.cc | 18 +++++++++---------
 tests/c++.at  | 21 +++++++++++++--------
 3 files changed, 47 insertions(+), 41 deletions(-)

diff --git a/data/c++.m4 b/data/c++.m4
index aa2cffa2..6e123a0d 100644
--- a/data/c++.m4
+++ b/data/c++.m4
@@ -2,7 +2,7 @@
 
 # C++ skeleton for Bison
 
-# Copyright (C) 2002-2015 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 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
@@ -30,6 +30,16 @@ m4_include(b4_pkgdatadir/[c.m4])
 m4_define([b4_comment],
 [b4_comment_([$1], [$2// ], [$2// ])])
 
+# b4_inline(hh|cc)
+# ----------------
+# Expand to `inline\n  ` if $1 is hh.
+m4_define([b4_inline],
+[m4_case([$1],
+  [cc], [],
+  [hh], [[inline
+  ]],
+  [m4_fatal([$0: invalid argument: $1])])])
+
 ## -------- ##
 ## Checks.  ##
 ## -------- ##
@@ -275,12 +285,11 @@ m4_define([b4_public_types_declare],
 ]b4_symbol_constructor_declare])
 
 
-# b4_public_types_define
-# ----------------------
+# b4_public_types_define(hh|cc)
+# -----------------------------
 # Provide the implementation needed by the public types.
 m4_define([b4_public_types_define],
-[[  inline
-  ]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const 
location_type& l, ])[const std::string& m)
+[  b4_inline([$1])b4_parser_class_name[::syntax_error::syntax_error 
(]b4_locations_if([const location_type& l, ])[const std::string& m)
     : std::runtime_error (m)]b4_locations_if([
     , location (l)])[
   {}
@@ -372,45 +381,38 @@ m4_define([b4_public_types_define],
   }
 
   // by_type.
-  inline
-  ]b4_parser_class_name[::by_type::by_type ()
+  ]b4_inline([$1])b4_parser_class_name[::by_type::by_type ()
     : type (empty_symbol)
   {}
 
-  inline
-  ]b4_parser_class_name[::by_type::by_type (const by_type& other)
+  ]b4_inline([$1])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)
+  ]b4_inline([$1])b4_parser_class_name[::by_type::by_type (token_type t)
     : type (yytranslate_ (t))
   {}
 
-  inline
-  void
+  ]b4_inline([$1])[void
   ]b4_parser_class_name[::by_type::clear ()
   {
     type = empty_symbol;
   }
 
-  inline
-  void
+  ]b4_inline([$1])[void
   ]b4_parser_class_name[::by_type::move (by_type& that)
   {
     type = that.type;
     that.clear ();
   }
 
-  inline
-  int
+  ]b4_inline([$1])[int
   ]b4_parser_class_name[::by_type::type_get () const
   {
     return type;
   }
 ]b4_token_ctor_if([[
-  inline
-  ]b4_parser_class_name[::token_type
+  ]b4_inline([$1])b4_parser_class_name[::token_type
   ]b4_parser_class_name[::by_type::token () const
   {
     // YYTOKNUM[NUM] -- (External) token number corresponding to the
@@ -436,14 +438,13 @@ m4_define([b4_symbol_constructor_declare], [])
 m4_define([b4_symbol_constructor_define], [])
 
 
-# b4_yytranslate_define
-# ---------------------
-# Define yytranslate_.  Sometimes used in the header file,
+# b4_yytranslate_define(cc|hh)
+# ----------------------------
+# Define yytranslate_.  Sometimes used in the header file ($1=hh),
 # 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_inline([$1])b4_parser_class_name[::token_number_type
   ]b4_parser_class_name[::yytranslate_ (]b4_token_ctor_if([token_type],
                                                           [int])[ t)
   {
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 2e9d4d50..4b071d08 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -142,9 +142,9 @@ b4_bison_locations_if([# Backward compatibility.
 m4_include(b4_pkgdatadir/[stack.hh])
 b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
 
-# b4_shared_declarations
-# ----------------------
-# Declaration that might either go into the header (if --defines)
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --defines, $1 = hh)
 # or open coded in the parser body.
 m4_define([b4_shared_declarations],
 [b4_percent_code_get([[requires]])[
@@ -359,8 +359,8 @@ b4_location_define])])[
 ]b4_parse_param_vars[
   };
 
-]b4_token_ctor_if([b4_yytranslate_define
-b4_public_types_define])[
+]b4_token_ctor_if([b4_yytranslate_define([$1])[
+]b4_public_types_define([$1])])[
 ]b4_namespace_close[
 
 ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
@@ -386,7 +386,7 @@ b4_copyright([Skeleton interface for Bison LALR(1) parsers 
in C++])
 // C++ LALR(1) parser skeleton written by Akim Demaille.
 
 ]b4_cpp_guard_open([b4_spec_defines_file])[
-]b4_shared_declarations[
+]b4_shared_declarations(hh)[
 ]b4_cpp_guard_close([b4_spec_defines_file])
 b4_output_end()
 ])
@@ -406,7 +406,7 @@ m4_if(b4_prefix, [yy], [],
 ]b4_null_define[
 
 ]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
-               [b4_shared_declarations])[
+               [b4_shared_declarations([cc])])[
 
 // User implementation prologue.
 ]b4_user_post_prologue[
@@ -533,7 +533,7 @@ m4_if(b4_prefix, [yy], [],
   | Symbol types.  |
   `---------------*/
 
-]b4_token_ctor_if([], [b4_public_types_define])[
+]b4_token_ctor_if([], [b4_public_types_define([cc])])[
 
   // by_state.
   ]b4_parser_class_name[::by_state::by_state ()
@@ -1149,7 +1149,7 @@ b4_error_verbose_if([state_type yystate, const 
symbol_type& yyla],
   }
 #endif // ]b4_api_PREFIX[DEBUG
 
-]b4_token_ctor_if([], [b4_yytranslate_define])[
+]b4_token_ctor_if([], [b4_yytranslate_define([cc])])[
 ]b4_namespace_close[
 ]b4_epilogue[]dnl
 b4_output_end()
diff --git a/tests/c++.at b/tests/c++.at
index dc79d6b9..0c9174c4 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -633,6 +633,7 @@ AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
 
 AT_DATA_GRAMMAR([[input.y]],
 [[%skeleton "lalr1.cc"
+%defines
 
 %code
 {
@@ -664,6 +665,17 @@ item:
 
 %%
 
+void
+yy::parser::error (const std::string &m)
+{
+  std::cerr << "error: " << m << '\n';
+}
+]AT_MAIN_DEFINE[
+]])
+
+AT_DATA_SOURCE([input-scan.cc],
+[[#include "input.hh"
+
 int
 yylex (yy::parser::semantic_type *)
 {
@@ -677,16 +689,9 @@ yylex (yy::parser::semantic_type *)
       return res;
   }
 }
-
-void
-yy::parser::error (const std::string &m)
-{
-  std::cerr << "error: " << m << '\n';
-}
-]AT_MAIN_DEFINE[
 ]])
 
-AT_FULL_COMPILE([[input]])
+AT_FULL_COMPILE([[input]], [[scan]])
 
 AT_PARSER_CHECK([[./input]], [[0]], [[]],
 [[error: invalid expression
-- 
2.17.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]