From ecd5cae2d467a30174c5ac182ddb52547639dc60 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 11 Apr 2020 17:59:55 +0200 Subject: [PATCH] c++: fix generated headers A forthcoming commit (tokens: properly define the "error" token kind) revealed a problem in the C++ generated headers: they are not self-contained. With this file: %language "c++" %define api.value.type variant %code { static int yylex (yy::parser::semantic_type *lvalp); } %token X %% exp: X { printf ("x\n"); } ; %% void yy::parser::error (const std::string& m) { std::cerr << m << '\n'; } static int yylex (yy::parser::semantic_type *lvalp) { static int const input[] = {yy::parser::token::X, 0}; static int toknum = 0; return input[toknum++]; } int main (int argc, char const* argv[]) { yy::parser p; return p.parse (); } the generated header fails to compile cleanly (foo.cc just #includes the generated header): $ clang++-mp-9.0 -c -Wundefined-func-template foo.cc In file included from foo.cc:1: bar.tab.hh:550:12: warning: instantiation of function 'yy::parser::basic_symbol::basic_symbol' required here, but no definition is available [-Wundefined-func-template] struct symbol_type : basic_symbol ^ bar.tab.hh:436:7: note: forward declaration of template entity is here basic_symbol (basic_symbol&& that); ^ bar.tab.hh:550:12: note: add an explicit instantiation declaration to suppress this warning if 'yy::parser::basic_symbol::basic_symbol' is explicitly instantiated in another translation unit struct symbol_type : basic_symbol ^ 1 warning generated. * data/skeletons/c++.m4 (b4_public_types_define): Move the implementation of the basic_symbol move-ctor to... (b4_public_types_define): here, its declaration. * tests/headers.at (Sane headers): Use a declared token so that the corresponding token constructor is declared. Which triggers the aforementioned issue. --- data/skeletons/c++.m4 | 21 ++++++++------------- tests/headers.at | 8 +++++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/data/skeletons/c++.m4 b/data/skeletons/c++.m4 index a0dbbd97..b8512b44 100644 --- a/data/skeletons/c++.m4 +++ b/data/skeletons/c++.m4 @@ -301,7 +301,14 @@ m4_define([b4_symbol_type_define], #if 201103L <= YY_CPLUSPLUS /// Move constructor. - basic_symbol (basic_symbol&& that); + basic_symbol (basic_symbol&& that) + : Base (std::move (that)) + , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([ + , location (std::move (that.location))])[ + {]b4_variant_if([ + b4_symbol_variant([this->type_get ()], [value], [move], + [std::move (that.value)]) + ])[} #endif /// Copy constructor. @@ -417,18 +424,6 @@ m4_define([b4_symbol_type_define], # Provide the implementation needed by the public types. m4_define([b4_public_types_define], [[ // basic_symbol. -#if 201103L <= YY_CPLUSPLUS - template - ]b4_parser_class[::basic_symbol::basic_symbol (basic_symbol&& that) - : Base (std::move (that)) - , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([ - , location (std::move (that.location))])[ - {]b4_variant_if([ - b4_symbol_variant([this->type_get ()], [value], [move], - [std::move (that.value)]) - ])[} -#endif - template ]b4_parser_class[::basic_symbol::basic_symbol (const basic_symbol& that) : Base (that) diff --git a/tests/headers.at b/tests/headers.at index f1cb7316..20a9e4c5 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -125,7 +125,9 @@ AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_GRAMMAR([input.y], [[$1 %define parse.error verbose -]AT_VARIANT_IF([%token 'x'], [%union {int integer;}])[ +]AT_VARIANT_IF([%token X], +[%union {int integer;} +%token X])[ %code { #include /* printf. */ ]AT_PUSH_IF([[ @@ -138,12 +140,12 @@ AT_DATA_GRAMMAR([input.y], } %% exp: - 'x' { printf ("x\n"); } + X { printf ("x\n"); } ; %% ]AT_YYERROR_DEFINE[ -]AT_YYLEX_DEFINE(["x"])[ +]AT_YYLEX_DEFINE([{AT_CXX_IF([yy::parser::token::])X, 0}])[ ]]) AT_BISON_CHECK([-d -o input.AT_LANG_EXT input.y])