[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