diff --git a/tests/local.at b/tests/local.at index 3bcb8357..0b4231f9 100644 --- a/tests/local.at +++ b/tests/local.at @@ -138,7 +138,7 @@ m4_define([AT_BISON_OPTION_PUSHDEFS], # This sucks hard, GNU M4 should really provide M5-like $$1. m4_define([_AT_BISON_OPTION_PUSHDEFS], [m4_if([$1$2], $[1]$[2], [], - [m4_fatal([$0: Invalid arguments: $@])])dnl + [m4_fatal([$0: invalid arguments: $@])])dnl m4_pushdef([AT_AUTOMOVE_IF], [m4_bmatch([$3], [%define api\.value\.automove], [$1], [$2])]) m4_pushdef([AT_DEFINES_IF], @@ -904,6 +904,33 @@ AT_PARSER_CHECK([./c-and-cxx]) ]) +# AT_REQUIRE_CXX_VERSION(STD) +# --------------------------- +# Skip unless this compiler supports at least C++ STD (e.g., "11", +# "14", etc.). +m4_define([AT_REQUIRE_CXX_VERSION], +[AT_DATA([check.cc], +[[int main () +{ +#if __cplusplus < ]m4_case([$1], + [98], [199711], + [03], [199711], + [11], [201103], + [14], [201402], + [17], [201703], + [2a], [201709], + [m4_fatal([$0: invalid arguments: $@])])[ + return 77; +#else + return 0; +#endif +} +]]) +AT_COMPILE_CXX([check]) +AT_CHECK([@&t@./check]) +]) + + # AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR # ------------------------------------ # Check that we can expect exceptions to be handled properly. diff --git a/tests/types.at b/tests/types.at index 27553726..e31af74b 100644 --- a/tests/types.at +++ b/tests/types.at @@ -66,14 +66,19 @@ AT_CLEANUP # $3: PARSER-ACTION, # $4: INPUT, # $5: SCANNER-ACTION, -# $6: RESULT) +# $6: RESULT, +# $7: REQUIREMENT) # -------------------------------------- # Compile the grammar and check the expected result. # BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES. +# +# Use REQUIREMENT e.g. skip the test if the compiler does not meet the +# requirements. m4_pushdef([_AT_TEST], [ AT_SETUP([$1]) AT_KEYWORDS([api.value.type]) +$7 AT_BISON_OPTION_PUSHDEFS([%debug $1 $2]) AT_DATA_GRAMMAR([test.y], [[%debug @@ -100,8 +105,9 @@ start: $3; ]]) AT_FULL_COMPILE([[test]]) -AT_PARSER_CHECK([./test], 0, [$6 -], [stderr]) +AT_PARSER_CHECK([[./test]], 0, [[$6 +]]) + AT_BISON_OPTION_POPDEFS AT_CLEANUP ]) @@ -111,7 +117,8 @@ AT_CLEANUP # $3: PARSER-ACTION, # $4: INPUT, # $5: SCANNER-ACTION, -# $6: RESULT) +# $6: RESULT, +# $7: REQUIREMENT) # -------------------------------------- # Check with and without %defines, to avoid regressions. It turns out # that in that case yacc.c calls the set-up of the %union twice, @@ -121,8 +128,8 @@ AT_CLEANUP # a second time doubled the side-effects and resulted in a double # definition of the union members. m4_pushdef([AT_TEST], -[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6]) - _AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6]) +[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6], [$7]) + _AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6], [$7]) ]) m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]], @@ -248,17 +255,35 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]], # A Bison-defined variant, for lalr1.cc only. m4_if(b4_skel, [lalr1.cc], [ - AT_TEST([%skeleton "]b4_skel[" - %define api.value.type variant], - [%token '1'; - %token '2';], - ['1' '2' { std::cout << $1 << ", " << $2 << '\n'; }], - ["12"], - [if (res == '1') - AT_VAL.build (10); - else if (res == '2') - AT_VAL.build ("two");], - [10, two])]) + AT_TEST([%skeleton "]b4_skel[" + %define api.value.type variant], + [%token '1'; + %token '2';], + ['1' '2' { std::cout << $1 << ", " << $2 << '\n'; }], + ["12"], + [if (res == '1') + AT_VAL.build (10); + else if (res == '2') + AT_VAL.build ("two");], + [10, two]) + + # Move-only types. + AT_TEST([%skeleton "]b4_skel[" + %code requires { #include } + %define api.value.type variant], + [[%token > '1'; + %token > '2';]], + ['1' '2' { std::cout << *$1 << ", " << *$2 << '\n'; }], + ["12"], + [[if (res == '1') + ]AT_VAL[.emplace > + (std::make_unique (10)); + else if (res == '2') + ]AT_VAL[.emplace > + (std::make_unique ("two"));]], + [10, two], + [AT_REQUIRE_CXX_VERSION(14)])]) + ]) ]) m4_popdef([AT_TEST])