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
This commit is contained in:
parent
b49ce401c2
commit
21b11495d7
@ -1,3 +1,43 @@
|
||||
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>
|
||||
|
||||
PR preprocessor/14699
|
||||
|
@ -44,7 +44,8 @@ struct pragma_entry
|
||||
{
|
||||
struct pragma_entry *next;
|
||||
const cpp_hashnode *pragma; /* Name and length. */
|
||||
int is_nspace;
|
||||
bool is_nspace;
|
||||
bool is_internal;
|
||||
union {
|
||||
pragma_cb handler;
|
||||
struct pragma_entry *space;
|
||||
@ -106,7 +107,10 @@ static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
|
||||
static struct pragma_entry *insert_pragma_entry (cpp_reader *,
|
||||
struct pragma_entry **,
|
||||
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 char ** save_registered_pragmas (struct pragma_entry *, char **);
|
||||
static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
|
||||
@ -219,6 +223,7 @@ start_directive (cpp_reader *pfile)
|
||||
/* Setup in-directive state. */
|
||||
pfile->state.in_directive = 1;
|
||||
pfile->state.save_comments = 0;
|
||||
pfile->directive_result.type = CPP_PADDING;
|
||||
|
||||
/* Some handlers need the position of the # for diagnostics. */
|
||||
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)
|
||||
cpp_push_buffer (pfile, (const uchar *) buf, count,
|
||||
/* from_stage3 */ true);
|
||||
/* Disgusting hack. */
|
||||
if (dir_no == T_PRAGMA)
|
||||
if (dir_no == T_PRAGMA && pfile->buffer->prev)
|
||||
pfile->buffer->file = pfile->buffer->prev->file;
|
||||
start_directive (pfile);
|
||||
|
||||
@ -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
|
||||
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 *
|
||||
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;
|
||||
|
||||
@ -975,6 +982,7 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
|
||||
new->u.space = NULL;
|
||||
}
|
||||
|
||||
new->is_internal = internal;
|
||||
new->next = *chain;
|
||||
*chain = new;
|
||||
return new;
|
||||
@ -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
|
||||
goes in the global namespace. HANDLER is the handler it will call,
|
||||
which must be non-NULL. */
|
||||
void
|
||||
cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
|
||||
pragma_cb handler)
|
||||
which must be non-NULL. INTERNAL is true if this is a pragma
|
||||
registered by cpplib itself, false if it is registered via
|
||||
cpp_register_pragma */
|
||||
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 *entry;
|
||||
@ -999,7 +1009,7 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
|
||||
node = cpp_lookup (pfile, U space, strlen (space));
|
||||
entry = lookup_pragma_entry (*chain, node);
|
||||
if (!entry)
|
||||
entry = insert_pragma_entry (pfile, chain, node, NULL);
|
||||
entry = insert_pragma_entry (pfile, chain, node, NULL, internal);
|
||||
else if (!entry->is_nspace)
|
||||
goto clash;
|
||||
chain = &entry->u.space;
|
||||
@ -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);
|
||||
}
|
||||
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. */
|
||||
@ -1030,12 +1050,12 @@ void
|
||||
_cpp_init_internal_pragmas (cpp_reader *pfile)
|
||||
{
|
||||
/* 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. */
|
||||
cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
|
||||
cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
|
||||
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
|
||||
register_pragma (pfile, "GCC", "poison", do_pragma_poison, true);
|
||||
register_pragma (pfile, "GCC", "system_header", do_pragma_system_header, true);
|
||||
register_pragma (pfile, "GCC", "dependency", do_pragma_dependency, true);
|
||||
}
|
||||
|
||||
/* Return the number of registered pragmas in PE. */
|
||||
@ -1113,7 +1133,11 @@ _cpp_restore_pragma_names (cpp_reader *pfile, char **saved)
|
||||
front end. C99 defines three pragmas and says that no macro
|
||||
expansion is to be performed on them; whether or not macro
|
||||
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
|
||||
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
|
||||
might need for diagnostics, make sure it has the right
|
||||
@ -1147,6 +1171,31 @@ do_pragma (cpp_reader *pfile)
|
||||
(*pfile->cb.line_change) (pfile, pragma_token, false);
|
||||
(*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)
|
||||
{
|
||||
_cpp_backup_tokens (pfile, count);
|
||||
@ -1350,6 +1399,7 @@ void
|
||||
_cpp_do__Pragma (cpp_reader *pfile)
|
||||
{
|
||||
const cpp_token *string = get__Pragma_string (pfile);
|
||||
pfile->directive_result.type = CPP_PADDING;
|
||||
|
||||
if (string)
|
||||
destringize_and_run (pfile, &string->val.str);
|
||||
@ -1358,6 +1408,29 @@ _cpp_do__Pragma (cpp_reader *pfile)
|
||||
"_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. */
|
||||
static void
|
||||
do_sccs (cpp_reader *pfile ATTRIBUTE_UNUSED)
|
||||
|
@ -52,101 +52,102 @@ struct _cpp_file;
|
||||
'='. The lexer needs operators ending in '=', like ">>=", to be in
|
||||
the same order as their counterparts without the '=', like ">>". */
|
||||
|
||||
/* Positions in the table. */
|
||||
#define CPP_LAST_EQ CPP_MAX
|
||||
#define CPP_FIRST_DIGRAPH CPP_HASH
|
||||
#define CPP_LAST_PUNCTUATOR CPP_DOT_STAR
|
||||
#define CPP_LAST_CPP_OP CPP_LESS_EQ
|
||||
|
||||
#define TTYPE_TABLE \
|
||||
OP(CPP_EQ = 0, "=") \
|
||||
OP(CPP_NOT, "!") \
|
||||
OP(CPP_GREATER, ">") /* compare */ \
|
||||
OP(CPP_LESS, "<") \
|
||||
OP(CPP_PLUS, "+") /* math */ \
|
||||
OP(CPP_MINUS, "-") \
|
||||
OP(CPP_MULT, "*") \
|
||||
OP(CPP_DIV, "/") \
|
||||
OP(CPP_MOD, "%") \
|
||||
OP(CPP_AND, "&") /* bit ops */ \
|
||||
OP(CPP_OR, "|") \
|
||||
OP(CPP_XOR, "^") \
|
||||
OP(CPP_RSHIFT, ">>") \
|
||||
OP(CPP_LSHIFT, "<<") \
|
||||
OP(CPP_MIN, "<?") /* extension */ \
|
||||
OP(CPP_MAX, ">?") \
|
||||
OP(EQ, "=") \
|
||||
OP(NOT, "!") \
|
||||
OP(GREATER, ">") /* compare */ \
|
||||
OP(LESS, "<") \
|
||||
OP(PLUS, "+") /* math */ \
|
||||
OP(MINUS, "-") \
|
||||
OP(MULT, "*") \
|
||||
OP(DIV, "/") \
|
||||
OP(MOD, "%") \
|
||||
OP(AND, "&") /* bit ops */ \
|
||||
OP(OR, "|") \
|
||||
OP(XOR, "^") \
|
||||
OP(RSHIFT, ">>") \
|
||||
OP(LSHIFT, "<<") \
|
||||
OP(MIN, "<?") /* extension */ \
|
||||
OP(MAX, ">?") \
|
||||
\
|
||||
OP(CPP_COMPL, "~") \
|
||||
OP(CPP_AND_AND, "&&") /* logical */ \
|
||||
OP(CPP_OR_OR, "||") \
|
||||
OP(CPP_QUERY, "?") \
|
||||
OP(CPP_COLON, ":") \
|
||||
OP(CPP_COMMA, ",") /* grouping */ \
|
||||
OP(CPP_OPEN_PAREN, "(") \
|
||||
OP(CPP_CLOSE_PAREN, ")") \
|
||||
TK(CPP_EOF, SPELL_NONE) \
|
||||
OP(CPP_EQ_EQ, "==") /* compare */ \
|
||||
OP(CPP_NOT_EQ, "!=") \
|
||||
OP(CPP_GREATER_EQ, ">=") \
|
||||
OP(CPP_LESS_EQ, "<=") \
|
||||
OP(COMPL, "~") \
|
||||
OP(AND_AND, "&&") /* logical */ \
|
||||
OP(OR_OR, "||") \
|
||||
OP(QUERY, "?") \
|
||||
OP(COLON, ":") \
|
||||
OP(COMMA, ",") /* grouping */ \
|
||||
OP(OPEN_PAREN, "(") \
|
||||
OP(CLOSE_PAREN, ")") \
|
||||
TK(EOF, NONE) \
|
||||
OP(EQ_EQ, "==") /* compare */ \
|
||||
OP(NOT_EQ, "!=") \
|
||||
OP(GREATER_EQ, ">=") \
|
||||
OP(LESS_EQ, "<=") \
|
||||
\
|
||||
/* These two are unary + / - in preprocessor expressions. */ \
|
||||
OP(CPP_PLUS_EQ, "+=") /* math */ \
|
||||
OP(CPP_MINUS_EQ, "-=") \
|
||||
OP(PLUS_EQ, "+=") /* math */ \
|
||||
OP(MINUS_EQ, "-=") \
|
||||
\
|
||||
OP(CPP_MULT_EQ, "*=") \
|
||||
OP(CPP_DIV_EQ, "/=") \
|
||||
OP(CPP_MOD_EQ, "%=") \
|
||||
OP(CPP_AND_EQ, "&=") /* bit ops */ \
|
||||
OP(CPP_OR_EQ, "|=") \
|
||||
OP(CPP_XOR_EQ, "^=") \
|
||||
OP(CPP_RSHIFT_EQ, ">>=") \
|
||||
OP(CPP_LSHIFT_EQ, "<<=") \
|
||||
OP(CPP_MIN_EQ, "<?=") /* extension */ \
|
||||
OP(CPP_MAX_EQ, ">?=") \
|
||||
OP(MULT_EQ, "*=") \
|
||||
OP(DIV_EQ, "/=") \
|
||||
OP(MOD_EQ, "%=") \
|
||||
OP(AND_EQ, "&=") /* bit ops */ \
|
||||
OP(OR_EQ, "|=") \
|
||||
OP(XOR_EQ, "^=") \
|
||||
OP(RSHIFT_EQ, ">>=") \
|
||||
OP(LSHIFT_EQ, "<<=") \
|
||||
OP(MIN_EQ, "<?=") /* extension */ \
|
||||
OP(MAX_EQ, ">?=") \
|
||||
/* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \
|
||||
OP(CPP_HASH, "#") /* digraphs */ \
|
||||
OP(CPP_PASTE, "##") \
|
||||
OP(CPP_OPEN_SQUARE, "[") \
|
||||
OP(CPP_CLOSE_SQUARE, "]") \
|
||||
OP(CPP_OPEN_BRACE, "{") \
|
||||
OP(CPP_CLOSE_BRACE, "}") \
|
||||
OP(HASH, "#") /* digraphs */ \
|
||||
OP(PASTE, "##") \
|
||||
OP(OPEN_SQUARE, "[") \
|
||||
OP(CLOSE_SQUARE, "]") \
|
||||
OP(OPEN_BRACE, "{") \
|
||||
OP(CLOSE_BRACE, "}") \
|
||||
/* The remainder of the punctuation. Order is not significant. */ \
|
||||
OP(CPP_SEMICOLON, ";") /* structure */ \
|
||||
OP(CPP_ELLIPSIS, "...") \
|
||||
OP(CPP_PLUS_PLUS, "++") /* increment */ \
|
||||
OP(CPP_MINUS_MINUS, "--") \
|
||||
OP(CPP_DEREF, "->") /* accessors */ \
|
||||
OP(CPP_DOT, ".") \
|
||||
OP(CPP_SCOPE, "::") \
|
||||
OP(CPP_DEREF_STAR, "->*") \
|
||||
OP(CPP_DOT_STAR, ".*") \
|
||||
OP(CPP_ATSIGN, "@") /* used in Objective-C */ \
|
||||
OP(SEMICOLON, ";") /* structure */ \
|
||||
OP(ELLIPSIS, "...") \
|
||||
OP(PLUS_PLUS, "++") /* increment */ \
|
||||
OP(MINUS_MINUS, "--") \
|
||||
OP(DEREF, "->") /* accessors */ \
|
||||
OP(DOT, ".") \
|
||||
OP(SCOPE, "::") \
|
||||
OP(DEREF_STAR, "->*") \
|
||||
OP(DOT_STAR, ".*") \
|
||||
OP(ATSIGN, "@") /* used in Objective-C */ \
|
||||
\
|
||||
TK(CPP_NAME, SPELL_IDENT) /* word */ \
|
||||
TK(CPP_AT_NAME, SPELL_IDENT) /* @word - Objective-C */ \
|
||||
TK(CPP_NUMBER, SPELL_LITERAL) /* 34_be+ta */ \
|
||||
TK(NAME, IDENT) /* word */ \
|
||||
TK(AT_NAME, IDENT) /* @word - Objective-C */ \
|
||||
TK(NUMBER, LITERAL) /* 34_be+ta */ \
|
||||
\
|
||||
TK(CPP_CHAR, SPELL_LITERAL) /* 'char' */ \
|
||||
TK(CPP_WCHAR, SPELL_LITERAL) /* L'char' */ \
|
||||
TK(CPP_OTHER, SPELL_LITERAL) /* stray punctuation */ \
|
||||
TK(CHAR, LITERAL) /* 'char' */ \
|
||||
TK(WCHAR, LITERAL) /* L'char' */ \
|
||||
TK(OTHER, LITERAL) /* stray punctuation */ \
|
||||
\
|
||||
TK(CPP_STRING, SPELL_LITERAL) /* "string" */ \
|
||||
TK(CPP_WSTRING, SPELL_LITERAL) /* L"string" */ \
|
||||
TK(CPP_OBJC_STRING, SPELL_LITERAL) /* @"string" - Objective-C */ \
|
||||
TK(CPP_HEADER_NAME, SPELL_LITERAL) /* <stdio.h> in #include */ \
|
||||
TK(STRING, LITERAL) /* "string" */ \
|
||||
TK(WSTRING, LITERAL) /* L"string" */ \
|
||||
TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \
|
||||
TK(HEADER_NAME, LITERAL) /* <stdio.h> in #include */ \
|
||||
\
|
||||
TK(CPP_COMMENT, SPELL_LITERAL) /* Only if output comments. */ \
|
||||
TK(COMMENT, LITERAL) /* Only if output comments. */ \
|
||||
/* SPELL_LITERAL happens to DTRT. */ \
|
||||
TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
|
||||
TK(CPP_PADDING, SPELL_NONE) /* Whitespace for cpp0. */
|
||||
TK(MACRO_ARG, NONE) /* Macro argument. */ \
|
||||
TK(PRAGMA, NONE) /* Only if deferring pragmas */ \
|
||||
TK(PADDING, NONE) /* Whitespace for -E. */
|
||||
|
||||
#define OP(e, s) e,
|
||||
#define TK(e, s) e,
|
||||
#define OP(e, s) CPP_ ## e,
|
||||
#define TK(e, s) CPP_ ## e,
|
||||
enum cpp_ttype
|
||||
{
|
||||
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 TK
|
||||
@ -409,6 +410,10 @@ struct cpp_options
|
||||
|
||||
/* Nonzero means __STDC__ should have the value 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
|
||||
@ -634,6 +639,7 @@ extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
|
||||
unsigned char *);
|
||||
extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
|
||||
void (*) (cpp_reader *));
|
||||
extern void cpp_handle_deferred_pragma (cpp_reader *, const cpp_string *);
|
||||
extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
|
||||
const cpp_token *);
|
||||
extern const cpp_token *cpp_get_token (cpp_reader *);
|
||||
|
@ -322,6 +322,9 @@ struct cpp_reader
|
||||
/* If in_directive, the directive if known. */
|
||||
const struct directive *directive;
|
||||
|
||||
/* Token generated while handling a directive, if any. */
|
||||
cpp_token directive_result;
|
||||
|
||||
/* Search paths for include files. */
|
||||
struct cpp_dir *quote_include; /* "" */
|
||||
struct cpp_dir *bracket_include; /* <> */
|
||||
|
13
libcpp/lex.c
13
libcpp/lex.c
@ -42,7 +42,7 @@ static const unsigned char *const digraph_spellings[] =
|
||||
{ U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" };
|
||||
|
||||
#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 };
|
||||
#undef OP
|
||||
#undef TK
|
||||
@ -736,7 +736,16 @@ _cpp_lex_token (cpp_reader *pfile)
|
||||
handles the directive as normal. */
|
||||
&& pfile->state.parsing_args != 1
|
||||
&& _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
|
||||
{
|
||||
if (pfile->directive_result.type == CPP_PADDING)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
result = &pfile->directive_result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pfile->cb.line_change && !pfile->state.skipping)
|
||||
pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
|
||||
}
|
||||
@ -1573,6 +1582,8 @@ cpp_token_val_index (cpp_token *tok)
|
||||
return CPP_TOKEN_FLD_ARG_NO;
|
||||
else if (tok->type == CPP_PADDING)
|
||||
return CPP_TOKEN_FLD_SOURCE;
|
||||
else if (tok->type == CPP_PRAGMA)
|
||||
return CPP_TOKEN_FLD_STR;
|
||||
/* else fall through */
|
||||
default:
|
||||
return CPP_TOKEN_FLD_NONE;
|
||||
|
@ -109,10 +109,8 @@ static const char * const monthnames[] =
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
/* Handle builtin macros like __FILE__, and push the resulting token
|
||||
on the context stack. Also handles _Pragma, for which no new token
|
||||
is created. Returns 1 if it generates a new token context, 0 to
|
||||
return the token to the caller. */
|
||||
/* Helper function for builtin_macro. Returns the text generated by
|
||||
a builtin macro. */
|
||||
const uchar *
|
||||
_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
|
||||
context stack. Also handles _Pragma, for which no new token is
|
||||
created. Returns 1 if it generates a new token context, 0 to
|
||||
context stack. Also handles _Pragma, for which a new token may not
|
||||
be created. Returns 1 if it generates a new token context, 0 to
|
||||
return the token to the caller. */
|
||||
static int
|
||||
builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
|
||||
@ -263,6 +261,13 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
|
||||
return 0;
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user