From 5950c3c9a7729687a04f9b008e441959a2d9114d Mon Sep 17 00:00:00 2001 From: Ben Elliston Date: Mon, 14 Jul 2008 05:09:48 +0000 Subject: cpplib.h (NODE_CONDITIONAL): New. libcpp/ * include/cpplib.h (NODE_CONDITIONAL): New. (struct cpp_callbacks): New macro_to_expand field. (struct cpp_hashnode): Adjust size of flags and type fields. (cpp_peek_token): Prototype. * lex.c (cpp_peek_token): New function. (_cpp_temp_token): Protect pre-existing lookaheads. * macro.c (cpp_get_token): Expand any conditional macros. (_cpp_backup_tokens_direct): New. (_cpp_backup_tokens): Call _cpp_backup_tokens_direct. (warn_of_redefinition): Silently allow redefined conditional macros. (_cpp_create_definition): Remove the conditional flag when a user defines one of the conditional macros. * internal.h (_cpp_backup_tokens_direct): New prototype. gcc/ * c-common.h (C_CPP_HASHNODE): New macro. * coretypes.h (struct cpp_token): Forward declare. * doc/extend.texi (PowerPC AltiVec Built-in Functions): Document the context-sensitive keyword method. * config/rs6000/rs6000-c.c (__vector_keyword, vector_keyword, __pixel_keyword, pixel_keyword, __bool_keyword, bool_keyword, expand_bool_pixel): New. (altivec_categorize_keyword): New function. (init_vector_keywords): New function. (rs6000_macro_to_expand): Likewise. (rs6000_cpu_cpp_builtins): Enable context-sensitive macros if not compiling an ISO C dialect. gcc/testsuite/ * gcc.target/powerpc/altivec-macros.c: New test. * gcc.target/powerpc/altviec-26.c: Likewise. * gcc.dg/vmx/1b-06.c: Remove bool variable. * gcc.dg/vmx/1b-07.c: Likewise. * gcc.dg/vmx/1b-06-ansi.c: New test for the pre-define method. * gcc.dg/vmx/1b-07-ansi.c: Likewise. From-SVN: r137775 --- libcpp/macro.c | 55 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'libcpp/macro.c') diff --git a/libcpp/macro.c b/libcpp/macro.c index edc2856..1563d78 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1251,16 +1251,21 @@ cpp_get_token (cpp_reader *pfile) if (!(node->flags & NODE_DISABLED)) { - int ret; + int ret = 0; /* If not in a macro context, and we're going to start an expansion, record the location. */ if (can_set && !context->macro) pfile->invocation_location = result->src_loc; if (pfile->state.prevent_expansion) break; - ret = enter_macro_context (pfile, node, result); - if (ret) - { + + /* Conditional macros require that a predicate be evaluated + first. */ + if (((!(node->flags & NODE_CONDITIONAL)) + || (pfile->cb.macro_to_expand + && (node = pfile->cb.macro_to_expand (pfile, result)))) + && (ret = enter_macro_context (pfile, node, result))) + { if (pfile->state.in_directive || ret == 2) continue; return padding_token (pfile, result); @@ -1338,26 +1343,31 @@ cpp_scan_nooutput (cpp_reader *pfile) pfile->state.prevent_expansion--; } +/* Step back one or more tokens obtained from the lexer. */ +void +_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count) +{ + pfile->lookaheads += count; + while (count--) + { + pfile->cur_token--; + if (pfile->cur_token == pfile->cur_run->base + /* Possible with -fpreprocessed and no leading #line. */ + && pfile->cur_run->prev != NULL) + { + pfile->cur_run = pfile->cur_run->prev; + pfile->cur_token = pfile->cur_run->limit; + } + } +} + /* Step back one (or more) tokens. Can only step back more than 1 if they are from the lexer, and not from macro expansion. */ void _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) { if (pfile->context->prev == NULL) - { - pfile->lookaheads += count; - while (count--) - { - pfile->cur_token--; - if (pfile->cur_token == pfile->cur_run->base - /* Possible with -fpreprocessed and no leading #line. */ - && pfile->cur_run->prev != NULL) - { - pfile->cur_run = pfile->cur_run->prev; - pfile->cur_token = pfile->cur_run->limit; - } - } - } + _cpp_backup_tokens_direct (pfile, count); else { if (count != 1) @@ -1383,6 +1393,11 @@ warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node, if (node->flags & NODE_WARN) return true; + /* Redefinitions of conditional (context-sensitive) macros, on + the other hand, must be allowed silently. */ + if (node->flags & NODE_CONDITIONAL) + return false; + /* Redefinition of a macro is allowed if and only if the old and new definitions are the same. (6.10.3 paragraph 2). */ macro1 = node->value.macro; @@ -1815,6 +1830,10 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS")) node->flags |= NODE_WARN; + /* If user defines one of the conditional macros, remove the + conditional flag */ + node->flags &= ~NODE_CONDITIONAL; + return ok; } -- cgit v1.1