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.
This commit is contained in:
+6
-3
@@ -1068,6 +1068,7 @@ parse_defined (cpp_reader *pfile)
|
||||
}
|
||||
}
|
||||
|
||||
bool is_defined = false;
|
||||
if (node)
|
||||
{
|
||||
if ((pfile->context != initial_context
|
||||
@@ -1075,9 +1076,11 @@ parse_defined (cpp_reader *pfile)
|
||||
&& CPP_OPTION (pfile, warn_expansion_to_defined))
|
||||
cpp_pedwarning (pfile, CPP_W_EXPANSION_TO_DEFINED,
|
||||
"this use of \"defined\" may not be portable");
|
||||
|
||||
is_defined = _cpp_defined_macro_p (node);
|
||||
if (!_cpp_maybe_notify_macro_use (pfile, node, token->src_loc))
|
||||
/* It wasn't a macro after all. */
|
||||
is_defined = false;
|
||||
_cpp_mark_macro_used (node);
|
||||
_cpp_maybe_notify_macro_use (pfile, node, token->src_loc);
|
||||
|
||||
/* A possible controlling macro of the form #if !defined ().
|
||||
_cpp_parse_expr checks there was no other junk on the line. */
|
||||
@@ -1093,7 +1096,7 @@ parse_defined (cpp_reader *pfile)
|
||||
result.unsignedp = false;
|
||||
result.high = 0;
|
||||
result.overflow = false;
|
||||
result.low = node && _cpp_defined_macro_p (node);
|
||||
result.low = is_defined;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user