From 5fe636c7ee9334658b32ea9985bb92f86f16759f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 5 Oct 2018 08:27:11 +0200 Subject: [PATCH] c++: provide a means to control how location.hh is included Users may want to generate the location file elsewhere, say $top_srcdir/include/ast/location.hh. Yet, we should not generate `#include "$top_srcdir/include/ast/location.hh"` but probably something like `#include `, or `#include "ast/location.hh", or `#include `. It entirely depends on the compiler flags (-I/-isystem) that are used. Bison cannot guess what is expected, so let's give the user a means to tell how the location file should be included. * data/location.cc (b4_location_file): New. * data/glr.cc, data/lalr1.cc: Use it. --- data/glr.cc | 2 +- data/lalr1.cc | 4 +-- data/location.cc | 10 ++++-- tests/c++.at | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/data/glr.cc b/data/glr.cc index 6eba471e..27ae7be0 100644 --- a/data/glr.cc +++ b/data/glr.cc @@ -247,7 +247,7 @@ b4_percent_code_get([[requires]])[ #include ]m4_ifdef([b4_location_file], - [[# include "]b4_location_file["]])[ + [[# include ]b4_location_include])[ ]b4_null_define[ diff --git a/data/lalr1.cc b/data/lalr1.cc index 7709c2cd..804efb65 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -163,8 +163,8 @@ m4_define([b4_shared_declarations], # include ]b4_cxx_portability[ -]m4_ifdef([b4_location_file], - [[# include "]b4_location_file["]])[ +]m4_ifdef([b4_location_include], + [[# include ]b4_location_include])[ ]b4_variant_if([b4_variant_includes])[ ]b4_attribute_define[ diff --git a/data/location.cc b/data/location.cc index 9c21cecd..44a1f5ab 100644 --- a/data/location.cc +++ b/data/location.cc @@ -37,8 +37,12 @@ b4_percent_define_ifdef([[api.position.file]], b4_percent_define_check_file([b4_location_file], [[api.location.file]], b4_defines_if([[location.hh]])) - - +# If location.hh is to be generated, the name under which should it be +# included. +m4_ifdef([b4_location_file], + [m4_define([b4_location_include], + [b4_percent_define_get([[api.location.include]], + ["b4_location_file"])])]) # b4_location_define # ------------------ @@ -317,7 +321,7 @@ m4_ifdef([b4_position_file], [[ // 3. remove references to this file from your build system // 4. if you used to include it, include "]b4_location_file[" instead. -#include "]b4_location_file[" +#include ]b4_location_include[ ]b4_output_end[ ]]) diff --git a/tests/c++.at b/tests/c++.at index 8a3d2b00..2b354c2d 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -1323,3 +1323,82 @@ AT_BISON_CHECK([[-o input.cc input.yy]]) AT_FOR_EACH_CXX([AT_COMPILE_CXX([[input]])]) AT_CLEANUP + +## ------------------ ## +## Shared locations. ## +## ------------------ ## + +AT_SETUP([Shared locations]) + +# AT_TEST([PREFIX], [DIRECTIVES]) +# ------------------------------- +# Generate and compile to *.o. Make sure there is no (allowed) YY* +# nor yy* identifiers in the header after applying api.prefix. Check +# that headers can be compiled by a C++ compiler. +m4_pushdef([AT_TEST], +[AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %define api.namespace {$1} $2]) +AT_LOC_PUSHDEF([begin.line], [begin.column], [end.line], [end.column]) +AT_DATA_GRAMMAR([$1.yy], +[[%skeleton "lalr1.cc" +%define api.namespace {$1} +$2 +%code { + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ +} +%% +exp: '0'; +%% +]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE(["0"])[ +]]) + +AT_BISON_CHECK([-fcaret -o $1.cc $1.yy]) +AT_LANG_COMPILE([$1.o], [], [-Iinclude]) + +AT_LOC_POPDEF +AT_BISON_OPTION_POPDEFS +]) + +mkdir -p include/ast + +AT_TEST([x1], + [%defines + %locations + %define api.location.file "include/ast/loc.hh" + %define api.location.include {}]) + +AT_TEST([x2], + [%defines + %locations + %code requires {#include } + %define api.location.type {x1::location}]) + +m4_popdef([AT_TEST]) + +AT_DATA([main.cc], +[AT_DATA_SOURCE_PROLOGUE +[#include "x1.hh" +#include "x2.hh" + +#define RUN(S) \ + do { \ + S::parser parser; \ + int res = parser.parse(); \ + if (res) \ + std::cerr << #S": " << res << '\n'; \ + } while (false) + +int +main (void) +{ + RUN(x1); + RUN(x2); +} +]])# main.cc + + +AT_COMPILE_CXX([parser], [[x[12].o main.cc]], [-Iinclude]) +AT_PARSER_CHECK([./parser], [0]) + +AT_CLEANUP