aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorBen Elliston <bje@au.ibm.com>2008-07-14 05:09:48 +0000
committerBen Elliston <bje@gcc.gnu.org>2008-07-14 15:09:48 +1000
commit5950c3c9a7729687a04f9b008e441959a2d9114d (patch)
tree5549f4ccea5a3b85211df500d0617fd3866b139f /libcpp
parentb463e8de6c7e9c7fe8ad2f4f4be126f58b23c07a (diff)
downloadgcc-5950c3c9a7729687a04f9b008e441959a2d9114d.zip
gcc-5950c3c9a7729687a04f9b008e441959a2d9114d.tar.gz
gcc-5950c3c9a7729687a04f9b008e441959a2d9114d.tar.bz2
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
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog17
-rw-r--r--libcpp/include/cpplib.h10
-rw-r--r--libcpp/internal.h1
-rw-r--r--libcpp/lex.c66
-rw-r--r--libcpp/macro.c55
5 files changed, 128 insertions, 21 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 2d29a30..9b3b53e 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,20 @@
+2008-07-14 Ben Elliston <bje@au.ibm.com>
+
+ * 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.
+
2008-06-13 Andrew Haley <aph@redhat.com>
PR preprocessor/33305
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 92ab291..a79c26d 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -484,6 +484,10 @@ struct cpp_callbacks
void (*read_pch) (cpp_reader *, const char *, int, const char *);
missing_header_cb missing_header;
+ /* Context-sensitive macro support. Returns macro (if any) that should
+ be expanded. */
+ cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *);
+
/* Called to emit a diagnostic if client_diagnostic option is true.
This callback receives the translated message. */
void (*error) (cpp_reader *, int, const char *, va_list *)
@@ -558,6 +562,7 @@ extern const char *progname;
#define NODE_DISABLED (1 << 5) /* A disabled macro. */
#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
#define NODE_USED (1 << 7) /* Dumped with -dU. */
+#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */
/* Different flavors of hash node. */
enum node_type
@@ -629,8 +634,8 @@ struct cpp_hashnode GTY(())
then index into directive table.
Otherwise, a NODE_OPERATOR. */
unsigned char rid_code; /* Rid code - for front ends. */
- ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */
- unsigned char flags; /* CPP flags. */
+ ENUM_BITFIELD(node_type) type : 7; /* CPP node type. */
+ unsigned int flags : 9; /* CPP flags. */
union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
};
@@ -717,6 +722,7 @@ extern const cpp_token *cpp_get_token_with_location (cpp_reader *,
extern const unsigned char *cpp_macro_definition (cpp_reader *,
const cpp_hashnode *);
extern void _cpp_backup_tokens (cpp_reader *, unsigned int);
+extern const cpp_token *cpp_peek_token (cpp_reader *, int);
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *,
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 65cac32..4fb4e43 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -532,6 +532,7 @@ extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *,
extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *,
const cpp_token *, unsigned int);
+extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int);
/* In identifiers.c */
extern void _cpp_init_hashtable (cpp_reader *, hash_table *);
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 70897fd..c1e009d 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -734,6 +734,49 @@ next_tokenrun (tokenrun *run)
return run->next;
}
+/* Look ahead in the input stream. */
+const cpp_token *
+cpp_peek_token (cpp_reader *pfile, int index)
+{
+ cpp_context *context = pfile->context;
+ const cpp_token *peektok;
+ int count;
+
+ /* First, scan through any pending cpp_context objects. */
+ while (context->prev)
+ {
+ ptrdiff_t sz = (context->direct_p
+ ? LAST (context).token - FIRST (context).token
+ : LAST (context).ptoken - FIRST (context).ptoken);
+
+ if (index < (int) sz)
+ return (context->direct_p
+ ? FIRST (context).token + index
+ : *(FIRST (context).ptoken + index));
+
+ index -= (int) sz;
+ context = context->prev;
+ }
+
+ /* We will have to read some new tokens after all (and do so
+ without invalidating preceding tokens). */
+ count = index;
+ pfile->keep_tokens++;
+
+ do
+ {
+ peektok = _cpp_lex_token (pfile);
+ if (peektok->type == CPP_EOF)
+ return peektok;
+ }
+ while (index--);
+
+ _cpp_backup_tokens_direct (pfile, count + 1);
+ pfile->keep_tokens--;
+
+ return peektok;
+}
+
/* Allocate a single token that is invalidated at the same time as the
rest of the tokens on the line. Has its line and col set to the
same as the last lexed token, so that diagnostics appear in the
@@ -742,9 +785,30 @@ cpp_token *
_cpp_temp_token (cpp_reader *pfile)
{
cpp_token *old, *result;
+ ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token;
+ ptrdiff_t la = (ptrdiff_t) pfile->lookaheads;
old = pfile->cur_token - 1;
- if (pfile->cur_token == pfile->cur_run->limit)
+ /* Any pre-existing lookaheads must not be clobbered. */
+ if (la)
+ {
+ if (sz <= la)
+ {
+ tokenrun *next = next_tokenrun (pfile->cur_run);
+
+ if (sz < la)
+ memmove (next->base + 1, next->base,
+ (la - sz) * sizeof (cpp_token));
+
+ next->base[0] = pfile->cur_run->limit[-1];
+ }
+
+ if (sz > 1)
+ memmove (pfile->cur_token + 1, pfile->cur_token,
+ MIN (la, sz - 1) * sizeof (cpp_token));
+ }
+
+ if (!sz && pfile->cur_token == pfile->cur_run->limit)
{
pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->cur_run->base;
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;
}