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
