diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-11-24 08:23:55 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-11-24 08:31:03 -0800 |
commit | 13f93cf5336ec0085277b9a5ef88c02359527170 (patch) | |
tree | 21dd731e4de98eaab84f2e61d5bc54debf9c9851 /libcpp/lex.c | |
parent | 489be3119e6cd092bf7f30880a5d641f0bf0672f (diff) | |
download | gcc-13f93cf5336ec0085277b9a5ef88c02359527170.zip gcc-13f93cf5336ec0085277b9a5ef88c02359527170.tar.gz gcc-13f93cf5336ec0085277b9a5ef88c02359527170.tar.bz2 |
preprocessor: Add deferred macros
Deferred macros are needed for C++ modules. Header units may export
macro definitions and undefinitions. These are resolved lazily at the
point of (potential) use. (The language specifies that, it's not just
a useful optimization.) Thus, identifier nodes grow a 'deferred'
field, which fortunately doesn't expand the structure on 64-bit
systems as there was padding there. This is non-zero on NT_MACRO
nodes, if the macro is deferred. When such an identifier is lexed, it
is resolved via a callback that I added recently. That will either
provide the macro definition, or discover it there was an overriding
undef. Either way the identifier is no longer a deferred macro.
Notice it is now possible for NT_MACRO nodes to have a NULL macro
expansion.
libcpp/
* include/cpplib.h (struct cpp_hashnode): Add deferred field.
(cpp_set_deferred_macro): Define.
(cpp_get_deferred_macro): Declare.
(cpp_macro_definition): Reformat, add overload.
(cpp_macro_definition_location): Deal with deferred macro.
(cpp_alloc_token_string, cpp_compare_macro): Declare.
* internal.h (_cpp_notify_macro_use): Return bool
(_cpp_maybe_notify_macro_use): Likewise.
* directives.c (do_undef): Check macro is not undef before
warning.
(do_ifdef, do_ifndef): Deal with deferred macro.
* expr.c (parse_defined): Likewise.
* lex.c (cpp_allocate_token_string): Break out of ...
(create_literal): ... here. Call it.
(cpp_maybe_module_directive): Deal with deferred macro.
* macro.c (cpp_get_token_1): Deal with deferred macro.
(warn_of_redefinition): Deal with deferred macro.
(compare_macros): Rename to ...
(cpp_compare_macro): ... here. Make extern.
(cpp_get_deferred_macro): New.
(_cpp_notify_macro_use): Deal with deferred macro, return bool
indicating definedness.
(cpp_macro_definition): Deal with deferred macro.
Diffstat (limited to 'libcpp/lex.c')
-rw-r--r-- | libcpp/lex.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/libcpp/lex.c b/libcpp/lex.c index 0f18daf..07d5a4f 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1577,13 +1577,20 @@ static void create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, unsigned int len, enum cpp_ttype type) { - uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); - - memcpy (dest, base, len); - dest[len] = '\0'; token->type = type; token->val.str.len = len; - token->val.str.text = dest; + token->val.str.text = cpp_alloc_token_string (pfile, base, len); +} + +const uchar * +cpp_alloc_token_string (cpp_reader *pfile, + const unsigned char *ptr, unsigned len) +{ + uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); + + dest[len] = 0; + memcpy (dest, ptr, len); + return dest; } /* A pair of raw buffer pointers. The currently open one is [1], the @@ -2712,6 +2719,7 @@ cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result) /* Don't attempt to expand the token. */ tok->flags |= NO_EXPAND; if (_cpp_defined_macro_p (node) + && _cpp_maybe_notify_macro_use (pfile, node, tok->src_loc) && !cpp_fun_like_macro_p (node)) cpp_error_with_line (pfile, CPP_DL_ERROR, tok->src_loc, 0, "module control-line \"%s\" cannot be" |