aboutsummaryrefslogtreecommitdiff
path: root/libcpp/lex.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-11-13 20:17:42 +0000
committerTom Tromey <tromey@gcc.gnu.org>2017-11-13 20:17:42 +0000
commitfb771b9dad6ef78a985353128cea48e620eb4324 (patch)
treed94251e8c98cb3a0a9bfd711707dea469e857c6b /libcpp/lex.c
parent4d85d480272fb7331924f04534e0f5f14b60421e (diff)
downloadgcc-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.c30
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,