cpplib.h (struct cpp_name): Now struct cpp_string.
* cpplib.h (struct cpp_name): Now struct cpp_string. (CPP_INT, CPP_FLOAT, CPP_NUMBER, CPP_COMMENT, CPP_HEADER_NAME): Change to type S. (struct cpp_token): Rename 'name' field to 'str'. Add 'node' field, a cpp_hashnode *. All references to val.name updated to use val.str or val.node as appropriate. (struct cpp_reader): Add spec_nodes field. (cpp_idcmp): Now cpp_ideq; takes a token * and a char *. * cpphash.h (struct spec_nodes): New. (enum spell_type): Reorder. Only SPELL_STRING tokens use val.str. All references to 'spelling > SPELL_NONE' updated to match. (CPP_IN_SYSTEM_HEADER): Check pfile->buffer and pfile->buffer->inc are not NULL before dereferencing them. * cpplex.c (parse_name): Take a pointer to the current token, plus current position and limit as args; return the new position; don't copy the text of a name into the string buffer, instead call cpp_lookup and store the node pointer. If extending a token, copy out the text of the old into a scratch buffer, append the new, look that up and store the new node pointer. Inline. (maybe_paste_with_next): If the result of paste is a NAME, then look up the pasted text and store its node pointer. (lex_line): Adjust for new parse_name interface. Check for L"str", L'str' using spec_nodes->n_L. (spell_token): SPELL_IDENT tokens have their spelling in val.node->name. Handle SPELL_STRING tokens that don't have string delimiters. (_cpp_expand_name_space, (can_paste): Check for L ## "str" using spec_nodes->n_L. (cpp_get_token, special_symbol): No need to call cpp_lookup. (cpp_idcmp): Now cpp_ideq; take a token * and a const char *; return 1=equal 0=not, not a tristate. * cpphash.c (var_args_str): Delete. (find_param): Compare node fields directly. (is__va_args__): Use CPP_PEDANTIC. Just compare token->val.node with spec_nodes->n__VA_ARGS__. (dump_funlike_macro): Don't use var_args_str. * cpplib.c (_cpp_check_directive): Just walk through spec_nodes->dirs comparing pointers. (get_define_node, do_pragma_poison, detect_if_not_defined, parse_ifdef): The identifier has already been looked up. (do_ifdef, do_ifndef): parse_ifdef won't return a poisoned node. (do_if): Only call detect_if_not_defined at beginning of file. (_cpp_parse_assertion): Only copy string pointers for SPELL_STRING tokens. (pragma_dispatch): Take a node pointer and examine its name field. (_cpp_init_stacks): Also initialize the spec_nodes structure. * cppinit.c (cpp_reader_init): Call _cpp_init_stacks after _cpp_init_macros. (cpp_cleanup): Free pfile->spec_nodes. Call _cpp_cleanup_* in reverse order from the corresponding _cpp_init_* routines. * cppexp.c (parse_number, parse_charconst, parse_defined, lex): Check val.node->type instead of calling cpp_defined. Use spec_nodes entries where appropriate. * fix-header.c, scan-decls.c: Update for interface changes. From-SVN: r34926
This commit is contained in:
parent
ffc14f3159
commit
bfb9dc7faa
@ -1,3 +1,72 @@
|
||||
2000-07-08 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* cpplib.h (struct cpp_name): Now struct cpp_string.
|
||||
(CPP_INT, CPP_FLOAT, CPP_NUMBER, CPP_COMMENT,
|
||||
CPP_HEADER_NAME): Change to type S.
|
||||
(struct cpp_token): Rename 'name' field to 'str'. Add 'node'
|
||||
field, a cpp_hashnode *. All references to val.name updated
|
||||
to use val.str or val.node as appropriate.
|
||||
(struct cpp_reader): Add spec_nodes field.
|
||||
(cpp_idcmp): Now cpp_ideq; takes a token * and a char *.
|
||||
|
||||
* cpphash.h (struct spec_nodes): New.
|
||||
(enum spell_type): Reorder. Only SPELL_STRING tokens use
|
||||
val.str. All references to 'spelling > SPELL_NONE' updated to
|
||||
match.
|
||||
|
||||
(CPP_IN_SYSTEM_HEADER): Check pfile->buffer and
|
||||
pfile->buffer->inc are not NULL before dereferencing them.
|
||||
|
||||
* cpplex.c (parse_name): Take a pointer to the current token,
|
||||
plus current position and limit as args; return the new
|
||||
position; don't copy the text of a name into the string
|
||||
buffer, instead call cpp_lookup and store the node pointer.
|
||||
If extending a token, copy out the text of the old into a
|
||||
scratch buffer, append the new, look that up and store the new
|
||||
node pointer. Inline.
|
||||
(maybe_paste_with_next): If the result of paste is a NAME,
|
||||
then look up the pasted text and store its node pointer.
|
||||
(lex_line): Adjust for new parse_name interface.
|
||||
Check for L"str", L'str' using spec_nodes->n_L.
|
||||
(spell_token): SPELL_IDENT tokens have their spelling in
|
||||
val.node->name. Handle SPELL_STRING tokens that don't have
|
||||
string delimiters.
|
||||
(_cpp_expand_name_space,
|
||||
(can_paste): Check for L ## "str" using spec_nodes->n_L.
|
||||
(cpp_get_token, special_symbol): No need to call cpp_lookup.
|
||||
(cpp_idcmp): Now cpp_ideq; take a token * and a const char *;
|
||||
return 1=equal 0=not, not a tristate.
|
||||
|
||||
* cpphash.c (var_args_str): Delete.
|
||||
(find_param): Compare node fields directly.
|
||||
(is__va_args__): Use CPP_PEDANTIC. Just compare
|
||||
token->val.node with spec_nodes->n__VA_ARGS__.
|
||||
(dump_funlike_macro): Don't use var_args_str.
|
||||
|
||||
* cpplib.c (_cpp_check_directive): Just walk through
|
||||
spec_nodes->dirs comparing pointers.
|
||||
(get_define_node, do_pragma_poison, detect_if_not_defined,
|
||||
parse_ifdef): The identifier has already been looked up.
|
||||
(do_ifdef, do_ifndef): parse_ifdef won't return a poisoned
|
||||
node.
|
||||
(do_if): Only call detect_if_not_defined at beginning of file.
|
||||
(_cpp_parse_assertion): Only copy string pointers for
|
||||
SPELL_STRING tokens.
|
||||
(pragma_dispatch): Take a node pointer and examine its name
|
||||
field.
|
||||
(_cpp_init_stacks): Also initialize the spec_nodes structure.
|
||||
|
||||
* cppinit.c (cpp_reader_init): Call _cpp_init_stacks after
|
||||
_cpp_init_macros.
|
||||
(cpp_cleanup): Free pfile->spec_nodes. Call _cpp_cleanup_* in
|
||||
reverse order from the corresponding _cpp_init_* routines.
|
||||
|
||||
* cppexp.c (parse_number, parse_charconst, parse_defined,
|
||||
lex): Check val.node->type instead of calling cpp_defined.
|
||||
Use spec_nodes entries where appropriate.
|
||||
|
||||
* fix-header.c, scan-decls.c: Update for interface changes.
|
||||
|
||||
2000-07-08 Geoffrey Keating <geoffk@cygnus.com>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_emit_move): Fix conditions for
|
||||
|
23
gcc/cppexp.c
23
gcc/cppexp.c
@ -137,10 +137,10 @@ parse_number (pfile, tok)
|
||||
const cpp_token *tok;
|
||||
{
|
||||
struct op op;
|
||||
const U_CHAR *start = tok->val.name.text;
|
||||
const U_CHAR *end = start + tok->val.name.len;
|
||||
const U_CHAR *start = tok->val.str.text;
|
||||
const U_CHAR *end = start + tok->val.str.len;
|
||||
const U_CHAR *p = start;
|
||||
int c, i, nsuff;
|
||||
int c = 0, i, nsuff;
|
||||
unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base;
|
||||
int base = 10;
|
||||
int overflow = 0;
|
||||
@ -261,8 +261,8 @@ parse_charconst (pfile, tok)
|
||||
int num_bits;
|
||||
unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK;
|
||||
int max_chars;
|
||||
const U_CHAR *ptr = tok->val.name.text;
|
||||
const U_CHAR *end = ptr + tok->val.name.len;
|
||||
const U_CHAR *ptr = tok->val.str.text;
|
||||
const U_CHAR *end = ptr + tok->val.str.len;
|
||||
|
||||
int c = -1;
|
||||
|
||||
@ -304,8 +304,7 @@ parse_charconst (pfile, tok)
|
||||
/* If char type is signed, sign-extend the constant. */
|
||||
num_bits = num_chars * width;
|
||||
|
||||
if (cpp_defined (pfile, U"__CHAR_UNSIGNED__",
|
||||
sizeof ("__CHAR_UNSIGNED__")-1)
|
||||
if (pfile->spec_nodes->n__CHAR_UNSIGNED__->type != T_VOID
|
||||
|| ((result >> (num_bits - 1)) & 1) == 0)
|
||||
op.value = result & ((unsigned HOST_WIDEST_INT) ~0
|
||||
>> (HOST_BITS_PER_WIDEST_INT - num_bits));
|
||||
@ -345,9 +344,12 @@ parse_defined (pfile)
|
||||
if (paren && _cpp_get_raw_token (pfile)->type != CPP_CLOSE_PAREN)
|
||||
SYNTAX_ERROR ("missing close paren after \"defined\"");
|
||||
|
||||
if (tok->val.node->type == T_POISON)
|
||||
SYNTAX_ERROR2 ("attempt to use poisoned \"%s\"", tok->val.node->name);
|
||||
|
||||
op.value = tok->val.node->type != T_VOID;
|
||||
op.unsignedp = 0;
|
||||
op.op = CPP_INT;
|
||||
op.value = cpp_defined (pfile, tok->val.name.text, tok->val.name.len);
|
||||
return op;
|
||||
|
||||
syntax_error:
|
||||
@ -419,7 +421,7 @@ lex (pfile, skip_evaluation)
|
||||
SYNTAX_ERROR2 ("invalid character '\\%03o' in #if", tok->val.aux);
|
||||
|
||||
case CPP_NAME:
|
||||
if (!cpp_idcmp (tok->val.name.text, tok->val.name.len, "defined"))
|
||||
if (tok->val.node == pfile->spec_nodes->n_defined)
|
||||
return parse_defined (pfile);
|
||||
|
||||
op.op = CPP_INT;
|
||||
@ -427,8 +429,7 @@ lex (pfile, skip_evaluation)
|
||||
op.value = 0;
|
||||
|
||||
if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
|
||||
cpp_warning (pfile, "\"%.*s\" is not defined",
|
||||
(int) tok->val.name.len, tok->val.name.text);
|
||||
cpp_warning (pfile, "\"%s\" is not defined", tok->val.node->name);
|
||||
return op;
|
||||
|
||||
case CPP_HASH:
|
||||
|
@ -61,8 +61,6 @@ static int save_expansion PARAMS((cpp_reader *, cpp_toklist *,
|
||||
static unsigned int find_param PARAMS ((const cpp_token *,
|
||||
const cpp_token *));
|
||||
|
||||
static const unsigned char var_args_str[] = "__VA_ARGS__";
|
||||
|
||||
/* Calculate hash of a string of length LEN. */
|
||||
unsigned int
|
||||
_cpp_calc_hash (str, len)
|
||||
@ -131,7 +129,7 @@ cpp_lookup (pfile, name, len)
|
||||
p = obstack_alloc (pfile->hash_ob, sizeof (cpp_hashnode) + len);
|
||||
new = (cpp_hashnode *)p;
|
||||
p += offsetof (cpp_hashnode, name);
|
||||
|
||||
|
||||
new->type = T_VOID;
|
||||
new->length = len;
|
||||
new->hash = hash;
|
||||
@ -189,9 +187,7 @@ find_param (first, token)
|
||||
if (first->type == CPP_NAME)
|
||||
{
|
||||
param++;
|
||||
if (first->val.name.len == token->val.name.len
|
||||
&& !memcmp (first->val.name.text, token->val.name.text,
|
||||
token->val.name.len))
|
||||
if (first->val.node == token->val.node)
|
||||
return param;
|
||||
}
|
||||
|
||||
@ -206,15 +202,13 @@ is__va_args__ (pfile, token)
|
||||
cpp_reader *pfile;
|
||||
const cpp_token *token;
|
||||
{
|
||||
if (!CPP_OPTION (pfile, pedantic)
|
||||
|| token->val.name.len != sizeof (var_args_str) - 1
|
||||
|| ustrncmp (token->val.name.text, var_args_str,
|
||||
sizeof (var_args_str) - 1))
|
||||
if (!CPP_PEDANTIC (pfile)
|
||||
|| token->val.node != pfile->spec_nodes->n__VA_ARGS__)
|
||||
return 0;
|
||||
|
||||
cpp_pedwarn_with_line (pfile, token->line, token->col,
|
||||
"\"%s\" is only valid in the replacement list of a function-like macro",
|
||||
var_args_str);
|
||||
token->val.node->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -257,7 +251,7 @@ count_params (pfile, first, list)
|
||||
if (is__va_args__ (pfile, token))
|
||||
goto out;
|
||||
|
||||
params_len += token->val.name.len + 1;
|
||||
params_len += token->val.node->length + 1;
|
||||
prev_ident = 1;
|
||||
list->paramc++;
|
||||
|
||||
@ -265,9 +259,8 @@ count_params (pfile, first, list)
|
||||
if (find_param (first, token))
|
||||
{
|
||||
cpp_error_with_line (pfile, token->line, token->col,
|
||||
"duplicate macro parameter \"%.*s\"",
|
||||
(int) token->val.name.len,
|
||||
token->val.name.text);
|
||||
"duplicate macro parameter \"%s\"",
|
||||
token->val.node->name);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@ -297,19 +290,16 @@ count_params (pfile, first, list)
|
||||
case CPP_ELLIPSIS:
|
||||
/* Convert ISO-style var_args to named varargs by changing
|
||||
the ellipsis into an identifier with name __VA_ARGS__.
|
||||
This simplifies other handling. We can safely have its
|
||||
text outside list->namebuf because there is no reason to
|
||||
extend the size of the list's namebuf (and thus change
|
||||
the pointer) in do_define. */
|
||||
This simplifies other handling. */
|
||||
if (!prev_ident)
|
||||
{
|
||||
cpp_token *tok = (cpp_token *) token;
|
||||
|
||||
tok->type = CPP_NAME;
|
||||
tok->val.name.len = sizeof (var_args_str) - 1;
|
||||
tok->val.name.text = var_args_str; /* Safe. */
|
||||
tok->val.node = pfile->spec_nodes->n__VA_ARGS__;
|
||||
list->paramc++;
|
||||
|
||||
params_len += tok->val.node->length + 1;
|
||||
|
||||
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99))
|
||||
cpp_pedwarn (pfile,
|
||||
"C89 does not permit anon varargs macros");
|
||||
@ -344,9 +334,9 @@ count_params (pfile, first, list)
|
||||
for (temp = first; temp <= token; temp++)
|
||||
if (temp->type == CPP_NAME)
|
||||
{
|
||||
memcpy (buf, temp->val.name.text, temp->val.name.len);
|
||||
buf += temp->val.name.len;
|
||||
*buf++ = '\0';
|
||||
/* copy null too */
|
||||
memcpy (buf, temp->val.node->name, temp->val.node->length + 1);
|
||||
buf += temp->val.node->length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,8 +483,8 @@ save_expansion (pfile, list, first, first_param)
|
||||
return 1;
|
||||
}
|
||||
ntokens++;
|
||||
if (token_spellings[token->type].type > SPELL_NONE)
|
||||
len += token->val.name.len;
|
||||
if (token_spellings[token->type].type == SPELL_STRING)
|
||||
len += token->val.str.len;
|
||||
}
|
||||
|
||||
/* Allocate space to hold the tokens. Empty expansions are stored
|
||||
@ -553,11 +543,11 @@ save_expansion (pfile, list, first, first_param)
|
||||
|
||||
/* Copy the token. */
|
||||
*dest = *token;
|
||||
if (token_spellings[token->type].type > SPELL_NONE)
|
||||
if (token_spellings[token->type].type == SPELL_STRING)
|
||||
{
|
||||
memcpy (buf, token->val.name.text, token->val.name.len);
|
||||
dest->val.name.text = buf;
|
||||
buf += dest->val.name.len;
|
||||
memcpy (buf, token->val.str.text, token->val.str.len);
|
||||
dest->val.str.text = buf;
|
||||
buf += dest->val.str.len;
|
||||
}
|
||||
dest++;
|
||||
}
|
||||
@ -664,9 +654,9 @@ dump_funlike_macro (pfile, node)
|
||||
CPP_PUTS(pfile, ", ", 2);
|
||||
else if (list->flags & VAR_ARGS)
|
||||
{
|
||||
if (!ustrcmp (param, var_args_str))
|
||||
pfile->limit -= sizeof (var_args_str) - 1;
|
||||
CPP_PUTS (pfile, "...", 3);
|
||||
if (!ustrcmp (param, U"__VA_ARGS__"))
|
||||
pfile->limit -= sizeof (U"__VA_ARGS__") - 1;
|
||||
CPP_PUTS_Q (pfile, "...", 3);
|
||||
}
|
||||
param += len + 1;
|
||||
}
|
||||
|
@ -25,15 +25,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
typedef unsigned char U_CHAR;
|
||||
#define U (const U_CHAR *) /* Intended use: U"string" */
|
||||
|
||||
/* Order here matters. Those beyond SPELL_NONE store their spelling
|
||||
in the token list, and it's length in the token->val.name.len. */
|
||||
/* Tokens with SPELL_STRING store their spelling in the token list,
|
||||
and it's length in the token->val.name.len. */
|
||||
enum spell_type
|
||||
{
|
||||
SPELL_OPERATOR = 0,
|
||||
SPELL_CHAR,
|
||||
SPELL_NONE,
|
||||
SPELL_IDENT,
|
||||
SPELL_STRING
|
||||
SPELL_STRING,
|
||||
SPELL_NONE
|
||||
};
|
||||
|
||||
struct token_spelling
|
||||
@ -116,6 +116,20 @@ struct include_file
|
||||
time_t date; /* modification date of file, if known */
|
||||
};
|
||||
|
||||
/* Special nodes - identifiers with predefined significance.
|
||||
Note that the array length of dirs[] must be kept in sync with
|
||||
cpplib.c's dtable[]. */
|
||||
struct spec_nodes
|
||||
{
|
||||
cpp_hashnode *n_L; /* L"str" */
|
||||
cpp_hashnode *n_defined; /* #if defined */
|
||||
cpp_hashnode *n__STRICT_ANSI__; /* STDC_0_IN_SYSTEM_HEADERS */
|
||||
cpp_hashnode *n__CHAR_UNSIGNED__; /* plain char is unsigned */
|
||||
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
|
||||
cpp_hashnode *dirs[19]; /* 19 directives counting #sccs */
|
||||
};
|
||||
|
||||
|
||||
/* The cmacro works like this: If it's NULL, the file is to be
|
||||
included again. If it's NEVER_REREAD, the file is never to be
|
||||
included again. Otherwise it is a macro hashnode, and the file is
|
||||
@ -173,7 +187,9 @@ extern unsigned char _cpp_IStable[256];
|
||||
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
|
||||
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
|
||||
#define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional)
|
||||
#define CPP_IN_SYSTEM_HEADER(PFILE) (CPP_BUFFER (PFILE)->inc->sysp)
|
||||
#define CPP_IN_SYSTEM_HEADER(PFILE) \
|
||||
(CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->inc \
|
||||
&& CPP_BUFFER (PFILE)->inc->sysp)
|
||||
#define CPP_PEDANTIC(PF) \
|
||||
(CPP_OPTION (PF, pedantic) && !CPP_IN_SYSTEM_HEADER (PF))
|
||||
#define CPP_WTRADITIONAL(PF) \
|
||||
|
@ -421,8 +421,8 @@ cpp_reader_init (pfile)
|
||||
CPP_OPTION (pfile, pending) =
|
||||
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
|
||||
|
||||
_cpp_init_stacks (pfile);
|
||||
_cpp_init_macros (pfile);
|
||||
_cpp_init_stacks (pfile);
|
||||
_cpp_init_includes (pfile);
|
||||
}
|
||||
|
||||
@ -469,10 +469,13 @@ cpp_cleanup (pfile)
|
||||
if (pfile->deps)
|
||||
deps_free (pfile->deps);
|
||||
|
||||
if (pfile->spec_nodes)
|
||||
free (pfile->spec_nodes);
|
||||
|
||||
_cpp_free_temp_tokens (pfile);
|
||||
_cpp_cleanup_includes (pfile);
|
||||
_cpp_cleanup_stacks (pfile);
|
||||
_cpp_cleanup_macros (pfile);
|
||||
_cpp_cleanup_includes (pfile);
|
||||
_cpp_free_temp_tokens (pfile);
|
||||
}
|
||||
|
||||
|
||||
|
242
gcc/cpplex.c
242
gcc/cpplex.c
@ -73,8 +73,9 @@ static const unsigned char *backslash_start PARAMS ((cpp_reader *,
|
||||
static int skip_block_comment PARAMS ((cpp_reader *));
|
||||
static int skip_line_comment PARAMS ((cpp_reader *));
|
||||
static void skip_whitespace PARAMS ((cpp_reader *, int));
|
||||
static void parse_name PARAMS ((cpp_reader *, cpp_toklist *, cpp_name *));
|
||||
static void parse_number PARAMS ((cpp_reader *, cpp_toklist *, cpp_name *));
|
||||
static const U_CHAR *parse_name PARAMS ((cpp_reader *, cpp_token *,
|
||||
const U_CHAR *, const U_CHAR *));
|
||||
static void parse_number PARAMS ((cpp_reader *, cpp_toklist *, cpp_string *));
|
||||
static void parse_string PARAMS ((cpp_reader *, cpp_toklist *, cpp_token *,
|
||||
unsigned int));
|
||||
static int trigraph_ok PARAMS ((cpp_reader *, const unsigned char *));
|
||||
@ -111,9 +112,9 @@ static void release_temp_tokens PARAMS ((cpp_reader *));
|
||||
static U_CHAR * quote_string PARAMS ((U_CHAR *, const U_CHAR *, unsigned int));
|
||||
static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
|
||||
|
||||
#define INIT_TOKEN_NAME(list, token) \
|
||||
do {(token)->val.name.len = 0; \
|
||||
(token)->val.name.text = (list)->namebuf + (list)->name_used; \
|
||||
#define INIT_TOKEN_STR(list, token) \
|
||||
do {(token)->val.str.len = 0; \
|
||||
(token)->val.str.text = (list)->namebuf + (list)->name_used; \
|
||||
} while (0)
|
||||
|
||||
#define VALID_SIGN(c, prevc) \
|
||||
@ -148,8 +149,12 @@ static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
|
||||
|
||||
/* An upper bound on the number of bytes needed to spell a token,
|
||||
including preceding whitespace. */
|
||||
#define TOKEN_LEN(token) (5 + (token_spellings[(token)->type].type > \
|
||||
SPELL_NONE ? (token)->val.name.len: 0))
|
||||
#define TOKEN_SPELL(token) token_spellings[(token)->type].type
|
||||
#define TOKEN_LEN(token) (5 + (TOKEN_SPELL(token) == SPELL_STRING \
|
||||
? (token)->val.str.len \
|
||||
: (TOKEN_SPELL(token) == SPELL_IDENT \
|
||||
? (token)->val.node->length \
|
||||
: 0)))
|
||||
|
||||
#define T(e, s) {SPELL_OPERATOR, (const U_CHAR *) s},
|
||||
#define I(e, s) {SPELL_IDENT, s},
|
||||
@ -443,8 +448,8 @@ _cpp_glue_header_name (pfile)
|
||||
hdr = get_temp_token (pfile);
|
||||
hdr->type = CPP_HEADER_NAME;
|
||||
hdr->flags = 0;
|
||||
hdr->val.name.text = buf;
|
||||
hdr->val.name.len = len;
|
||||
hdr->val.str.text = buf;
|
||||
hdr->val.str.len = len;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
@ -469,8 +474,8 @@ _cpp_expand_name_space (list, len)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < list->tokens_used; i++)
|
||||
if (token_spellings[list->tokens[i].type].type > SPELL_NONE)
|
||||
list->tokens[i].val.name.text += (list->namebuf - old_namebuf);
|
||||
if (token_spellings[list->tokens[i].type].type == SPELL_STRING)
|
||||
list->tokens[i].val.str.text += (list->namebuf - old_namebuf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,10 +588,11 @@ _cpp_equiv_tokens (a, b)
|
||||
case SPELL_NONE:
|
||||
return a->val.aux == b->val.aux; /* arg_no or character. */
|
||||
case SPELL_IDENT:
|
||||
return a->val.node == b->val.node;
|
||||
case SPELL_STRING:
|
||||
return (a->val.name.len == b->val.name.len
|
||||
&& !memcmp (a->val.name.text, b->val.name.text,
|
||||
a->val.name.len));
|
||||
return (a->val.str.len == b->val.str.len
|
||||
&& !memcmp (a->val.str.text, b->val.str.text,
|
||||
a->val.str.len));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -611,34 +617,19 @@ _cpp_equiv_toklists (a, b)
|
||||
}
|
||||
|
||||
/* Utility routine:
|
||||
Compares, in the manner of strcmp(3), the token beginning at TOKEN
|
||||
and extending for LEN characters to the NUL-terminated string
|
||||
STRING. Typical usage:
|
||||
|
||||
if (! cpp_idcmp (pfile->token_buffer + here, CPP_WRITTEN (pfile) - here,
|
||||
"inline"))
|
||||
{ ... }
|
||||
*/
|
||||
Compares, the token TOKEN to the NUL-terminated string STRING.
|
||||
TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */
|
||||
|
||||
int
|
||||
cpp_idcmp (token, len, string)
|
||||
const U_CHAR *token;
|
||||
size_t len;
|
||||
cpp_ideq (token, string)
|
||||
const cpp_token *token;
|
||||
const char *string;
|
||||
{
|
||||
size_t len2 = strlen (string);
|
||||
int r;
|
||||
|
||||
if ((r = memcmp (token, string, MIN (len, len2))))
|
||||
return r;
|
||||
|
||||
/* The longer of the two strings sorts after the shorter. */
|
||||
if (len == len2)
|
||||
if (token->type != CPP_NAME)
|
||||
return 0;
|
||||
else if (len < len2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
|
||||
return !ustrcmp (token->val.node->name, (const U_CHAR *)string);
|
||||
}
|
||||
|
||||
/* Lexing algorithm.
|
||||
@ -965,51 +956,43 @@ skip_whitespace (pfile, in_directive)
|
||||
}
|
||||
|
||||
/* Parse (append) an identifier. */
|
||||
static void
|
||||
parse_name (pfile, list, name)
|
||||
static inline const U_CHAR *
|
||||
parse_name (pfile, tok, cur, rlimit)
|
||||
cpp_reader *pfile;
|
||||
cpp_toklist *list;
|
||||
cpp_name *name;
|
||||
cpp_token *tok;
|
||||
const U_CHAR *cur, *rlimit;
|
||||
{
|
||||
const unsigned char *name_limit;
|
||||
unsigned char *namebuf;
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
register const unsigned char *cur = buffer->cur;
|
||||
const U_CHAR *name = cur;
|
||||
unsigned int len;
|
||||
|
||||
expanded:
|
||||
name_limit = list->namebuf + list->name_cap;
|
||||
namebuf = list->namebuf + list->name_used;
|
||||
|
||||
for (; cur < buffer->rlimit && namebuf < name_limit; )
|
||||
while (cur < rlimit)
|
||||
{
|
||||
unsigned char c = *namebuf = *cur; /* Copy a single char. */
|
||||
|
||||
if (! is_idchar(c))
|
||||
goto out;
|
||||
namebuf++;
|
||||
cur++;
|
||||
if (! is_idchar (*cur))
|
||||
break;
|
||||
/* $ is not a legal identifier character in the standard, but is
|
||||
commonly accepted as an extension. Don't warn about it in
|
||||
skipped conditional blocks. */
|
||||
if (c == '$' && CPP_PEDANTIC (pfile) && ! pfile->skipping)
|
||||
if (*cur == '$' && CPP_PEDANTIC (pfile) && ! pfile->skipping)
|
||||
{
|
||||
buffer->cur = cur;
|
||||
CPP_BUFFER (pfile)->cur = cur;
|
||||
cpp_pedwarn (pfile, "'$' character in identifier");
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
len = cur - name;
|
||||
|
||||
/* Run out of name space? */
|
||||
if (cur < buffer->rlimit)
|
||||
if (tok->val.node)
|
||||
{
|
||||
list->name_used = namebuf - list->namebuf;
|
||||
auto_expand_name_space (list);
|
||||
goto expanded;
|
||||
unsigned int oldlen = tok->val.node->length;
|
||||
U_CHAR *newname = alloca (oldlen + len);
|
||||
memcpy (newname, tok->val.node->name, oldlen);
|
||||
memcpy (newname + oldlen, name, len);
|
||||
len += oldlen;
|
||||
name = newname;
|
||||
}
|
||||
|
||||
out:
|
||||
buffer->cur = cur;
|
||||
name->len = namebuf - name->text;
|
||||
list->name_used = namebuf - list->namebuf;
|
||||
tok->val.node = cpp_lookup (pfile, name, len);
|
||||
return cur;
|
||||
}
|
||||
|
||||
/* Parse (append) a number. */
|
||||
@ -1017,7 +1000,7 @@ static void
|
||||
parse_number (pfile, list, name)
|
||||
cpp_reader *pfile;
|
||||
cpp_toklist *list;
|
||||
cpp_name *name;
|
||||
cpp_string *name;
|
||||
{
|
||||
const unsigned char *name_limit;
|
||||
unsigned char *namebuf;
|
||||
@ -1057,7 +1040,7 @@ parse_number (pfile, list, name)
|
||||
}
|
||||
|
||||
/* Places a string terminated by an unescaped TERMINATOR into a
|
||||
cpp_name, which should be expandable and thus at the top of the
|
||||
cpp_string, which should be expandable and thus at the top of the
|
||||
list's stack. Handles embedded trigraphs, if necessary, and
|
||||
escaped newlines.
|
||||
|
||||
@ -1073,7 +1056,7 @@ parse_string (pfile, list, token, terminator)
|
||||
unsigned int terminator;
|
||||
{
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
cpp_name *name = &token->val.name;
|
||||
cpp_string *name = &token->val.str;
|
||||
register const unsigned char *cur = buffer->cur;
|
||||
const unsigned char *name_limit;
|
||||
unsigned char *namebuf;
|
||||
@ -1221,9 +1204,9 @@ save_comment (list, token, from, len, type)
|
||||
if (list->name_used + len > list->name_cap)
|
||||
_cpp_expand_name_space (list, len);
|
||||
|
||||
INIT_TOKEN_NAME (list, token);
|
||||
INIT_TOKEN_STR (list, token);
|
||||
token->type = CPP_COMMENT;
|
||||
token->val.name.len = len;
|
||||
token->val.str.len = len;
|
||||
|
||||
buffer = list->namebuf + list->name_used;
|
||||
list->name_used += len;
|
||||
@ -1326,21 +1309,21 @@ lex_line (pfile, list)
|
||||
prev_dot = PREV_TOKEN_TYPE == CPP_DOT && IMMED_TOKEN ();
|
||||
if (prev_dot)
|
||||
cur_token--;
|
||||
INIT_TOKEN_NAME (list, cur_token);
|
||||
INIT_TOKEN_STR (list, cur_token);
|
||||
/* Prepend an immediately previous CPP_DOT token. */
|
||||
if (prev_dot)
|
||||
{
|
||||
if (list->name_cap == list->name_used)
|
||||
auto_expand_name_space (list);
|
||||
|
||||
cur_token->val.name.len = 1;
|
||||
cur_token->val.str.len = 1;
|
||||
list->namebuf[list->name_used++] = '.';
|
||||
}
|
||||
|
||||
continue_number:
|
||||
cur_token->type = CPP_NUMBER; /* Before parse_number. */
|
||||
buffer->cur = cur;
|
||||
parse_number (pfile, list, &cur_token->val.name);
|
||||
parse_number (pfile, list, &cur_token->val.str);
|
||||
cur = buffer->cur;
|
||||
}
|
||||
/* Check for # 123 form of #line. */
|
||||
@ -1364,13 +1347,11 @@ lex_line (pfile, list)
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
cur--; /* Backup character. */
|
||||
INIT_TOKEN_NAME (list, cur_token);
|
||||
cur_token->val.node = 0;
|
||||
cur_token->type = CPP_NAME; /* Identifier, macro etc. */
|
||||
|
||||
continue_name:
|
||||
buffer->cur = cur;
|
||||
parse_name (pfile, list, &cur_token->val.name);
|
||||
cur = buffer->cur;
|
||||
cur = parse_name (pfile, cur_token, cur, buffer->rlimit);
|
||||
|
||||
if (MIGHT_BE_DIRECTIVE ())
|
||||
list->directive = _cpp_check_directive (pfile, cur_token,
|
||||
@ -1395,18 +1376,15 @@ lex_line (pfile, list)
|
||||
cur_token->type = c == '\'' ? CPP_CHAR : CPP_STRING;
|
||||
/* Do we have a wide string? */
|
||||
if (cur_token[-1].type == CPP_NAME && IMMED_TOKEN ()
|
||||
&& cur_token[-1].val.name.len == 1
|
||||
&& cur_token[-1].val.name.text[0] == 'L'
|
||||
&& cur_token[-1].val.node == pfile->spec_nodes->n_L
|
||||
&& !CPP_TRADITIONAL (pfile))
|
||||
{
|
||||
/* No need for 'L' any more. */
|
||||
list->name_used--;
|
||||
(--cur_token)->type = (c == '\'' ? CPP_WCHAR : CPP_WSTRING);
|
||||
}
|
||||
|
||||
do_parse_string:
|
||||
/* Here c is one of ' " or >. */
|
||||
INIT_TOKEN_NAME (list, cur_token);
|
||||
INIT_TOKEN_STR (list, cur_token);
|
||||
buffer->cur = cur;
|
||||
parse_string (pfile, list, cur_token, c);
|
||||
cur = buffer->cur;
|
||||
@ -1797,7 +1775,7 @@ lex_line (pfile, list)
|
||||
{
|
||||
if (first[1].type == CPP_NAME)
|
||||
cpp_error (pfile, "invalid preprocessing directive #%.*s",
|
||||
(int) first[1].val.name.len, first[1].val.name.text);
|
||||
(int) first[1].val.node->length, first[1].val.node->name);
|
||||
else
|
||||
cpp_error (pfile, "invalid preprocessing directive");
|
||||
}
|
||||
@ -1900,23 +1878,27 @@ spell_token (pfile, token, buffer)
|
||||
break;
|
||||
|
||||
case SPELL_IDENT:
|
||||
memcpy (buffer, token->val.name.text, token->val.name.len);
|
||||
buffer += token->val.name.len;
|
||||
memcpy (buffer, token->val.node->name, token->val.node->length);
|
||||
buffer += token->val.node->length;
|
||||
break;
|
||||
|
||||
case SPELL_STRING:
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (token->type == CPP_WSTRING || token->type == CPP_WCHAR)
|
||||
*buffer++ = 'L';
|
||||
c = '\'';
|
||||
|
||||
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
|
||||
c = '"';
|
||||
*buffer++ = c;
|
||||
memcpy (buffer, token->val.name.text, token->val.name.len);
|
||||
buffer += token->val.name.len;
|
||||
*buffer++ = c;
|
||||
*buffer++ = '"';
|
||||
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
|
||||
*buffer++ = '\'';
|
||||
|
||||
memcpy (buffer, token->val.str.text, token->val.str.len);
|
||||
buffer += token->val.str.len;
|
||||
|
||||
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
|
||||
*buffer++ = '"';
|
||||
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
|
||||
*buffer++ = '\'';
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2096,7 +2078,7 @@ is_macro_disabled (pfile, expansion, token)
|
||||
if (CPP_OPTION (pfile, warn_traditional))
|
||||
cpp_warning (pfile,
|
||||
"function macro %.*s must be used with arguments in traditional C",
|
||||
(int) token->val.name.len, token->val.name.text);
|
||||
(int) token->val.node->length, token->val.node->name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -2314,8 +2296,8 @@ make_string_token (token, text, len)
|
||||
buf = (U_CHAR *) xmalloc (len * 4);
|
||||
token->type = CPP_STRING;
|
||||
token->flags = 0;
|
||||
token->val.name.text = buf;
|
||||
token->val.name.len = quote_string (buf, text, len) - buf;
|
||||
token->val.str.text = buf;
|
||||
token->val.str.len = quote_string (buf, text, len) - buf;
|
||||
return token;
|
||||
}
|
||||
|
||||
@ -2335,8 +2317,8 @@ alloc_number_token (pfile, number)
|
||||
|
||||
result->type = CPP_NUMBER;
|
||||
result->flags = 0;
|
||||
result->val.name.text = (U_CHAR *) buf;
|
||||
result->val.name.len = strlen (buf);
|
||||
result->val.str.text = (U_CHAR *) buf;
|
||||
result->val.str.len = strlen (buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2369,10 +2351,10 @@ release_temp_tokens (pfile)
|
||||
{
|
||||
cpp_token *token = pfile->temp_tokens[--pfile->temp_used];
|
||||
|
||||
if (token_spellings[token->type].type > SPELL_NONE)
|
||||
if (token_spellings[token->type].type == SPELL_STRING)
|
||||
{
|
||||
free ((char *) token->val.name.text);
|
||||
token->val.name.text = 0;
|
||||
free ((char *) token->val.str.text);
|
||||
token->val.str.text = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2394,9 +2376,9 @@ _cpp_free_temp_tokens (pfile)
|
||||
|
||||
if (pfile->date)
|
||||
{
|
||||
free ((char *) pfile->date->val.name.text);
|
||||
free ((char *) pfile->date->val.str.text);
|
||||
free (pfile->date);
|
||||
free ((char *) pfile->time->val.name.text);
|
||||
free ((char *) pfile->time->val.str.text);
|
||||
free (pfile->time);
|
||||
}
|
||||
}
|
||||
@ -2410,11 +2392,11 @@ duplicate_token (pfile, token)
|
||||
cpp_token *result = get_temp_token (pfile);
|
||||
|
||||
*result = *token;
|
||||
if (token_spellings[token->type].type > SPELL_NONE)
|
||||
if (token_spellings[token->type].type == SPELL_STRING)
|
||||
{
|
||||
U_CHAR *buff = (U_CHAR *) xmalloc (token->val.name.len);
|
||||
memcpy (buff, token->val.name.text, token->val.name.len);
|
||||
result->val.name.text = buff;
|
||||
U_CHAR *buff = (U_CHAR *) xmalloc (token->val.str.len);
|
||||
memcpy (buff, token->val.str.text, token->val.str.len);
|
||||
result->val.str.text = buff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2489,13 +2471,11 @@ can_paste (pfile, token1, token2, digraph)
|
||||
case CPP_NAME:
|
||||
if (b == CPP_NAME) return CPP_NAME;
|
||||
if (b == CPP_NUMBER
|
||||
&& is_numstart(token2->val.name.text[0])) return CPP_NAME;
|
||||
&& is_numstart(token2->val.str.text[0])) return CPP_NAME;
|
||||
if (b == CPP_CHAR
|
||||
&& token1->val.name.len == 1
|
||||
&& token1->val.name.text[0] == 'L') return CPP_WCHAR;
|
||||
&& token1->val.node == pfile->spec_nodes->n_L) return CPP_WCHAR;
|
||||
if (b == CPP_STRING
|
||||
&& token1->val.name.len == 1
|
||||
&& token1->val.name.text[0] == 'L') return CPP_WSTRING;
|
||||
&& token1->val.node == pfile->spec_nodes->n_L) return CPP_WSTRING;
|
||||
break;
|
||||
|
||||
case CPP_NUMBER:
|
||||
@ -2504,7 +2484,7 @@ can_paste (pfile, token1, token2, digraph)
|
||||
if (b == CPP_DOT) return CPP_NUMBER;
|
||||
/* Numbers cannot have length zero, so this is safe. */
|
||||
if ((b == CPP_PLUS || b == CPP_MINUS)
|
||||
&& VALID_SIGN ('+', token1->val.name.text[token1->val.name.len - 1]))
|
||||
&& VALID_SIGN ('+', token1->val.str.text[token1->val.str.len - 1]))
|
||||
return CPP_NUMBER;
|
||||
break;
|
||||
|
||||
@ -2578,15 +2558,21 @@ maybe_paste_with_next (pfile, token)
|
||||
if (type == CPP_NAME || type == CPP_NUMBER)
|
||||
{
|
||||
/* Join spellings. */
|
||||
U_CHAR *buff, *buff2;
|
||||
U_CHAR *buf, *end;
|
||||
|
||||
pasted = get_temp_token (pfile);
|
||||
buff = (U_CHAR *) xmalloc (TOKEN_LEN (token) + TOKEN_LEN (second));
|
||||
buff2 = spell_token (pfile, token, buff);
|
||||
buff2 = spell_token (pfile, second, buff2);
|
||||
buf = (U_CHAR *) alloca (TOKEN_LEN (token) + TOKEN_LEN (second));
|
||||
end = spell_token (pfile, token, buf);
|
||||
end = spell_token (pfile, second, end);
|
||||
*end = '\0';
|
||||
|
||||
pasted->val.name.text = buff;
|
||||
pasted->val.name.len = buff2 - buff;
|
||||
if (type == CPP_NAME)
|
||||
pasted->val.node = cpp_lookup (pfile, buf, end - buf);
|
||||
else
|
||||
{
|
||||
pasted->val.str.text = uxstrdup (buf);
|
||||
pasted->val.str.len = end - buf;
|
||||
}
|
||||
}
|
||||
else if (type == CPP_WCHAR || type == CPP_WSTRING)
|
||||
pasted = duplicate_token (pfile, second);
|
||||
@ -2597,7 +2583,7 @@ maybe_paste_with_next (pfile, token)
|
||||
}
|
||||
|
||||
pasted->type = type;
|
||||
pasted->flags = digraph ? DIGRAPH: 0;
|
||||
pasted->flags = digraph ? DIGRAPH : 0;
|
||||
}
|
||||
|
||||
/* The pasted token gets the whitespace flags and position of the
|
||||
@ -2681,8 +2667,8 @@ stringify_arg (pfile, token)
|
||||
}
|
||||
|
||||
result->type = CPP_STRING;
|
||||
result->val.name.text = main_buf;
|
||||
result->val.name.len = buf_used;
|
||||
result->val.str.text = main_buf;
|
||||
result->val.str.len = buf_used;
|
||||
restore_macro_expansion (pfile, prev_value);
|
||||
return result;
|
||||
}
|
||||
@ -2907,7 +2893,7 @@ cpp_get_token (pfile)
|
||||
if (pfile->no_expand_level == pfile->cur_context || pfile->paste_level)
|
||||
return token;
|
||||
|
||||
node = cpp_lookup (pfile, token->val.name.text, token->val.name.len);
|
||||
node = token->val.node;
|
||||
if (node->type == T_VOID)
|
||||
return token;
|
||||
|
||||
@ -3194,7 +3180,7 @@ special_symbol (pfile, node, token)
|
||||
|
||||
#ifdef STDC_0_IN_SYSTEM_HEADERS
|
||||
if (CPP_IN_SYSTEM_HEADER (pfile)
|
||||
&& !cpp_defined (pfile, DSC("__STRICT_ANSI__")))
|
||||
&& pfile->spec_nodes->n__STRICT_ANSI__->type == T_VOID)
|
||||
stdc = 0;
|
||||
#endif
|
||||
result = alloc_number_token (pfile, stdc);
|
||||
@ -3217,16 +3203,16 @@ special_symbol (pfile, node, token)
|
||||
pfile->time = make_string_token
|
||||
((cpp_token *) xmalloc (sizeof (cpp_token)), DSC("12:34:56"));
|
||||
|
||||
sprintf ((char *) pfile->date->val.name.text, "%s %2d %4d",
|
||||
sprintf ((char *) pfile->date->val.str.text, "%s %2d %4d",
|
||||
monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
|
||||
sprintf ((char *) pfile->time->val.name.text, "%02d:%02d:%02d",
|
||||
sprintf ((char *) pfile->time->val.str.text, "%02d:%02d:%02d",
|
||||
tb->tm_hour, tb->tm_min, tb->tm_sec);
|
||||
}
|
||||
result = node->type == T_DATE ? pfile->date: pfile->time;
|
||||
break;
|
||||
|
||||
case T_POISON:
|
||||
cpp_error (pfile, "attempt to use poisoned \"%s\".", node->name);
|
||||
cpp_error (pfile, "attempt to use poisoned \"%s\"", node->name);
|
||||
return token;
|
||||
|
||||
default:
|
||||
|
126
gcc/cpplib.c
126
gcc/cpplib.c
@ -148,8 +148,6 @@ _cpp_check_directive (pfile, token, bol)
|
||||
const cpp_token *token;
|
||||
int bol;
|
||||
{
|
||||
const U_CHAR *name = token->val.name.text;
|
||||
size_t len = token->val.name.len;
|
||||
unsigned int i;
|
||||
|
||||
/* If we are rescanning preprocessed input, don't obey any directives
|
||||
@ -158,7 +156,7 @@ _cpp_check_directive (pfile, token, bol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < N_DIRECTIVES; i++)
|
||||
if (dtable[i].length == len && !memcmp (dtable[i].name, name, len))
|
||||
if (pfile->spec_nodes->dirs[i] == token->val.node)
|
||||
{
|
||||
/* If we are skipping a failed conditional group, all non-conditional
|
||||
directives are ignored. */
|
||||
@ -250,8 +248,6 @@ get_define_node (pfile)
|
||||
{
|
||||
cpp_hashnode *node;
|
||||
const cpp_token *token;
|
||||
const U_CHAR *sym;
|
||||
unsigned int len;
|
||||
|
||||
/* Skip any -C comments. */
|
||||
while ((token = cpp_get_token (pfile))->type == CPP_COMMENT)
|
||||
@ -259,27 +255,26 @@ get_define_node (pfile)
|
||||
|
||||
if (token->type != CPP_NAME)
|
||||
{
|
||||
cpp_error_with_line (pfile, pfile->token_list.line, token->col,
|
||||
cpp_error_with_line (pfile, token->line, token->col,
|
||||
"macro names must be identifiers");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* That identifier is not allowed to be "defined". See predefined
|
||||
macro names (6.10.8.4). */
|
||||
len = token->val.name.len;
|
||||
sym = token->val.name.text;
|
||||
if (str_match (sym, len, "defined"))
|
||||
node = token->val.node;
|
||||
|
||||
if (node == pfile->spec_nodes->n_defined)
|
||||
{
|
||||
cpp_error_with_line (pfile, pfile->token_list.line, token->col,
|
||||
"\"defined\" is not a legal macro name");
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = cpp_lookup (pfile, sym, len);
|
||||
/* Check for poisoned identifiers now. */
|
||||
if (node->type == T_POISON)
|
||||
{
|
||||
cpp_error (pfile, "attempt to use poisoned \"%.*s\"", (int) len, sym);
|
||||
cpp_error (pfile, "attempt to use poisoned \"%s\"", node->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -360,7 +355,7 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (name->val.name.len == 0)
|
||||
if (name->val.str.len == 0)
|
||||
{
|
||||
cpp_error (pfile, "empty file name in #%s", dir);
|
||||
return 1;
|
||||
@ -369,8 +364,8 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
|
||||
if (!trail && cpp_get_token (pfile)->type != CPP_EOF)
|
||||
cpp_error (pfile, "junk at end of #%s", dir);
|
||||
|
||||
*lenp = name->val.name.len;
|
||||
*strp = name->val.name.text;
|
||||
*lenp = name->val.str.len;
|
||||
*strp = name->val.str.text;
|
||||
*abp = (name->type == CPP_HEADER_NAME);
|
||||
return 0;
|
||||
}
|
||||
@ -466,8 +461,8 @@ read_line_number (pfile, num)
|
||||
{
|
||||
const cpp_token *tok = cpp_get_token (pfile);
|
||||
enum cpp_ttype type = tok->type;
|
||||
const U_CHAR *p = tok->val.name.text;
|
||||
unsigned int len = tok->val.name.len;
|
||||
const U_CHAR *p = tok->val.str.text;
|
||||
unsigned int len = tok->val.str.len;
|
||||
|
||||
if (type == CPP_NUMBER && len == 1 && p[0] >= '1' && p[0] <= '4')
|
||||
{
|
||||
@ -526,8 +521,8 @@ do_line (pfile)
|
||||
|
||||
tok = cpp_get_token (pfile);
|
||||
type = tok->type;
|
||||
str = tok->val.name.text;
|
||||
len = tok->val.name.len;
|
||||
str = tok->val.str.text;
|
||||
len = tok->val.str.len;
|
||||
|
||||
if (type != CPP_NUMBER || strtoul_for_line (str, len, &new_lineno))
|
||||
{
|
||||
@ -542,8 +537,8 @@ do_line (pfile)
|
||||
ip->lineno = new_lineno;
|
||||
tok = cpp_get_token (pfile);
|
||||
type = tok->type;
|
||||
str = tok->val.name.text;
|
||||
len = tok->val.name.len;
|
||||
str = tok->val.str.text;
|
||||
len = tok->val.str.len;
|
||||
|
||||
if (type == CPP_EOF)
|
||||
goto done;
|
||||
@ -683,8 +678,7 @@ struct pragma_entry
|
||||
};
|
||||
|
||||
static int pragma_dispatch
|
||||
PARAMS ((cpp_reader *, const struct pragma_entry *,
|
||||
const U_CHAR *, size_t));
|
||||
PARAMS ((cpp_reader *, const struct pragma_entry *, const cpp_hashnode *));
|
||||
static int do_pragma_once PARAMS ((cpp_reader *));
|
||||
static int do_pragma_implementation PARAMS ((cpp_reader *));
|
||||
static int do_pragma_poison PARAMS ((cpp_reader *));
|
||||
@ -710,12 +704,14 @@ static const struct pragma_entry gcc_pragmas[] =
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int pragma_dispatch (pfile, table, p, len)
|
||||
static int pragma_dispatch (pfile, table, node)
|
||||
cpp_reader *pfile;
|
||||
const struct pragma_entry *table;
|
||||
const U_CHAR *p;
|
||||
size_t len;
|
||||
const cpp_hashnode *node;
|
||||
{
|
||||
const U_CHAR *p = node->name;
|
||||
size_t len = node->length;
|
||||
|
||||
for (; table->name; table++)
|
||||
if (strlen (table->name) == len && !memcmp (p, table->name, len))
|
||||
return (*table->handler) (pfile);
|
||||
@ -738,8 +734,7 @@ do_pragma (pfile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pop = pragma_dispatch (pfile, top_pragmas,
|
||||
tok->val.name.text, tok->val.name.len);
|
||||
pop = pragma_dispatch (pfile, top_pragmas, tok->val.node);
|
||||
if (!pop)
|
||||
pass_thru_directive (pfile);
|
||||
return 0;
|
||||
@ -757,8 +752,7 @@ do_pragma_gcc (pfile)
|
||||
else if (tok->type != CPP_NAME)
|
||||
return 0;
|
||||
|
||||
return pragma_dispatch (pfile, gcc_pragmas,
|
||||
tok->val.name.text, tok->val.name.len);
|
||||
return pragma_dispatch (pfile, gcc_pragmas, tok->val.node);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -799,9 +793,9 @@ do_pragma_implementation (pfile)
|
||||
}
|
||||
|
||||
/* Make a NUL-terminated copy of the string. */
|
||||
copy = alloca (tok->val.name.len + 1);
|
||||
memcpy (copy, tok->val.name.text, tok->val.name.len);
|
||||
copy[tok->val.name.len] = '\0';
|
||||
copy = alloca (tok->val.str.len + 1);
|
||||
memcpy (copy, tok->val.str.text, tok->val.str.len);
|
||||
copy[tok->val.str.len] = '\0';
|
||||
|
||||
if (cpp_included (pfile, copy))
|
||||
cpp_warning (pfile,
|
||||
@ -837,7 +831,7 @@ do_pragma_poison (pfile)
|
||||
return 1;
|
||||
}
|
||||
|
||||
hp = cpp_lookup (pfile, tok->val.name.text, tok->val.name.len);
|
||||
hp = tok->val.node;
|
||||
if (hp->type == T_POISON)
|
||||
; /* It is allowed to poison the same identifier twice. */
|
||||
else
|
||||
@ -943,7 +937,7 @@ detect_if_not_defined (pfile)
|
||||
|
||||
token++;
|
||||
if (token->type != CPP_NAME
|
||||
|| !str_match (token->val.name.text, token->val.name.len, "defined"))
|
||||
|| token->val.node != pfile->spec_nodes->n_defined)
|
||||
return 0;
|
||||
|
||||
token++;
|
||||
@ -953,7 +947,7 @@ detect_if_not_defined (pfile)
|
||||
if (token->type != CPP_NAME)
|
||||
return 0;
|
||||
|
||||
cmacro = cpp_lookup (pfile, token->val.name.text, token->val.name.len);
|
||||
cmacro = token->val.node;
|
||||
|
||||
if (token[-1].type == CPP_OPEN_PAREN)
|
||||
{
|
||||
@ -977,15 +971,11 @@ parse_ifdef (pfile, name)
|
||||
cpp_reader *pfile;
|
||||
const U_CHAR *name;
|
||||
{
|
||||
const U_CHAR *ident;
|
||||
unsigned int len;
|
||||
enum cpp_ttype type;
|
||||
const cpp_hashnode *node = 0;
|
||||
|
||||
const cpp_token *token = cpp_get_token (pfile);
|
||||
type = token->type;
|
||||
ident = token->val.name.text;
|
||||
len = token->val.name.len;
|
||||
|
||||
if (!CPP_TRADITIONAL (pfile))
|
||||
{
|
||||
@ -998,9 +988,13 @@ parse_ifdef (pfile, name)
|
||||
}
|
||||
|
||||
if (type == CPP_NAME)
|
||||
node = cpp_lookup (pfile, ident, len);
|
||||
node = token->val.node;
|
||||
if (node && node->type == T_POISON)
|
||||
cpp_error (pfile, "attempt to use poisoned identifier \"%s\"", node->name);
|
||||
{
|
||||
cpp_error (pfile, "attempt to use poisoned identifier \"%s\"",
|
||||
node->name);
|
||||
node = 0;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
@ -1011,17 +1005,12 @@ static int
|
||||
do_ifdef (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int def = 0;
|
||||
const cpp_hashnode *node = 0;
|
||||
|
||||
if (! pfile->skipping)
|
||||
{
|
||||
node = parse_ifdef (pfile, dtable[T_IFDEF].name);
|
||||
if (node)
|
||||
def = (node->type != T_VOID && node->type != T_POISON);
|
||||
}
|
||||
node = parse_ifdef (pfile, dtable[T_IFDEF].name);
|
||||
|
||||
push_conditional (pfile, !def, T_IFDEF, 0);
|
||||
push_conditional (pfile, !(node && node->type != T_VOID), T_IFDEF, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1033,18 +1022,16 @@ do_ifndef (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int start_of_file = 0;
|
||||
int def = 0;
|
||||
const cpp_hashnode *cmacro = 0;
|
||||
const cpp_hashnode *node = 0;
|
||||
|
||||
if (! pfile->skipping)
|
||||
{
|
||||
start_of_file = (pfile->token_list.flags & BEG_OF_FILE);
|
||||
cmacro = parse_ifdef (pfile, dtable[T_IFNDEF].name);
|
||||
if (cmacro)
|
||||
def = cmacro->type != T_VOID;
|
||||
node = parse_ifdef (pfile, dtable[T_IFNDEF].name);
|
||||
}
|
||||
|
||||
push_conditional (pfile, def, T_IFNDEF, start_of_file ? cmacro : 0);
|
||||
push_conditional (pfile, node && node->type != T_VOID,
|
||||
T_IFNDEF, start_of_file ? node : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1060,7 +1047,8 @@ do_if (pfile)
|
||||
|
||||
if (! pfile->skipping)
|
||||
{
|
||||
cmacro = detect_if_not_defined (pfile);
|
||||
if (pfile->token_list.flags & BEG_OF_FILE)
|
||||
cmacro = detect_if_not_defined (pfile);
|
||||
value = _cpp_parse_expr (pfile);
|
||||
}
|
||||
push_conditional (pfile, value == 0, T_IF, cmacro);
|
||||
@ -1294,13 +1282,13 @@ _cpp_parse_assertion (pfile, answerp)
|
||||
dest = &list->tokens[list->tokens_used++];
|
||||
*dest = *token;
|
||||
|
||||
if (token_spellings[token->type].type > SPELL_NONE)
|
||||
if (token_spellings[token->type].type == SPELL_STRING)
|
||||
{
|
||||
_cpp_expand_name_space (list, token->val.name.len);
|
||||
dest->val.name.text = list->namebuf + list->name_used;
|
||||
_cpp_expand_name_space (list, token->val.str.len);
|
||||
dest->val.str.text = list->namebuf + list->name_used;
|
||||
memcpy (list->namebuf + list->name_used,
|
||||
token->val.name.text, token->val.name.len);
|
||||
list->name_used += token->val.name.len;
|
||||
token->val.str.text, token->val.str.len);
|
||||
list->name_used += token->val.str.len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1322,12 +1310,12 @@ _cpp_parse_assertion (pfile, answerp)
|
||||
|
||||
lookup_node:
|
||||
*answerp = answer;
|
||||
len = predicate->val.name.len;
|
||||
len = predicate->val.node->length;
|
||||
sym = alloca (len + 1);
|
||||
|
||||
/* Prefix '#' to get it out of macro namespace. */
|
||||
sym[0] = '#';
|
||||
memcpy (sym + 1, predicate->val.name.text, len);
|
||||
memcpy (sym + 1, predicate->val.node->name, len);
|
||||
return cpp_lookup (pfile, sym, len + 1);
|
||||
|
||||
error:
|
||||
@ -1586,12 +1574,26 @@ cpp_pop_buffer (pfile)
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
#define DSC(x) U x, sizeof x - 1
|
||||
void
|
||||
_cpp_init_stacks (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int i;
|
||||
struct spec_nodes *s;
|
||||
|
||||
pfile->buffer_ob = xnew (struct obstack);
|
||||
obstack_init (pfile->buffer_ob);
|
||||
|
||||
/* Perhaps not the ideal place to put this. */
|
||||
pfile->spec_nodes = s = xnew (struct spec_nodes);
|
||||
s->n_L = cpp_lookup (pfile, DSC("L"));
|
||||
s->n_defined = cpp_lookup (pfile, DSC("defined"));
|
||||
s->n__STRICT_ANSI__ = cpp_lookup (pfile, DSC("__STRICT_ANSI__"));
|
||||
s->n__CHAR_UNSIGNED__ = cpp_lookup (pfile, DSC("__CHAR_UNSIGNED__"));
|
||||
s->n__VA_ARGS__ = cpp_lookup (pfile, DSC("__VA_ARGS__"));
|
||||
for (i = 0; i < N_DIRECTIVES; i++)
|
||||
s->dirs[i] = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
|
||||
}
|
||||
|
||||
void
|
||||
|
27
gcc/cpplib.h
27
gcc/cpplib.h
@ -34,7 +34,7 @@ typedef struct cpp_options cpp_options;
|
||||
typedef struct cpp_printer cpp_printer;
|
||||
typedef struct cpp_token cpp_token;
|
||||
typedef struct cpp_toklist cpp_toklist;
|
||||
typedef struct cpp_name cpp_name;
|
||||
typedef struct cpp_string cpp_string;
|
||||
typedef struct cpp_hashnode cpp_hashnode;
|
||||
|
||||
/* The first two groups, apart from '=', can appear in preprocessor
|
||||
@ -112,18 +112,18 @@ typedef struct cpp_hashnode cpp_hashnode;
|
||||
C(CPP_OTHER, 0) /* stray punctuation */ \
|
||||
\
|
||||
I(CPP_NAME, 0) /* word */ \
|
||||
I(CPP_INT, 0) /* 23 */ \
|
||||
I(CPP_FLOAT, 0) /* 3.14159 */ \
|
||||
I(CPP_NUMBER, 0) /* 34_be+ta */ \
|
||||
S(CPP_INT, 0) /* 23 */ \
|
||||
S(CPP_FLOAT, 0) /* 3.14159 */ \
|
||||
S(CPP_NUMBER, 0) /* 34_be+ta */ \
|
||||
S(CPP_CHAR, 0) /* 'char' */ \
|
||||
S(CPP_WCHAR, 0) /* L'char' */ \
|
||||
S(CPP_STRING, 0) /* "string" */ \
|
||||
S(CPP_WSTRING, 0) /* L"string" */ \
|
||||
\
|
||||
I(CPP_COMMENT, 0) /* Only if output comments. */ \
|
||||
S(CPP_COMMENT, 0) /* Only if output comments. */ \
|
||||
N(CPP_MACRO_ARG, 0) /* Macro argument. */ \
|
||||
N(CPP_EOF, 0) /* End of file. */ \
|
||||
I(CPP_HEADER_NAME, 0) /* <stdio.h> in #include */
|
||||
S(CPP_HEADER_NAME, 0) /* <stdio.h> in #include */
|
||||
|
||||
#define T(e, s) e,
|
||||
#define I(e, s) e,
|
||||
@ -141,8 +141,8 @@ enum cpp_ttype
|
||||
#undef C
|
||||
#undef N
|
||||
|
||||
/* Payload of a NAME, NUMBER, FLOAT, STRING, or COMMENT token. */
|
||||
struct cpp_name
|
||||
/* Payload of a NUMBER, FLOAT, STRING, or COMMENT token. */
|
||||
struct cpp_string
|
||||
{
|
||||
unsigned int len;
|
||||
const unsigned char *text;
|
||||
@ -168,7 +168,8 @@ struct cpp_token
|
||||
union
|
||||
{
|
||||
HOST_WIDEST_INT integer; /* an integer */
|
||||
struct cpp_name name; /* a string */
|
||||
struct cpp_hashnode *node; /* an identifier */
|
||||
struct cpp_string str; /* a string, or number */
|
||||
unsigned int aux; /* argument no. for a CPP_MACRO_ARG, or
|
||||
character represented by CPP_OTHER. */
|
||||
} val;
|
||||
@ -558,6 +559,10 @@ struct cpp_reader
|
||||
|
||||
/* True if output_line_command needs to output a newline. */
|
||||
unsigned char need_newline;
|
||||
|
||||
/* Special nodes - identifiers with predefined significance to the
|
||||
preprocessor. */
|
||||
struct spec_nodes *spec_nodes;
|
||||
};
|
||||
|
||||
/* struct cpp_printer encapsulates state used to convert the stream of
|
||||
@ -693,8 +698,8 @@ extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
|
||||
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
|
||||
extern void cpp_scan_buffer PARAMS ((cpp_reader *, cpp_printer *));
|
||||
extern void cpp_scan_buffer_nooutput PARAMS ((cpp_reader *));
|
||||
extern int cpp_idcmp PARAMS ((const unsigned char *,
|
||||
size_t, const char *));
|
||||
extern int cpp_ideq PARAMS ((const cpp_token *,
|
||||
const char *));
|
||||
|
||||
/* In cpphash.c */
|
||||
extern int cpp_defined PARAMS ((cpp_reader *,
|
||||
|
@ -501,7 +501,7 @@ recognized_extern (name)
|
||||
switch (special_file_handling)
|
||||
{
|
||||
case errno_h:
|
||||
if (!cpp_idcmp (name->val.name.text, name->val.name.len, "errno"))
|
||||
if (cpp_ideq (name, "errno"))
|
||||
seen_errno = 1, required_other--;
|
||||
break;
|
||||
|
||||
@ -531,8 +531,8 @@ recognized_function (fname, kind, have_arg_list, file_seen)
|
||||
missing_extern_C_count++;
|
||||
#endif
|
||||
|
||||
fn = lookup_std_proto ((const char *)fname->val.name.text,
|
||||
fname->val.name.len);
|
||||
fn = lookup_std_proto ((const char *)fname->val.node->name,
|
||||
fname->val.node->length);
|
||||
|
||||
/* Remove the function from the list of required function. */
|
||||
if (fn)
|
||||
@ -653,9 +653,7 @@ read_scan_file (in_fname, argc, argv)
|
||||
if (CPP_BUFFER (&scan_in) == buf)
|
||||
break;
|
||||
}
|
||||
else if (t->type == CPP_NAME && cpp_idcmp (t->val.name.text,
|
||||
t->val.name.len,
|
||||
"_filbuf") == 0)
|
||||
else if (cpp_ideq (t, "_filbuf"))
|
||||
seen_filbuf++;
|
||||
}
|
||||
if (seen_filbuf)
|
||||
|
@ -193,18 +193,17 @@ scan_decls (pfile, argc, argv)
|
||||
break;
|
||||
case CPP_NAME:
|
||||
/* "inline" and "extern" are recognized but skipped */
|
||||
if (!cpp_idcmp (token->val.name.text, token->val.name.len, "inline"))
|
||||
if (cpp_ideq (token, "inline"))
|
||||
{
|
||||
saw_inline = 1;
|
||||
}
|
||||
else if (!cpp_idcmp (token->val.name.text,
|
||||
token->val.name.len, "extern"))
|
||||
else if (cpp_ideq (token, "extern"))
|
||||
{
|
||||
saw_extern = 1;
|
||||
token = cpp_get_token (pfile);
|
||||
if (token->type == CPP_STRING
|
||||
&& !cpp_idcmp (token->val.name.text,
|
||||
token->val.name.len, "C"))
|
||||
&& token->val.str.len == 1
|
||||
&& token->val.str.text[0] == 'C')
|
||||
{
|
||||
current_extern_C = 1;
|
||||
token = cpp_get_token (pfile);
|
||||
|
Loading…
Reference in New Issue
Block a user