preprocessor: Add deferred macros
authorNathan Sidwell <nathan@acm.org>
Tue, 24 Nov 2020 16:23:55 +0000 (08:23 -0800)
committerNathan Sidwell <nathan@acm.org>
Tue, 24 Nov 2020 16:31:03 +0000 (08:31 -0800)
commit13f93cf5336ec0085277b9a5ef88c02359527170
tree21dd731e4de98eaab84f2e61d5bc54debf9c9851
parent489be3119e6cd092bf7f30880a5d641f0bf0672f
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.
libcpp/directives.c
libcpp/expr.c
libcpp/include/cpplib.h
libcpp/internal.h
libcpp/lex.c
libcpp/macro.c