diff options
author | Tom Tromey <tom@tromey.com> | 2017-11-13 20:17:42 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2017-11-13 20:17:42 +0000 |
commit | fb771b9dad6ef78a985353128cea48e620eb4324 (patch) | |
tree | d94251e8c98cb3a0a9bfd711707dea469e857c6b /libcpp/lex.c | |
parent | 4d85d480272fb7331924f04534e0f5f14b60421e (diff) | |
download | gcc-fb771b9dad6ef78a985353128cea48e620eb4324.zip gcc-fb771b9dad6ef78a985353128cea48e620eb4324.tar.gz gcc-fb771b9dad6ef78a985353128cea48e620eb4324.tar.bz2 |
Implement __VA_OPT__
This implements __VA_OPT__, a new preprocessor feature added in C++2A.
The paper can be found here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0306r4.html
gcc/ChangeLog
* doc/cpp.texi (Variadic Macros): Document __VA_OPT__.
gcc/testsuite/ChangeLog
* c-c++-common/cpp/va-opt-pedantic.c: New file.
* c-c++-common/cpp/va-opt.c: New file.
* c-c++-common/cpp/va-opt-error.c: New file.
libcpp/ChangeLog
* pch.c (cpp_read_state): Set n__VA_OPT__.
* macro.c (vaopt_state): New class.
(_cpp_arguments_ok): Check va_opt flag.
(replace_args, create_iso_definition): Use vaopt_state.
* lex.c (lex_identifier_intern): Possibly issue errors for
__VA_OPT__.
(lex_identifier): Likewise.
(maybe_va_opt_error): New function.
* internal.h (struct lexer_state) <va_args_ok>: Update comment.
(struct spec_nodes) <n__VA_OPT__>: New field.
* init.c (struct lang_flags) <va_opt>: New field.
(lang_defaults): Add entries for C++2A. Update all entries for
va_opt.
(cpp_set_lang): Initialize va_opt.
* include/cpplib.h (struct cpp_options) <va_opt>: New field.
* identifiers.c (_cpp_init_hashtable): Initialize n__VA_OPT__.
From-SVN: r254707
Diffstat (limited to 'libcpp/lex.c')
-rw-r--r-- | libcpp/lex.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/libcpp/lex.c b/libcpp/lex.c index 8af09e5..a8dc3ba 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1352,6 +1352,28 @@ forms_identifier_p (cpp_reader *pfile, int first, return false; } +/* Helper function to issue error about improper __VA_OPT__ use. */ +static void +maybe_va_opt_error (cpp_reader *pfile) +{ + if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, va_opt)) + { + /* __VA_OPT__ should not be accepted at all, but allow it in + system headers. */ + if (!cpp_in_system_header (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_OPT__ is not available until C++2a"); + } + else if (!pfile->state.va_args_ok) + { + /* __VA_OPT__ should only appear in the replacement list of a + variadic macro. */ + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_OPT__ can only appear in the expansion" + " of a C++2a variadic macro"); + } +} + /* Helper function to get the cpp_hashnode of the identifier BASE. */ static cpp_hashnode * lex_identifier_intern (cpp_reader *pfile, const uchar *base) @@ -1396,6 +1418,9 @@ lex_identifier_intern (cpp_reader *pfile, const uchar *base) " of a C99 variadic macro"); } + if (result == pfile->spec_nodes.n__VA_OPT__) + maybe_va_opt_error (pfile); + /* For -Wc++-compat, warn about use of C++ named operators. */ if (result->flags & NODE_WARN_OPERATOR) cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, @@ -1485,6 +1510,11 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, " of a C99 variadic macro"); } + /* __VA_OPT__ should only appear in the replacement list of a + variadic macro. */ + if (result == pfile->spec_nodes.n__VA_OPT__) + maybe_va_opt_error (pfile); + /* For -Wc++-compat, warn about use of C++ named operators. */ if (result->flags & NODE_WARN_OPERATOR) cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, |