Commit 21b11495 by Zack Weinberg

cpplib.h (TTYPE_TABLE): Remove CPP_ and SPELL_ prefixes throughout.

2004-09-09  Matt Austern  <austern@apple.com>
	    Zack Weinberg  <zack@codesourcery.com>

	* include/cpplib.h (TTYPE_TABLE): Remove CPP_ and SPELL_
	prefixes throughout.  Add entry for PRAGMA.  Remove
	unnecessary "= 0" from EQ.
	(enum cpp_ttype): Adjust OP and TK definitions to restore
	prefixes, via token-paste.
	(CPP_LAST_EQ, CPP_FIRST_DIGRAPH, CPP_LAST_PUNCTUATOR, CPP_LAST_CPP_OP):
	Change from #defines to additional cpp_ttype enumerators.
	(struct cpp_options): Add defer_pragmas.
	(cpp_handle_deferred_pragma): Prototype new interface.

	* internal.h (struct cpp_reader): Add directive_result.
	* directives.c (struct pragma_entry): Add is_internal field;
	give boolean fields type bool.
	(start_directive): Initialize pfile->directive_result.type.
	(_cpp_do__Pragma): Likewise.
	(run_directive): Do not crash if pfile->buffer->prev is NULL.
	(insert_pragma_entry): Add 'internal' argument; set new->is_internal
	from it.
	(register_pragma): New static function, bulk of former
	cpp_register_pragma here; add 'internal' argument, pass along
	to insert_pragma_entry.
	(cpp_register_pragma): Now a wrapper around register_pragma which
	always passes false for 'internal' argument.
	(_cpp_init_internal_pragmas): Call register_pragma directly, passing
	true for 'internal'.
	(do_pragma): If CPP_OPTION (pfile, defer_pragmas) and this isn't
	an internal pragma, save text till the end of the line as a CPP_PRAGMA
	token instead of executing the pragma.
	(cpp_handle_deferred_pragma): New interface.
	* lex.c (token_spellings): Adjust OP and TK definitions to
	match changes to cpplib.h.
	(_cpp_lex_token): Check for a directive-result token and
	return it if present.
	(cpp_token_val_index): Handle CPP_PRAGMA.
	* macro.c (cpp_builtin_macro_text): Correct comment.
	(builtin_macro): Handle directive-result tokens from _cpp_do__Pragma.

From-SVN: r87247
parent b49ce401
2004-09-09 Matt Austern <austern@apple.com>
Zack Weinberg <zack@codesourcery.com>
* include/cpplib.h (TTYPE_TABLE): Remove CPP_ and SPELL_
prefixes throughout. Add entry for PRAGMA. Remove
unnecessary "= 0" from EQ.
(enum cpp_ttype): Adjust OP and TK definitions to restore
prefixes, via token-paste.
(CPP_LAST_EQ, CPP_FIRST_DIGRAPH, CPP_LAST_PUNCTUATOR, CPP_LAST_CPP_OP):
Change from #defines to additional cpp_ttype enumerators.
(struct cpp_options): Add defer_pragmas.
(cpp_handle_deferred_pragma): Prototype new interface.
* internal.h (struct cpp_reader): Add directive_result.
* directives.c (struct pragma_entry): Add is_internal field;
give boolean fields type bool.
(start_directive): Initialize pfile->directive_result.type.
(_cpp_do__Pragma): Likewise.
(run_directive): Do not crash if pfile->buffer->prev is NULL.
(insert_pragma_entry): Add 'internal' argument; set new->is_internal
from it.
(register_pragma): New static function, bulk of former
cpp_register_pragma here; add 'internal' argument, pass along
to insert_pragma_entry.
(cpp_register_pragma): Now a wrapper around register_pragma which
always passes false for 'internal' argument.
(_cpp_init_internal_pragmas): Call register_pragma directly, passing
true for 'internal'.
(do_pragma): If CPP_OPTION (pfile, defer_pragmas) and this isn't
an internal pragma, save text till the end of the line as a CPP_PRAGMA
token instead of executing the pragma.
(cpp_handle_deferred_pragma): New interface.
* lex.c (token_spellings): Adjust OP and TK definitions to
match changes to cpplib.h.
(_cpp_lex_token): Check for a directive-result token and
return it if present.
(cpp_token_val_index): Handle CPP_PRAGMA.
* macro.c (cpp_builtin_macro_text): Correct comment.
(builtin_macro): Handle directive-result tokens from _cpp_do__Pragma.
2004-09-06 Serge Belyshev <belyshev@lubercy.com> 2004-09-06 Serge Belyshev <belyshev@lubercy.com>
PR preprocessor/14699 PR preprocessor/14699
...@@ -38,9 +78,9 @@ ...@@ -38,9 +78,9 @@
* macro.c: Likewise. * macro.c: Likewise.
* cpplib.h (cpp_deps_style): Export enum with name. * cpplib.h (cpp_deps_style): Export enum with name.
2004-07-23 Matthias Klose <doko@debian.org> 2004-07-23 Matthias Klose <doko@debian.org>
* init.c (init_library): Use PACKAGE for the text domain. * init.c (init_library): Use PACKAGE for the text domain.
2004-07-16 Andris Pavenis <pavenis@latnet.lv> 2004-07-16 Andris Pavenis <pavenis@latnet.lv>
......
...@@ -44,7 +44,8 @@ struct pragma_entry ...@@ -44,7 +44,8 @@ struct pragma_entry
{ {
struct pragma_entry *next; struct pragma_entry *next;
const cpp_hashnode *pragma; /* Name and length. */ const cpp_hashnode *pragma; /* Name and length. */
int is_nspace; bool is_nspace;
bool is_internal;
union { union {
pragma_cb handler; pragma_cb handler;
struct pragma_entry *space; struct pragma_entry *space;
...@@ -106,7 +107,10 @@ static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *, ...@@ -106,7 +107,10 @@ static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
static struct pragma_entry *insert_pragma_entry (cpp_reader *, static struct pragma_entry *insert_pragma_entry (cpp_reader *,
struct pragma_entry **, struct pragma_entry **,
const cpp_hashnode *, const cpp_hashnode *,
pragma_cb); pragma_cb,
bool);
static void register_pragma (cpp_reader *, const char *, const char *,
pragma_cb, bool);
static int count_registered_pragmas (struct pragma_entry *); static int count_registered_pragmas (struct pragma_entry *);
static char ** save_registered_pragmas (struct pragma_entry *, char **); static char ** save_registered_pragmas (struct pragma_entry *, char **);
static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *, static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
...@@ -219,6 +223,7 @@ start_directive (cpp_reader *pfile) ...@@ -219,6 +223,7 @@ start_directive (cpp_reader *pfile)
/* Setup in-directive state. */ /* Setup in-directive state. */
pfile->state.in_directive = 1; pfile->state.in_directive = 1;
pfile->state.save_comments = 0; pfile->state.save_comments = 0;
pfile->directive_result.type = CPP_PADDING;
/* Some handlers need the position of the # for diagnostics. */ /* Some handlers need the position of the # for diagnostics. */
pfile->directive_line = pfile->line_table->highest_line; pfile->directive_line = pfile->line_table->highest_line;
...@@ -442,7 +447,7 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) ...@@ -442,7 +447,7 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
cpp_push_buffer (pfile, (const uchar *) buf, count, cpp_push_buffer (pfile, (const uchar *) buf, count,
/* from_stage3 */ true); /* from_stage3 */ true);
/* Disgusting hack. */ /* Disgusting hack. */
if (dir_no == T_PRAGMA) if (dir_no == T_PRAGMA && pfile->buffer->prev)
pfile->buffer->file = pfile->buffer->prev->file; pfile->buffer->file = pfile->buffer->prev->file;
start_directive (pfile); start_directive (pfile);
...@@ -954,10 +959,12 @@ lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma) ...@@ -954,10 +959,12 @@ lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma)
/* Create and insert a pragma entry for NAME at the beginning of a /* Create and insert a pragma entry for NAME at the beginning of a
singly-linked CHAIN. If handler is NULL, it is a namespace, singly-linked CHAIN. If handler is NULL, it is a namespace,
otherwise it is a pragma and its handler. */ otherwise it is a pragma and its handler. If INTERNAL is true
this pragma is being inserted by libcpp itself. */
static struct pragma_entry * static struct pragma_entry *
insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain, insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
const cpp_hashnode *pragma, pragma_cb handler) const cpp_hashnode *pragma, pragma_cb handler,
bool internal)
{ {
struct pragma_entry *new; struct pragma_entry *new;
...@@ -975,6 +982,7 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain, ...@@ -975,6 +982,7 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
new->u.space = NULL; new->u.space = NULL;
} }
new->is_internal = internal;
new->next = *chain; new->next = *chain;
*chain = new; *chain = new;
return new; return new;
...@@ -982,10 +990,12 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain, ...@@ -982,10 +990,12 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
/* Register a pragma NAME in namespace SPACE. If SPACE is null, it /* Register a pragma NAME in namespace SPACE. If SPACE is null, it
goes in the global namespace. HANDLER is the handler it will call, goes in the global namespace. HANDLER is the handler it will call,
which must be non-NULL. */ which must be non-NULL. INTERNAL is true if this is a pragma
void registered by cpplib itself, false if it is registered via
cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, cpp_register_pragma */
pragma_cb handler) static void
register_pragma (cpp_reader *pfile, const char *space, const char *name,
pragma_cb handler, bool internal)
{ {
struct pragma_entry **chain = &pfile->pragmas; struct pragma_entry **chain = &pfile->pragmas;
struct pragma_entry *entry; struct pragma_entry *entry;
...@@ -999,7 +1009,7 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, ...@@ -999,7 +1009,7 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
node = cpp_lookup (pfile, U space, strlen (space)); node = cpp_lookup (pfile, U space, strlen (space));
entry = lookup_pragma_entry (*chain, node); entry = lookup_pragma_entry (*chain, node);
if (!entry) if (!entry)
entry = insert_pragma_entry (pfile, chain, node, NULL); entry = insert_pragma_entry (pfile, chain, node, NULL, internal);
else if (!entry->is_nspace) else if (!entry->is_nspace)
goto clash; goto clash;
chain = &entry->u.space; chain = &entry->u.space;
...@@ -1022,7 +1032,17 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, ...@@ -1022,7 +1032,17 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
} }
else else
insert_pragma_entry (pfile, chain, node, handler); insert_pragma_entry (pfile, chain, node, handler, internal);
}
/* Register a pragma NAME in namespace SPACE. If SPACE is null, it
goes in the global namespace. HANDLER is the handler it will call,
which must be non-NULL. This function is exported from libcpp. */
void
cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
pragma_cb handler)
{
register_pragma (pfile, space, name, handler, false);
} }
/* Register the pragmas the preprocessor itself handles. */ /* Register the pragmas the preprocessor itself handles. */
...@@ -1030,12 +1050,12 @@ void ...@@ -1030,12 +1050,12 @@ void
_cpp_init_internal_pragmas (cpp_reader *pfile) _cpp_init_internal_pragmas (cpp_reader *pfile)
{ {
/* Pragmas in the global namespace. */ /* Pragmas in the global namespace. */
cpp_register_pragma (pfile, 0, "once", do_pragma_once); register_pragma (pfile, 0, "once", do_pragma_once, true);
/* New GCC-specific pragmas should be put in the GCC namespace. */ /* New GCC-specific pragmas should be put in the GCC namespace. */
cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison); register_pragma (pfile, "GCC", "poison", do_pragma_poison, true);
cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header); register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, true);
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency); register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, true);
} }
/* Return the number of registered pragmas in PE. */ /* Return the number of registered pragmas in PE. */
...@@ -1113,7 +1133,11 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved) ...@@ -1113,7 +1133,11 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved)
front end. C99 defines three pragmas and says that no macro front end. C99 defines three pragmas and says that no macro
expansion is to be performed on them; whether or not macro expansion is to be performed on them; whether or not macro
expansion happens for other pragmas is implementation defined. expansion happens for other pragmas is implementation defined.
This implementation never macro-expands the text after #pragma. */ This implementation never macro-expands the text after #pragma.
The library user has the option of deferring execution of
#pragmas not handled by cpplib, in which case they are converted
to CPP_PRAGMA tokens and inserted into the output stream. */
static void static void
do_pragma (cpp_reader *pfile) do_pragma (cpp_reader *pfile)
{ {
...@@ -1138,7 +1162,7 @@ do_pragma (cpp_reader *pfile) ...@@ -1138,7 +1162,7 @@ do_pragma (cpp_reader *pfile)
} }
} }
if (p) if (p && (p->is_internal || !CPP_OPTION (pfile, defer_pragmas)))
{ {
/* Since the handler below doesn't get the line number, that it /* Since the handler below doesn't get the line number, that it
might need for diagnostics, make sure it has the right might need for diagnostics, make sure it has the right
...@@ -1147,6 +1171,31 @@ do_pragma (cpp_reader *pfile) ...@@ -1147,6 +1171,31 @@ do_pragma (cpp_reader *pfile)
(*pfile->cb.line_change) (pfile, pragma_token, false); (*pfile->cb.line_change) (pfile, pragma_token, false);
(*p->u.handler) (pfile); (*p->u.handler) (pfile);
} }
else if (CPP_OPTION (pfile, defer_pragmas))
{
/* Squirrel away the pragma text. Pragmas are newline-terminated. */
const uchar *line_start, *line_end;
uchar *s;
cpp_string body;
cpp_token *ptok;
_cpp_backup_tokens (pfile, count);
line_start = CPP_BUFFER (pfile)->cur;
line_end = ustrchr (line_start, '\n');
body.len = (line_end - line_start) + 1;
s = _cpp_unaligned_alloc (pfile, body.len + 1);
memcpy (s, line_start, body.len);
s[body.len] = '\0';
body.text = s;
/* Create a CPP_PRAGMA token. */
ptok = &pfile->directive_result;
ptok->src_loc = pragma_token->src_loc;
ptok->type = CPP_PRAGMA;
ptok->flags = pragma_token->flags | NO_EXPAND;
ptok->val.str = body;
}
else if (pfile->cb.def_pragma) else if (pfile->cb.def_pragma)
{ {
_cpp_backup_tokens (pfile, count); _cpp_backup_tokens (pfile, count);
...@@ -1350,6 +1399,7 @@ void ...@@ -1350,6 +1399,7 @@ void
_cpp_do__Pragma (cpp_reader *pfile) _cpp_do__Pragma (cpp_reader *pfile)
{ {
const cpp_token *string = get__Pragma_string (pfile); const cpp_token *string = get__Pragma_string (pfile);
pfile->directive_result.type = CPP_PADDING;
if (string) if (string)
destringize_and_run (pfile, &string->val.str); destringize_and_run (pfile, &string->val.str);
...@@ -1358,6 +1408,29 @@ _cpp_do__Pragma (cpp_reader *pfile) ...@@ -1358,6 +1408,29 @@ _cpp_do__Pragma (cpp_reader *pfile)
"_Pragma takes a parenthesized string literal"); "_Pragma takes a parenthesized string literal");
} }
/* Handle a pragma that the front end deferred until now. */
void
cpp_handle_deferred_pragma (cpp_reader *pfile, const cpp_string *s)
{
cpp_context *saved_context = pfile->context;
cpp_token *saved_cur_token = pfile->cur_token;
tokenrun *saved_cur_run = pfile->cur_run;
bool saved_defer_pragmas = CPP_OPTION (pfile, defer_pragmas);
pfile->context = XNEW (cpp_context);
pfile->context->macro = 0;
pfile->context->prev = 0;
CPP_OPTION (pfile, defer_pragmas) = false;
run_directive (pfile, T_PRAGMA, s->text, s->len);
XDELETE (pfile->context);
pfile->context = saved_context;
pfile->cur_token = saved_cur_token;
pfile->cur_run = saved_cur_run;
CPP_OPTION (pfile, defer_pragmas) = saved_defer_pragmas;
}
/* Ignore #sccs on all systems. */ /* Ignore #sccs on all systems. */
static void static void
do_sccs (cpp_reader *pfile ATTRIBUTE_UNUSED) do_sccs (cpp_reader *pfile ATTRIBUTE_UNUSED)
......
...@@ -52,101 +52,102 @@ struct _cpp_file; ...@@ -52,101 +52,102 @@ struct _cpp_file;
'='. The lexer needs operators ending in '=', like ">>=", to be in '='. The lexer needs operators ending in '=', like ">>=", to be in
the same order as their counterparts without the '=', like ">>". */ the same order as their counterparts without the '=', like ">>". */
/* Positions in the table. */ #define TTYPE_TABLE \
#define CPP_LAST_EQ CPP_MAX OP(EQ, "=") \
#define CPP_FIRST_DIGRAPH CPP_HASH OP(NOT, "!") \
#define CPP_LAST_PUNCTUATOR CPP_DOT_STAR OP(GREATER, ">") /* compare */ \
#define CPP_LAST_CPP_OP CPP_LESS_EQ OP(LESS, "<") \
OP(PLUS, "+") /* math */ \
#define TTYPE_TABLE \ OP(MINUS, "-") \
OP(CPP_EQ = 0, "=") \ OP(MULT, "*") \
OP(CPP_NOT, "!") \ OP(DIV, "/") \
OP(CPP_GREATER, ">") /* compare */ \ OP(MOD, "%") \
OP(CPP_LESS, "<") \ OP(AND, "&") /* bit ops */ \
OP(CPP_PLUS, "+") /* math */ \ OP(OR, "|") \
OP(CPP_MINUS, "-") \ OP(XOR, "^") \
OP(CPP_MULT, "*") \ OP(RSHIFT, ">>") \
OP(CPP_DIV, "/") \ OP(LSHIFT, "<<") \
OP(CPP_MOD, "%") \ OP(MIN, "<?") /* extension */ \
OP(CPP_AND, "&") /* bit ops */ \ OP(MAX, ">?") \
OP(CPP_OR, "|") \ \
OP(CPP_XOR, "^") \ OP(COMPL, "~") \
OP(CPP_RSHIFT, ">>") \ OP(AND_AND, "&&") /* logical */ \
OP(CPP_LSHIFT, "<<") \ OP(OR_OR, "||") \
OP(CPP_MIN, "<?") /* extension */ \ OP(QUERY, "?") \
OP(CPP_MAX, ">?") \ OP(COLON, ":") \
\ OP(COMMA, ",") /* grouping */ \
OP(CPP_COMPL, "~") \ OP(OPEN_PAREN, "(") \
OP(CPP_AND_AND, "&&") /* logical */ \ OP(CLOSE_PAREN, ")") \
OP(CPP_OR_OR, "||") \ TK(EOF, NONE) \
OP(CPP_QUERY, "?") \ OP(EQ_EQ, "==") /* compare */ \
OP(CPP_COLON, ":") \ OP(NOT_EQ, "!=") \
OP(CPP_COMMA, ",") /* grouping */ \ OP(GREATER_EQ, ">=") \
OP(CPP_OPEN_PAREN, "(") \ OP(LESS_EQ, "<=") \
OP(CPP_CLOSE_PAREN, ")") \ \
TK(CPP_EOF, SPELL_NONE) \ /* These two are unary + / - in preprocessor expressions. */ \
OP(CPP_EQ_EQ, "==") /* compare */ \ OP(PLUS_EQ, "+=") /* math */ \
OP(CPP_NOT_EQ, "!=") \ OP(MINUS_EQ, "-=") \
OP(CPP_GREATER_EQ, ">=") \ \
OP(CPP_LESS_EQ, "<=") \ OP(MULT_EQ, "*=") \
\ OP(DIV_EQ, "/=") \
/* These two are unary + / - in preprocessor expressions. */ \ OP(MOD_EQ, "%=") \
OP(CPP_PLUS_EQ, "+=") /* math */ \ OP(AND_EQ, "&=") /* bit ops */ \
OP(CPP_MINUS_EQ, "-=") \ OP(OR_EQ, "|=") \
\ OP(XOR_EQ, "^=") \
OP(CPP_MULT_EQ, "*=") \ OP(RSHIFT_EQ, ">>=") \
OP(CPP_DIV_EQ, "/=") \ OP(LSHIFT_EQ, "<<=") \
OP(CPP_MOD_EQ, "%=") \ OP(MIN_EQ, "<?=") /* extension */ \
OP(CPP_AND_EQ, "&=") /* bit ops */ \ OP(MAX_EQ, ">?=") \
OP(CPP_OR_EQ, "|=") \ /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \
OP(CPP_XOR_EQ, "^=") \ OP(HASH, "#") /* digraphs */ \
OP(CPP_RSHIFT_EQ, ">>=") \ OP(PASTE, "##") \
OP(CPP_LSHIFT_EQ, "<<=") \ OP(OPEN_SQUARE, "[") \
OP(CPP_MIN_EQ, "<?=") /* extension */ \ OP(CLOSE_SQUARE, "]") \
OP(CPP_MAX_EQ, ">?=") \ OP(OPEN_BRACE, "{") \
/* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ OP(CLOSE_BRACE, "}") \
OP(CPP_HASH, "#") /* digraphs */ \ /* The remainder of the punctuation. Order is not significant. */ \
OP(CPP_PASTE, "##") \ OP(SEMICOLON, ";") /* structure */ \
OP(CPP_OPEN_SQUARE, "[") \ OP(ELLIPSIS, "...") \
OP(CPP_CLOSE_SQUARE, "]") \ OP(PLUS_PLUS, "++") /* increment */ \
OP(CPP_OPEN_BRACE, "{") \ OP(MINUS_MINUS, "--") \
OP(CPP_CLOSE_BRACE, "}") \ OP(DEREF, "->") /* accessors */ \
/* The remainder of the punctuation. Order is not significant. */ \ OP(DOT, ".") \
OP(CPP_SEMICOLON, ";") /* structure */ \ OP(SCOPE, "::") \
OP(CPP_ELLIPSIS, "...") \ OP(DEREF_STAR, "->*") \
OP(CPP_PLUS_PLUS, "++") /* increment */ \ OP(DOT_STAR, ".*") \
OP(CPP_MINUS_MINUS, "--") \ OP(ATSIGN, "@") /* used in Objective-C */ \
OP(CPP_DEREF, "->") /* accessors */ \ \
OP(CPP_DOT, ".") \ TK(NAME, IDENT) /* word */ \
OP(CPP_SCOPE, "::") \ TK(AT_NAME, IDENT) /* @word - Objective-C */ \
OP(CPP_DEREF_STAR, "->*") \ TK(NUMBER, LITERAL) /* 34_be+ta */ \
OP(CPP_DOT_STAR, ".*") \ \
OP(CPP_ATSIGN, "@") /* used in Objective-C */ \ TK(CHAR, LITERAL) /* 'char' */ \
\ TK(WCHAR, LITERAL) /* L'char' */ \
TK(CPP_NAME, SPELL_IDENT) /* word */ \ TK(OTHER, LITERAL) /* stray punctuation */ \
TK(CPP_AT_NAME, SPELL_IDENT) /* @word - Objective-C */ \ \
TK(CPP_NUMBER, SPELL_LITERAL) /* 34_be+ta */ \ TK(STRING, LITERAL) /* "string" */ \
\ TK(WSTRING, LITERAL) /* L"string" */ \
TK(CPP_CHAR, SPELL_LITERAL) /* 'char' */ \ TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \
TK(CPP_WCHAR, SPELL_LITERAL) /* L'char' */ \ TK(HEADER_NAME, LITERAL) /* <stdio.h> in #include */ \
TK(CPP_OTHER, SPELL_LITERAL) /* stray punctuation */ \ \
\ TK(COMMENT, LITERAL) /* Only if output comments. */ \
TK(CPP_STRING, SPELL_LITERAL) /* "string" */ \ /* SPELL_LITERAL happens to DTRT. */ \
TK(CPP_WSTRING, SPELL_LITERAL) /* L"string" */ \ TK(MACRO_ARG, NONE) /* Macro argument. */ \
TK(CPP_OBJC_STRING, SPELL_LITERAL) /* @"string" - Objective-C */ \ TK(PRAGMA, NONE) /* Only if deferring pragmas */ \
TK(CPP_HEADER_NAME, SPELL_LITERAL) /* <stdio.h> in #include */ \ TK(PADDING, NONE) /* Whitespace for -E. */
\
TK(CPP_COMMENT, SPELL_LITERAL) /* Only if output comments. */ \ #define OP(e, s) CPP_ ## e,
/* SPELL_LITERAL happens to DTRT. */ \ #define TK(e, s) CPP_ ## e,
TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
TK(CPP_PADDING, SPELL_NONE) /* Whitespace for cpp0. */
#define OP(e, s) e,
#define TK(e, s) e,
enum cpp_ttype enum cpp_ttype
{ {
TTYPE_TABLE TTYPE_TABLE
N_TTYPES N_TTYPES,
/* Positions in the table. */
CPP_LAST_EQ = CPP_MAX,
CPP_FIRST_DIGRAPH = CPP_HASH,
CPP_LAST_PUNCTUATOR= CPP_DOT_STAR,
CPP_LAST_CPP_OP = CPP_LESS_EQ
}; };
#undef OP #undef OP
#undef TK #undef TK
...@@ -409,6 +410,10 @@ struct cpp_options ...@@ -409,6 +410,10 @@ struct cpp_options
/* Nonzero means __STDC__ should have the value 0 in system headers. */ /* Nonzero means __STDC__ should have the value 0 in system headers. */
unsigned char stdc_0_in_system_headers; unsigned char stdc_0_in_system_headers;
/* True means return pragmas as tokens rather than processing
them directly. */
bool defer_pragmas;
}; };
/* Callback for header lookup for HEADER, which is the name of a /* Callback for header lookup for HEADER, which is the name of a
...@@ -634,6 +639,7 @@ extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *, ...@@ -634,6 +639,7 @@ extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
unsigned char *); unsigned char *);
extern void cpp_register_pragma (cpp_reader *, const char *, const char *, extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
void (*) (cpp_reader *)); void (*) (cpp_reader *));
extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *);
extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
const cpp_token *); const cpp_token *);
extern const cpp_token *cpp_get_token (cpp_reader *); extern const cpp_token *cpp_get_token (cpp_reader *);
......
...@@ -322,6 +322,9 @@ struct cpp_reader ...@@ -322,6 +322,9 @@ struct cpp_reader
/* If in_directive, the directive if known. */ /* If in_directive, the directive if known. */
const struct directive *directive; const struct directive *directive;
/* Token generated while handling a directive, if any. */
cpp_token directive_result;
/* Search paths for include files. */ /* Search paths for include files. */
struct cpp_dir *quote_include; /* "" */ struct cpp_dir *quote_include; /* "" */
struct cpp_dir *bracket_include; /* <> */ struct cpp_dir *bracket_include; /* <> */
......
...@@ -41,8 +41,8 @@ struct token_spelling ...@@ -41,8 +41,8 @@ struct token_spelling
static const unsigned char *const digraph_spellings[] = static const unsigned char *const digraph_spellings[] =
{ U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" }; { U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" };
#define OP(e, s) { SPELL_OPERATOR, U s }, #define OP(e, s) { SPELL_OPERATOR, U s },
#define TK(e, s) { s, U #e }, #define TK(e, s) { SPELL_ ## s, U #e },
static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE };
#undef OP #undef OP
#undef TK #undef TK
...@@ -736,7 +736,16 @@ _cpp_lex_token (cpp_reader *pfile) ...@@ -736,7 +736,16 @@ _cpp_lex_token (cpp_reader *pfile)
handles the directive as normal. */ handles the directive as normal. */
&& pfile->state.parsing_args != 1 && pfile->state.parsing_args != 1
&& _cpp_handle_directive (pfile, result->flags & PREV_WHITE)) && _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
continue; {
if (pfile->directive_result.type == CPP_PADDING)
continue;
else
{
result = &pfile->directive_result;
break;
}
}
if (pfile->cb.line_change && !pfile->state.skipping) if (pfile->cb.line_change && !pfile->state.skipping)
pfile->cb.line_change (pfile, result, pfile->state.parsing_args); pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
} }
...@@ -1573,6 +1582,8 @@ cpp_token_val_index (cpp_token *tok) ...@@ -1573,6 +1582,8 @@ cpp_token_val_index (cpp_token *tok)
return CPP_TOKEN_FLD_ARG_NO; return CPP_TOKEN_FLD_ARG_NO;
else if (tok->type == CPP_PADDING) else if (tok->type == CPP_PADDING)
return CPP_TOKEN_FLD_SOURCE; return CPP_TOKEN_FLD_SOURCE;
else if (tok->type == CPP_PRAGMA)
return CPP_TOKEN_FLD_STR;
/* else fall through */ /* else fall through */
default: default:
return CPP_TOKEN_FLD_NONE; return CPP_TOKEN_FLD_NONE;
......
...@@ -109,10 +109,8 @@ static const char * const monthnames[] = ...@@ -109,10 +109,8 @@ static const char * const monthnames[] =
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}; };
/* Handle builtin macros like __FILE__, and push the resulting token /* Helper function for builtin_macro. Returns the text generated by
on the context stack. Also handles _Pragma, for which no new token a builtin macro. */
is created. Returns 1 if it generates a new token context, 0 to
return the token to the caller. */
const uchar * const uchar *
_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
{ {
...@@ -245,8 +243,8 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) ...@@ -245,8 +243,8 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
} }
/* Convert builtin macros like __FILE__ to a token and push it on the /* Convert builtin macros like __FILE__ to a token and push it on the
context stack. Also handles _Pragma, for which no new token is context stack. Also handles _Pragma, for which a new token may not
created. Returns 1 if it generates a new token context, 0 to be created. Returns 1 if it generates a new token context, 0 to
return the token to the caller. */ return the token to the caller. */
static int static int
builtin_macro (cpp_reader *pfile, cpp_hashnode *node) builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
...@@ -263,6 +261,13 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) ...@@ -263,6 +261,13 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
return 0; return 0;
_cpp_do__Pragma (pfile); _cpp_do__Pragma (pfile);
if (pfile->directive_result.type == CPP_PRAGMA)
{
cpp_token *tok = _cpp_temp_token (pfile);
*tok = pfile->directive_result;
push_token_context (pfile, NULL, tok, 1);
}
return 1; return 1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment