aboutsummaryrefslogtreecommitdiff
path: root/libcpp/internal.h
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-11-18 10:24:12 -0800
committerNathan Sidwell <nathan@acm.org>2020-11-18 10:24:12 -0800
commitc9c3d5f28a589cd00be5748010783657189e9855 (patch)
tree9a1b904ee5ea9b639bd2b43fa16050edd3321044 /libcpp/internal.h
parent7ceb899e9343493f646434f74a149395f3913d9a (diff)
downloadgcc-c9c3d5f28a589cd00be5748010783657189e9855.zip
gcc-c9c3d5f28a589cd00be5748010783657189e9855.tar.gz
gcc-c9c3d5f28a589cd00be5748010783657189e9855.tar.bz2
preprocessor: C++ module-directives
C++20 modules introduces a new kind of preprocessor directive -- a module directive. These are directives but without the leading '#'. We have to detect them by sniffing the start of a logical line. When detected we replace the initial identifiers with unspellable tokens and pass them through to the language parser the same way deferred pragmas are. There's a PRAGMA_EOL at the logical end of line too. One additional complication is that we have to do header-name lexing after the initial tokens, and that requires changes in the macro-aware piece of the preprocessor. The above sniffer sets a counter in the lexer state, and that triggers at the appropriate point. We then do the same header-name lexing that occurs on a #include directive or has_include pseudo-macro. Except that the header name ends up in the token stream. A couple of token emitters need to deal with the new token possibility. gcc/c-family/ * c-lex.c (c_lex_with_flags): CPP_HEADER_NAMEs can now be seen. libcpp/ * include/cpplib.h (struct cpp_options): Add module_directives option. (NODE_MODULE): New node flag. (struct cpp_hashnode): Make rid-code a bitfield, increase bits in flags and swap with type field. * init.c (post_options): Create module-directive identifier nodes. * internal.h (struct lexer_state): Add directive_file_token & n_modules fields. Add module node enumerator. * lex.c (cpp_maybe_module_directive): New. (_cpp_lex_token): Call it. (cpp_output_token): Add '"' around CPP_HEADER_NAME token. (do_peek_ident, do_peek_module): New. (cpp_directives_only): Detect module-directive lines. * macro.c (cpp_get_token_1): Deal with directive_file_token triggering.
Diffstat (limited to 'libcpp/internal.h')
-rw-r--r--libcpp/internal.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 3f5bafb..4c1100b 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -280,6 +280,9 @@ struct lexer_state
/* Nonzero when tokenizing a deferred pragma. */
unsigned char in_deferred_pragma;
+ /* Count to token that is a header-name. */
+ unsigned char directive_file_token;
+
/* Nonzero if the deferred pragma being handled allows macro expansion. */
unsigned char pragma_allow_expansion;
};
@@ -292,6 +295,12 @@ struct spec_nodes
cpp_hashnode *n_false; /* C++ keyword false */
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */
+
+ enum {M_EXPORT, M_MODULE, M_IMPORT, M__IMPORT, M_HWM};
+
+ /* C++20 modules, only set when module_directives is in effect.
+ incoming variants [0], outgoing ones [1] */
+ cpp_hashnode *n_modules[M_HWM][2];
};
typedef struct _cpp_line_note _cpp_line_note;