mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-19 09:29:03 +08:00
cppexp.c: Don't include cpphash.h.
* cppexp.c: Don't include cpphash.h. (parse_charconst, cpp_lex): Use cpp_defined. (cpp_lex): Use get_directive_token throughout. Remove unnecessary cases from switch. Move assertion-handling code down to OTHER case. (cpp_parse_expr): If we see '+' or '-', check the context to determine if they are unary or binary operators. Streamline the jumps a bit. Do not call skip_rest_of_line. * cpplib.c: Make skip_rest_of_line and cpp_skip_hspace static. Export get_directive_token. Update commentary. (cpp_defined): New function. (do_define): Remove reference to T_PCSTRING. Call free_definition to release memory for old definition, when redefining a macro. (eval_if_expression): Set only_seen_white to 0 before calling cpp_parse_expr. Call skip_rest_of_line after it returns. (cpp_read_check_assertion): Don't preserve a pointer into the token buffer across a call to cpp_get_token. * Makefile.in (cppexp.o): Don't depend on cpphash.h. * cppfiles.c (redundant_include_p): Use cpp_defined. * cpphash.c (free_definition): New function. (delete_macro): Use it. Update commentary. * cpphash.h: Typedef HASHNODE here. Prototype cpp_lookup and free_definition. * cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING from enum node_type. Prototype cpp_defined and get_directive_token. Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace. * fix-header.c (check_macro_names): Use cpp_defined. (read_scan_file): Set inhibit_warnings and inhibit_errors in the options structure. From-SVN: r31908
This commit is contained in:
parent
26439cc59c
commit
cf4ed945ea
@ -1,3 +1,39 @@
|
||||
2000-02-10 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* cppexp.c: Don't include cpphash.h.
|
||||
(parse_charconst, cpp_lex): Use cpp_defined.
|
||||
(cpp_lex): Use get_directive_token throughout. Remove
|
||||
unnecessary cases from switch. Move assertion-handling code
|
||||
down to OTHER case.
|
||||
(cpp_parse_expr): If we see '+' or '-', check the context to
|
||||
determine if they are unary or binary operators. Streamline
|
||||
the jumps a bit. Do not call skip_rest_of_line.
|
||||
|
||||
* cpplib.c: Make skip_rest_of_line and cpp_skip_hspace
|
||||
static. Export get_directive_token. Update commentary.
|
||||
(cpp_defined): New function.
|
||||
(do_define): Remove reference to T_PCSTRING. Call
|
||||
free_definition to release memory for old definition, when
|
||||
redefining a macro.
|
||||
(eval_if_expression): Set only_seen_white to 0 before calling
|
||||
cpp_parse_expr. Call skip_rest_of_line after it returns.
|
||||
(cpp_read_check_assertion): Don't preserve a pointer into the
|
||||
token buffer across a call to cpp_get_token.
|
||||
|
||||
* Makefile.in (cppexp.o): Don't depend on cpphash.h.
|
||||
* cppfiles.c (redundant_include_p): Use cpp_defined.
|
||||
* cpphash.c (free_definition): New function.
|
||||
(delete_macro): Use it. Update commentary.
|
||||
* cpphash.h: Typedef HASHNODE here. Prototype cpp_lookup and
|
||||
free_definition.
|
||||
* cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING
|
||||
from enum node_type. Prototype cpp_defined and get_directive_token.
|
||||
Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace.
|
||||
|
||||
* fix-header.c (check_macro_names): Use cpp_defined.
|
||||
(read_scan_file): Set inhibit_warnings and inhibit_errors in
|
||||
the options structure.
|
||||
|
||||
2000-02-10 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* c-pragma.c (maximum_field_alignment): Remove duplicate declaration.
|
||||
|
@ -2043,7 +2043,7 @@ cpplib.o: cpplib.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
|
||||
cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
|
||||
cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h
|
||||
cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h
|
||||
cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
|
||||
cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h
|
||||
cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h
|
||||
|
||||
cppinit.o: cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \
|
||||
|
111
gcc/cppexp.c
111
gcc/cppexp.c
@ -27,7 +27,6 @@ Written by Per Bothner 1994. */
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
|
||||
#ifdef MULTIBYTE_CHARS
|
||||
#include <locale.h>
|
||||
@ -331,8 +330,8 @@ parse_charconst (pfile, start, end)
|
||||
/* If char type is signed, sign-extend the constant. */
|
||||
num_bits = num_chars * width;
|
||||
|
||||
if (cpp_lookup (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
|
||||
sizeof ("__CHAR_UNSIGNED__")-1)
|
||||
if (cpp_defined (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
|
||||
sizeof ("__CHAR_UNSIGNED__")-1)
|
||||
|| ((result >> (num_bits - 1)) & 1) == 0)
|
||||
op.value = result & ((unsigned HOST_WIDEST_INT) ~0
|
||||
>> (HOST_BITS_PER_WIDEST_INT - num_bits));
|
||||
@ -377,56 +376,28 @@ cpp_lex (pfile, skip_evaluation)
|
||||
cpp_reader *pfile;
|
||||
int skip_evaluation;
|
||||
{
|
||||
U_CHAR c;
|
||||
struct token *toktab;
|
||||
enum cpp_token token;
|
||||
struct operation op;
|
||||
U_CHAR *tok_start, *tok_end;
|
||||
int old_written;
|
||||
|
||||
retry:
|
||||
long old_written;
|
||||
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
cpp_skip_hspace (pfile);
|
||||
c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
|
||||
if (c == '#')
|
||||
{
|
||||
op.op = INT;
|
||||
op.value = cpp_read_check_assertion (pfile);
|
||||
return op;
|
||||
}
|
||||
token = get_directive_token (pfile);
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
op.op = 0;
|
||||
return op;
|
||||
}
|
||||
|
||||
token = cpp_get_token (pfile);
|
||||
tok_start = pfile->token_buffer + old_written;
|
||||
tok_end = CPP_PWRITTEN (pfile);
|
||||
pfile->limit = tok_start;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
switch (token)
|
||||
{
|
||||
case CPP_EOF: /* Should not happen ... */
|
||||
case CPP_VSPACE:
|
||||
op.op = 0;
|
||||
return op;
|
||||
case CPP_POP:
|
||||
if (CPP_BUFFER (pfile)->fname != NULL)
|
||||
{
|
||||
op.op = 0;
|
||||
return op;
|
||||
}
|
||||
cpp_pop_buffer (pfile);
|
||||
goto retry;
|
||||
case CPP_HSPACE:
|
||||
case CPP_COMMENT:
|
||||
goto retry;
|
||||
case CPP_NUMBER:
|
||||
return parse_number (pfile, tok_start, tok_end);
|
||||
case CPP_STRING:
|
||||
cpp_error (pfile, "string constants not allowed in #if expressions");
|
||||
cpp_error (pfile, "string constants are not allowed in #if expressions");
|
||||
op.op = ERROR;
|
||||
return op;
|
||||
case CPP_CHAR:
|
||||
@ -445,45 +416,38 @@ cpp_lex (pfile, skip_evaluation)
|
||||
else
|
||||
{
|
||||
int paren = 0, len;
|
||||
cpp_buffer *ip = CPP_BUFFER (pfile);
|
||||
U_CHAR *tok;
|
||||
HASHNODE *hp;
|
||||
|
||||
cpp_skip_hspace (pfile);
|
||||
if (*ip->cur == '(')
|
||||
pfile->no_macro_expand++;
|
||||
token = get_directive_token (pfile);
|
||||
if (token == CPP_LPAREN)
|
||||
{
|
||||
paren++;
|
||||
ip->cur++; /* Skip over the paren */
|
||||
cpp_skip_hspace (pfile);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
token = get_directive_token (pfile);
|
||||
}
|
||||
|
||||
if (!is_idstart(*ip->cur))
|
||||
if (token != CPP_NAME)
|
||||
goto oops;
|
||||
if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
|
||||
goto oops;
|
||||
tok = ip->cur;
|
||||
while (is_idchar(*ip->cur))
|
||||
++ip->cur;
|
||||
len = ip->cur - tok;
|
||||
cpp_skip_hspace (pfile);
|
||||
|
||||
tok = pfile->token_buffer + old_written;
|
||||
len = CPP_PWRITTEN (pfile) - tok;
|
||||
if (cpp_defined (pfile, tok, len))
|
||||
op.value = 1;
|
||||
|
||||
if (paren)
|
||||
{
|
||||
if (*ip->cur != ')')
|
||||
if (get_directive_token (pfile) != CPP_RPAREN)
|
||||
goto oops;
|
||||
++ip->cur;
|
||||
}
|
||||
hp = cpp_lookup (pfile, tok, len);
|
||||
if (hp != NULL)
|
||||
{
|
||||
if (hp->type == T_POISON)
|
||||
cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
|
||||
else
|
||||
op.value = 1;
|
||||
}
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
pfile->no_macro_expand--;
|
||||
}
|
||||
return op;
|
||||
|
||||
oops:
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
pfile->no_macro_expand--;
|
||||
cpp_error (pfile, "`defined' without an identifier");
|
||||
return op;
|
||||
|
||||
@ -501,6 +465,13 @@ cpp_lex (pfile, skip_evaluation)
|
||||
op.op = toktab->token;
|
||||
return op;
|
||||
}
|
||||
else if (tok_start + 1 == tok_end && *tok_start == '#')
|
||||
{
|
||||
CPP_FORWARD (CPP_BUFFER (pfile), -1);
|
||||
op.op = INT;
|
||||
op.value = cpp_read_check_assertion (pfile);
|
||||
return op;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
op.op = *tok_start;
|
||||
@ -736,15 +707,16 @@ cpp_parse_expr (pfile)
|
||||
cpp_ice (pfile, "cpp_lex returns a NAME");
|
||||
goto syntax_error;
|
||||
case INT: case CHAR:
|
||||
top->value = op.value;
|
||||
top->unsignedp = op.unsignedp;
|
||||
goto set_value;
|
||||
case 0:
|
||||
lprio = 0; goto maybe_reduce;
|
||||
case '+': case '-':
|
||||
/* Is this correct if unary ? FIXME */
|
||||
flags = RIGHT_OPERAND_REQUIRED;
|
||||
lprio = PLUS_PRIO; rprio = lprio + 1; goto maybe_reduce;
|
||||
if (top->flags & HAVE_VALUE)
|
||||
{
|
||||
lprio = PLUS_PRIO;
|
||||
goto binop;
|
||||
}
|
||||
/* else fall through */
|
||||
case '!': case '~':
|
||||
flags = RIGHT_OPERAND_REQUIRED;
|
||||
rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
|
||||
@ -777,10 +749,6 @@ cpp_parse_expr (pfile)
|
||||
goto maybe_reduce;
|
||||
case ERROR:
|
||||
goto syntax_error;
|
||||
binop:
|
||||
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
|
||||
rprio = lprio + 1;
|
||||
goto maybe_reduce;
|
||||
default:
|
||||
cpp_error (pfile, "invalid character in #if");
|
||||
goto syntax_error;
|
||||
@ -793,9 +761,15 @@ cpp_parse_expr (pfile)
|
||||
cpp_error (pfile, "syntax error in #if");
|
||||
goto syntax_error;
|
||||
}
|
||||
top->value = op.value;
|
||||
top->unsignedp = op.unsignedp;
|
||||
top->flags |= HAVE_VALUE;
|
||||
continue;
|
||||
|
||||
binop:
|
||||
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
|
||||
rprio = lprio + 1;
|
||||
|
||||
maybe_reduce:
|
||||
/* Push an operator, and check if we can reduce now. */
|
||||
while (top->rprio > lprio)
|
||||
@ -1065,6 +1039,5 @@ cpp_parse_expr (pfile)
|
||||
syntax_error:
|
||||
if (stack != init_stack)
|
||||
free (stack);
|
||||
skip_rest_of_line (pfile);
|
||||
return 0;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ redundant_include_p (pfile, ihash, ilist)
|
||||
included again if the string is the name of a defined macro. */
|
||||
return (i->control_macro
|
||||
&& (i->control_macro[0] == '\0'
|
||||
|| cpp_lookup (pfile, i->control_macro, -1)))
|
||||
|| cpp_defined (pfile, i->control_macro, -1)))
|
||||
? (struct include_hash *)-1 : i;
|
||||
|
||||
return 0;
|
||||
|
@ -140,20 +140,31 @@ cpp_lookup (pfile, name, len)
|
||||
return (HASHNODE *) 0;
|
||||
}
|
||||
|
||||
/* Free a DEFINITION structure. Used by delete_macro, and by
|
||||
do_define when redefining macros. */
|
||||
|
||||
void
|
||||
free_definition (d)
|
||||
DEFINITION *d;
|
||||
{
|
||||
struct reflist *ap, *nextap;
|
||||
|
||||
for (ap = d->pattern; ap != NULL; ap = nextap)
|
||||
{
|
||||
nextap = ap->next;
|
||||
free (ap);
|
||||
}
|
||||
if (d->nargs >= 0)
|
||||
free (d->argnames);
|
||||
free (d);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a hash node. Some weirdness to free junk from macros.
|
||||
* More such weirdness will have to be added if you define more hash
|
||||
* types that need it.
|
||||
*/
|
||||
|
||||
/* Note that the DEFINITION of a macro is removed from the hash table
|
||||
but its storage is not freed. This would be a storage leak
|
||||
except that it is not reasonable to keep undefining and redefining
|
||||
large numbers of macros many times.
|
||||
In any case, this is necessary, because a macro can be #undef'd
|
||||
in the middle of reading the arguments to a call to it.
|
||||
If #undef freed the DEFINITION, that would crash. */
|
||||
|
||||
void
|
||||
delete_macro (hp)
|
||||
HASHNODE *hp;
|
||||
@ -170,19 +181,7 @@ delete_macro (hp)
|
||||
*hp->bucket_hdr = hp->next;
|
||||
|
||||
if (hp->type == T_MACRO)
|
||||
{
|
||||
DEFINITION *d = hp->value.defn;
|
||||
struct reflist *ap, *nextap;
|
||||
|
||||
for (ap = d->pattern; ap != NULL; ap = nextap)
|
||||
{
|
||||
nextap = ap->next;
|
||||
free (ap);
|
||||
}
|
||||
if (d->nargs >= 0)
|
||||
free (d->argnames);
|
||||
free (d);
|
||||
}
|
||||
free_definition (hp->value.defn);
|
||||
|
||||
free (hp);
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ union hashval
|
||||
struct hashnode *aschain; /* #assert */
|
||||
};
|
||||
|
||||
typedef struct hashnode HASHNODE;
|
||||
struct hashnode {
|
||||
struct hashnode *next; /* double links for easy deletion */
|
||||
struct hashnode *prev;
|
||||
@ -97,6 +98,8 @@ struct hashnode {
|
||||
|
||||
extern HASHNODE *cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int,
|
||||
enum node_type, const char *));
|
||||
extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
extern void free_definition PARAMS ((DEFINITION *));
|
||||
extern void delete_macro PARAMS ((HASHNODE *));
|
||||
|
||||
extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
|
||||
|
65
gcc/cpplib.c
65
gcc/cpplib.c
@ -93,11 +93,12 @@ static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
|
||||
static int skip_comment PARAMS ((cpp_reader *, int));
|
||||
static int copy_comment PARAMS ((cpp_reader *, int));
|
||||
static void copy_rest_of_line PARAMS ((cpp_reader *));
|
||||
static void skip_rest_of_line PARAMS ((cpp_reader *));
|
||||
static void cpp_skip_hspace PARAMS ((cpp_reader *));
|
||||
static int handle_directive PARAMS ((cpp_reader *));
|
||||
static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
|
||||
cpp_reader *,
|
||||
const struct directive *));
|
||||
static enum cpp_token get_directive_token PARAMS ((cpp_reader *));
|
||||
static int read_line_number PARAMS ((cpp_reader *, int *));
|
||||
static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *));
|
||||
static int consider_directive_while_skipping PARAMS ((cpp_reader *,
|
||||
@ -192,12 +193,7 @@ cpp_grow_buffer (pfile, n)
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
}
|
||||
|
||||
/* Process the string STR as if it appeared as the body of a #define
|
||||
If STR is just an identifier, define it with value 1.
|
||||
If STR has anything after the identifier, then it should
|
||||
be identifier=definition. */
|
||||
|
||||
/* Process the string STR as if it appeared as the body of a #define
|
||||
/* Process the string STR as if it appeared as the body of a #define.
|
||||
If STR is just an identifier, define it with value 1.
|
||||
If STR has anything after the identifier, then it should
|
||||
be identifier=definition. */
|
||||
@ -252,6 +248,21 @@ cpp_assert (pfile, str)
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether the identifier ID, of length LEN, is a defined macro. */
|
||||
int
|
||||
cpp_defined (pfile, id, len)
|
||||
cpp_reader *pfile;
|
||||
const U_CHAR *id;
|
||||
int len;
|
||||
{
|
||||
HASHNODE *hp = cpp_lookup (pfile, id, len);
|
||||
if (hp && hp->type == T_POISON)
|
||||
{
|
||||
cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
|
||||
return 0;
|
||||
}
|
||||
return (hp != NULL);
|
||||
}
|
||||
|
||||
static enum cpp_token
|
||||
null_underflow (pfile)
|
||||
@ -407,7 +418,7 @@ copy_comment (pfile, m)
|
||||
|
||||
/* Skip whitespace \-newline and comments. Does not macro-expand. */
|
||||
|
||||
void
|
||||
static void
|
||||
cpp_skip_hspace (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
@ -508,7 +519,7 @@ copy_rest_of_line (pfile)
|
||||
the scan itself. >75% of calls to copy_r_o_l are from here or
|
||||
skip_if_group, which means the common case is to copy stuff into the
|
||||
token_buffer only to discard it. */
|
||||
void
|
||||
static void
|
||||
skip_rest_of_line (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
@ -684,11 +695,8 @@ do_define (pfile, keyword)
|
||||
if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL)
|
||||
{
|
||||
int ok = 0;
|
||||
/* Redefining a precompiled key is ok. */
|
||||
if (hp->type == T_PCSTRING)
|
||||
ok = 1;
|
||||
/* Redefining a poisoned identifier is even worse than `not ok'. */
|
||||
else if (hp->type == T_POISON)
|
||||
if (hp->type == T_POISON)
|
||||
ok = -1;
|
||||
/* Redefining a macro is ok if the definitions are the same. */
|
||||
else if (hp->type == T_MACRO)
|
||||
@ -713,6 +721,7 @@ do_define (pfile, keyword)
|
||||
{
|
||||
/* Replace the old definition. */
|
||||
hp->type = new_type;
|
||||
free_definition (hp->value.defn);
|
||||
hp->value.defn = mdef.defn;
|
||||
}
|
||||
}
|
||||
@ -986,7 +995,7 @@ output_line_command (pfile, file_change)
|
||||
/* Like cpp_get_token, except that it does not read past end-of-line.
|
||||
Also, horizontal space is skipped, and macros are popped. */
|
||||
|
||||
static enum cpp_token
|
||||
enum cpp_token
|
||||
get_directive_token (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
@ -1872,8 +1881,13 @@ eval_if_expression (pfile)
|
||||
HOST_WIDEST_INT value;
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
|
||||
/* Work around bug in cpp_get_token where it may mistake an
|
||||
assertion for a directive. */
|
||||
pfile->only_seen_white = 0;
|
||||
|
||||
value = cpp_parse_expr (pfile);
|
||||
|
||||
skip_rest_of_line (pfile);
|
||||
CPP_SET_WRITTEN (pfile, old_written); /* Pop */
|
||||
|
||||
return value;
|
||||
@ -2631,10 +2645,7 @@ cpp_get_token (pfile)
|
||||
return CPP_NAME;
|
||||
}
|
||||
|
||||
/* If macro wants an arglist, verify that a '(' follows.
|
||||
first skip all whitespace, copying it to the output
|
||||
after the macro name. Then, if there is no '(',
|
||||
decide this is not a macro call and leave things that way. */
|
||||
/* If macro wants an arglist, verify that a '(' follows. */
|
||||
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
|
||||
{
|
||||
int macbuf_whitespace = 0;
|
||||
@ -3130,9 +3141,9 @@ int
|
||||
cpp_read_check_assertion (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
U_CHAR *name = CPP_PWRITTEN (pfile);
|
||||
U_CHAR *name;
|
||||
int result;
|
||||
HASHNODE *hp;
|
||||
long written = CPP_WRITTEN (pfile);
|
||||
|
||||
FORWARD (1); /* Skip '#' */
|
||||
cpp_skip_hspace (pfile);
|
||||
@ -3140,15 +3151,21 @@ cpp_read_check_assertion (pfile)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name);
|
||||
result = (hp != 0);
|
||||
name = pfile->token_buffer + written;
|
||||
result = cpp_defined (pfile, name, CPP_PWRITTEN (pfile) - name);
|
||||
}
|
||||
|
||||
pfile->limit = name;
|
||||
CPP_SET_WRITTEN (pfile, written);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Remember the current position of PFILE. */
|
||||
/* Remember the current position of PFILE so it may be returned to
|
||||
after looking ahead a bit.
|
||||
|
||||
Note that when you set a mark, you _must_ return to that mark. You
|
||||
may not forget about it and continue parsing. You may not pop a
|
||||
buffer with an active mark. You may not call CPP_BUMP_LINE while a
|
||||
mark is active. */
|
||||
|
||||
static void
|
||||
parse_set_mark (pfile)
|
||||
|
11
gcc/cpplib.h
11
gcc/cpplib.h
@ -61,8 +61,8 @@ typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
|
||||
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
|
||||
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
|
||||
extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
|
||||
extern void cpp_skip_hspace PARAMS((cpp_reader *));
|
||||
extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
|
||||
|
||||
/* This frees resources used by PFILE. */
|
||||
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
|
||||
@ -139,9 +139,6 @@ struct file_name_map_list;
|
||||
Applying cpp_get_token repeatedly yields a stream of pre-processor
|
||||
tokens. Usually, there is only one cpp_reader object active. */
|
||||
|
||||
struct hashnode;
|
||||
typedef struct hashnode HASHNODE;
|
||||
|
||||
struct cpp_reader
|
||||
{
|
||||
parse_underflow_t get_token;
|
||||
@ -169,7 +166,7 @@ struct cpp_reader
|
||||
|
||||
/* Hash table of macros and assertions. See cpphash.c */
|
||||
#define HASHSIZE 1403
|
||||
HASHNODE **hashtab;
|
||||
struct hashnode **hashtab;
|
||||
|
||||
/* Hash table of other included files. See cppfiles.c */
|
||||
#define ALL_INCLUDE_HASHSIZE 71
|
||||
@ -600,7 +597,6 @@ enum node_type {
|
||||
T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
|
||||
T_MACRO, /* macro defined by `#define' */
|
||||
T_DISABLED, /* macro temporarily turned off for rescan */
|
||||
T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
|
||||
T_POISON, /* defined with `#pragma poison' */
|
||||
T_UNUSED /* Used for something not defined. */
|
||||
};
|
||||
@ -686,13 +682,12 @@ extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
|
||||
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
|
||||
unsigned char *, long));
|
||||
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
|
||||
extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
extern int cpp_defined PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
|
||||
extern void cpp_reader_init PARAMS ((cpp_reader *));
|
||||
extern void cpp_options_init PARAMS ((cpp_options *));
|
||||
extern int cpp_start_read PARAMS ((cpp_reader *, char *));
|
||||
extern int cpp_read_check_assertion PARAMS ((cpp_reader *));
|
||||
extern void skip_rest_of_line PARAMS ((cpp_reader *));
|
||||
extern void cpp_finish PARAMS ((cpp_reader *));
|
||||
|
||||
extern void quote_string PARAMS ((cpp_reader *, const char *));
|
||||
|
@ -603,7 +603,7 @@ check_macro_names (pfile, names)
|
||||
{
|
||||
while (*names)
|
||||
{
|
||||
if (cpp_lookup (pfile, names, -1))
|
||||
if (cpp_defined (pfile, names, -1))
|
||||
recognized_macro (names);
|
||||
names += strlen (names) + 1;
|
||||
}
|
||||
@ -626,6 +626,10 @@ read_scan_file (in_fname, argc, argv)
|
||||
cpp_reader_init (&scan_in);
|
||||
scan_in.opts = &scan_options;
|
||||
cpp_options_init (&scan_options);
|
||||
/* We are going to be scanning a header file out of its proper context,
|
||||
so ignore warnings and errors. */
|
||||
scan_options.inhibit_warnings = 1;
|
||||
scan_options.inhibit_errors = 1;
|
||||
i = cpp_handle_options (&scan_in, argc, argv);
|
||||
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
|
||||
cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
|
||||
|
16
gcc/testsuite/gcc.dg/20000207-1.c
Normal file
16
gcc/testsuite/gcc.dg/20000207-1.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do preprocess } */
|
||||
|
||||
/* Test for proper handling of unary minus in #if. */
|
||||
|
||||
#if !(-1)
|
||||
#error Error /* { dg-bogus "Error" "case !(-1)" } */
|
||||
#endif
|
||||
|
||||
#if !-1
|
||||
#error Error /* { dg-bogus "Error" "case !-1" } */
|
||||
#endif
|
||||
|
||||
#if -1
|
||||
#else
|
||||
#error Error /* { dg-bogus "Error" "case -1" } */
|
||||
#endif
|
16
gcc/testsuite/gcc.dg/20000207-2.c
Normal file
16
gcc/testsuite/gcc.dg/20000207-2.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do preprocess } */
|
||||
|
||||
/* Test for proper handling of unary plus in #if. */
|
||||
|
||||
#if !(+1)
|
||||
#error Error /* { dg-bogus "Error" "case !(+1)" } */
|
||||
#endif
|
||||
|
||||
#if !+1
|
||||
#error Error /* { dg-bogus "Error" "case !+1" } */
|
||||
#endif
|
||||
|
||||
#if +1
|
||||
#else
|
||||
#error Error /* { dg-bogus "Error" "case +1" } */
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user