Commit 9e62c811 by Zack Weinberg Committed by Zack Weinberg

cpphash.c (struct arg, [...]): Const-ify strings.

	* cpphash.c (struct arg, struct arglist): Const-ify strings.
	(warn_trad_stringify, duplicate_arg_p): New helper functions.
	(collect_expansion): Rewrite to scan over a token list.
	Remove -traditional support.
	(collect_formal_parameters): Rename to collect_params; rewrite
	to scan over a token list.
	(_cpp_create_definition): Adjust to scan a token list.
	(_cpp_macroexpand): Remove -traditional support.
	(_cpp_compare_defs): Whitespace is now canonicalized.
	(comp_def_part): Delete function.

	* cpphash.h: Update prototypes.
	* cpplex.c (init_token_list): Don't set lineno if there is no
	buffer.
	(pedantic_whitespace): New function.
	(_cpp_scan_line): Mark tokens that had hspace before.  Don't
	consume a newline.  Use pedantic_whitespace.
	(_cpp_lex_token): Remove support for -traditional macros.
	(_cpp_get_define_token): Delete.
	(_cpp_get_directive_token): Do the real work here.  Use
	pedantic_whitespace.
	(_cpp_init_input_buffer): Initialize pfile->directbuf.

	* cpplib.c (get_macro_name): Delete.
	(do_define): Read the entire line into pfile->directbuf, then
	feed the token list to _cpp_create_definition.
	* cpplib.h (HSPACE_BEFORE): new define.
	(struct cpp_reader): Add a toklist member, "directbuf".

From-SVN: r33309
parent 152897b1
2000-04-21 Zack Weinberg <zack@wolery.cumb.org> 2000-04-21 Zack Weinberg <zack@wolery.cumb.org>
* cpphash.c (struct arg, struct arglist): Const-ify strings.
(warn_trad_stringify, duplicate_arg_p): New helper functions.
(collect_expansion): Rewrite to scan over a token list.
Remove -traditional support.
(collect_formal_parameters): Rename to collect_params; rewrite
to scan over a token list.
(_cpp_create_definition): Adjust to scan a token list.
(_cpp_macroexpand): Remove -traditional support.
(_cpp_compare_defs): Whitespace is now canonicalized.
(comp_def_part): Delete function.
* cpphash.h: Update prototypes.
* cpplex.c (init_token_list): Don't set lineno if there is no
buffer.
(pedantic_whitespace): New function.
(_cpp_scan_line): Mark tokens that had hspace before. Don't
consume a newline. Use pedantic_whitespace.
(_cpp_lex_token): Remove support for -traditional macros.
(_cpp_get_define_token): Delete.
(_cpp_get_directive_token): Do the real work here. Use
pedantic_whitespace.
(_cpp_init_input_buffer): Initialize pfile->directbuf.
* cpplib.c (get_macro_name): Delete.
(do_define): Read the entire line into pfile->directbuf, then
feed the token list to _cpp_create_definition.
* cpplib.h (HSPACE_BEFORE): new define.
(struct cpp_reader): Add a toklist member, "directbuf".
* predict.c (estimate_probability): New heuristic: if a jump * predict.c (estimate_probability): New heuristic: if a jump
branches around a block with no successors, predict it taken. branches around a block with no successors, predict it taken.
Disentangle control flow. Disentangle control flow.
......
...@@ -272,7 +272,8 @@ extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *, ...@@ -272,7 +272,8 @@ extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *,
enum insert_option, enum insert_option,
unsigned long *)); unsigned long *));
extern void _cpp_free_definition PARAMS ((DEFINITION *)); extern void _cpp_free_definition PARAMS ((DEFINITION *));
extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *, int)); extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *,
cpp_toklist *, int));
extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *, extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *,
long, DEFINITION *)); long, DEFINITION *));
extern int _cpp_compare_defs PARAMS ((cpp_reader *, DEFINITION *, extern int _cpp_compare_defs PARAMS ((cpp_reader *, DEFINITION *,
......
...@@ -57,6 +57,8 @@ static void bump_column PARAMS ((cpp_printer *, unsigned int, ...@@ -57,6 +57,8 @@ static void bump_column PARAMS ((cpp_printer *, unsigned int,
static void expand_name_space PARAMS ((cpp_toklist *)); static void expand_name_space PARAMS ((cpp_toklist *));
static void expand_token_space PARAMS ((cpp_toklist *)); static void expand_token_space PARAMS ((cpp_toklist *));
static void init_token_list PARAMS ((cpp_reader *, cpp_toklist *, int)); static void init_token_list PARAMS ((cpp_reader *, cpp_toklist *, int));
static void pedantic_whitespace PARAMS ((cpp_reader *, U_CHAR *,
unsigned int));
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */ /* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
...@@ -474,7 +476,8 @@ init_token_list (pfile, list, recycle) ...@@ -474,7 +476,8 @@ init_token_list (pfile, list, recycle)
list->namebuf = (unsigned char *) xmalloc (list->name_cap); list->namebuf = (unsigned char *) xmalloc (list->name_cap);
} }
list->line = pfile->buffer->lineno; if (pfile->buffer)
list->line = pfile->buffer->lineno;
list->dir_handler = 0; list->dir_handler = 0;
list->dir_flags = 0; list->dir_flags = 0;
} }
...@@ -490,11 +493,13 @@ _cpp_scan_line (pfile, list) ...@@ -490,11 +493,13 @@ _cpp_scan_line (pfile, list)
int i, col; int i, col;
long written, len; long written, len;
enum cpp_ttype type; enum cpp_ttype type;
int space_before;
init_token_list (pfile, list, 1); init_token_list (pfile, list, 1);
written = CPP_WRITTEN (pfile); written = CPP_WRITTEN (pfile);
i = 0; i = 0;
space_before = 0;
for (;;) for (;;)
{ {
col = CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base; col = CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base;
...@@ -502,17 +507,26 @@ _cpp_scan_line (pfile, list) ...@@ -502,17 +507,26 @@ _cpp_scan_line (pfile, list)
len = CPP_WRITTEN (pfile) - written; len = CPP_WRITTEN (pfile) - written;
CPP_SET_WRITTEN (pfile, written); CPP_SET_WRITTEN (pfile, written);
if (type == CPP_HSPACE) if (type == CPP_HSPACE)
continue; {
if (CPP_PEDANTIC (pfile))
pedantic_whitespace (pfile, pfile->token_buffer + written, len);
space_before = 1;
continue;
}
if (list->tokens_used >= list->tokens_cap) if (list->tokens_used >= list->tokens_cap)
expand_token_space (list); expand_token_space (list);
if (list->name_used + len >= list->name_cap) if (list->name_used + len >= list->name_cap)
expand_name_space (list); expand_name_space (list);
if (type == CPP_MACRO)
type = CPP_NAME;
list->tokens_used++; list->tokens_used++;
list->tokens[i].type = type; list->tokens[i].type = type;
list->tokens[i].col = col; list->tokens[i].col = col;
list->tokens[i].flags = space_before ? HSPACE_BEFORE : 0;
if (type == CPP_VSPACE) if (type == CPP_VSPACE)
break; break;
...@@ -521,8 +535,12 @@ _cpp_scan_line (pfile, list) ...@@ -521,8 +535,12 @@ _cpp_scan_line (pfile, list)
memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len); memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len);
list->name_used += len; list->name_used += len;
i++; i++;
space_before = 0;
} }
list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1; list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1;
/* XXX Temporary kluge: put back the newline. */
FORWARD(-1);
} }
...@@ -1034,14 +1052,8 @@ _cpp_lex_token (pfile) ...@@ -1034,14 +1052,8 @@ _cpp_lex_token (pfile)
For -traditional, a comment is equivalent to nothing. */ For -traditional, a comment is equivalent to nothing. */
if (!CPP_OPTION (pfile, discard_comments)) if (!CPP_OPTION (pfile, discard_comments))
return CPP_COMMENT; return CPP_COMMENT;
else if (CPP_TRADITIONAL (pfile) else if (CPP_TRADITIONAL (pfile))
&& ! is_space (PEEKC ())) goto get_next;
{
if (pfile->parsing_define_directive)
return CPP_COMMENT;
else
goto get_next;
}
else else
{ {
CPP_PUTC (pfile, c); CPP_PUTC (pfile, c);
...@@ -1060,7 +1072,7 @@ _cpp_lex_token (pfile) ...@@ -1060,7 +1072,7 @@ _cpp_lex_token (pfile)
return CPP_OTHER; return CPP_OTHER;
} }
if (pfile->parsing_define_directive && ! CPP_TRADITIONAL (pfile)) if (pfile->parsing_define_directive)
{ {
c2 = PEEKC (); c2 = PEEKC ();
if (c2 == '#') if (c2 == '#')
...@@ -1510,6 +1522,26 @@ maybe_macroexpand (pfile, written) ...@@ -1510,6 +1522,26 @@ maybe_macroexpand (pfile, written)
return 1; return 1;
} }
/* Complain about \v or \f in a preprocessing directive (constraint
violation, C99 6.10 para 5). Caller has checked CPP_PEDANTIC. */
static void
pedantic_whitespace (pfile, p, len)
cpp_reader *pfile;
U_CHAR *p;
unsigned int len;
{
while (len)
{
if (*p == '\v')
cpp_pedwarn (pfile, "vertical tab in preprocessing directive");
else if (*p == '\f')
cpp_pedwarn (pfile, "form feed in preprocessing directive");
p++;
len--;
}
}
enum cpp_ttype enum cpp_ttype
cpp_get_token (pfile) cpp_get_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
...@@ -1591,14 +1623,10 @@ cpp_get_non_space_token (pfile) ...@@ -1591,14 +1623,10 @@ cpp_get_non_space_token (pfile)
} }
/* Like cpp_get_token, except that it does not execute directives, /* Like cpp_get_token, except that it does not execute directives,
does not consume vertical space, and automatically pops off macro does not consume vertical space, discards horizontal space, and
buffers. automatically pops off macro buffers. */
XXX This function will exist only till collect_expansion doesn't
need to see whitespace anymore, then it'll be merged with
_cpp_get_directive_token (below). */
enum cpp_ttype enum cpp_ttype
_cpp_get_define_token (pfile) _cpp_get_directive_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
long old_written; long old_written;
...@@ -1620,18 +1648,10 @@ _cpp_get_define_token (pfile) ...@@ -1620,18 +1648,10 @@ _cpp_get_define_token (pfile)
case CPP_HSPACE: case CPP_HSPACE:
if (CPP_PEDANTIC (pfile)) if (CPP_PEDANTIC (pfile))
{ pedantic_whitespace (pfile, pfile->token_buffer + old_written,
U_CHAR *p, *limit; CPP_WRITTEN (pfile) - old_written);
p = pfile->token_buffer + old_written; CPP_SET_WRITTEN (pfile, old_written);
limit = CPP_PWRITTEN (pfile); goto get_next;
while (p < limit)
{
if (*p == '\v' || *p == '\f')
cpp_pedwarn (pfile, "%s in preprocessing directive",
*p == '\f' ? "formfeed" : "vertical tab");
p++;
}
}
return CPP_HSPACE; return CPP_HSPACE;
case CPP_DIRECTIVE: case CPP_DIRECTIVE:
...@@ -1660,23 +1680,6 @@ _cpp_get_define_token (pfile) ...@@ -1660,23 +1680,6 @@ _cpp_get_define_token (pfile)
} }
} }
/* Just like _cpp_get_define_token except that it discards horizontal
whitespace. */
enum cpp_ttype
_cpp_get_directive_token (pfile)
cpp_reader *pfile;
{
int old_written = CPP_WRITTEN (pfile);
for (;;)
{
enum cpp_ttype token = _cpp_get_define_token (pfile);
if (token != CPP_COMMENT && token != CPP_HSPACE)
return token;
CPP_SET_WRITTEN (pfile, old_written);
}
}
/* Determine the current line and column. Used only by read_and_prescan. */ /* Determine the current line and column. Used only by read_and_prescan. */
static U_CHAR * static U_CHAR *
find_position (start, limit, linep) find_position (start, limit, linep)
...@@ -2008,6 +2011,7 @@ _cpp_init_input_buffer (pfile) ...@@ -2008,6 +2011,7 @@ _cpp_init_input_buffer (pfile)
U_CHAR *tmp; U_CHAR *tmp;
init_chartab (); init_chartab ();
init_token_list (pfile, &pfile->directbuf, 0);
/* Determine the appropriate size for the input buffer. Normal C /* Determine the appropriate size for the input buffer. Normal C
source files are smaller than eight K. */ source files are smaller than eight K. */
......
...@@ -66,7 +66,6 @@ static int read_line_number PARAMS ((cpp_reader *, int *)); ...@@ -66,7 +66,6 @@ static int read_line_number PARAMS ((cpp_reader *, int *));
static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *)); static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *));
static int consider_directive_while_skipping static int consider_directive_while_skipping
PARAMS ((cpp_reader *, IF_STACK *)); PARAMS ((cpp_reader *, IF_STACK *));
static int get_macro_name PARAMS ((cpp_reader *));
/* Values for the flags field of the table below. KANDR and COND /* Values for the flags field of the table below. KANDR and COND
directives come from traditional (K&R) C. The difference is, if we directives come from traditional (K&R) C. The difference is, if we
...@@ -310,36 +309,6 @@ pass_thru_directive (buf, len, pfile, keyword) ...@@ -310,36 +309,6 @@ pass_thru_directive (buf, len, pfile, keyword)
CPP_PUTS_Q (pfile, buf, len); CPP_PUTS_Q (pfile, buf, len);
} }
/* Subroutine of do_define: determine the name of the macro to be
defined. */
static int
get_macro_name (pfile)
cpp_reader *pfile;
{
long here, len;
here = CPP_WRITTEN (pfile);
if (_cpp_get_directive_token (pfile) != CPP_NAME)
{
cpp_error (pfile, "`#define' must be followed by an identifier");
goto invalid;
}
len = CPP_WRITTEN (pfile) - here;
if (len == 7 && !strncmp (pfile->token_buffer + here, "defined", 7))
{
cpp_error (pfile, "`defined' is not a legal macro name");
goto invalid;
}
return len;
invalid:
_cpp_skip_rest_of_line (pfile);
return 0;
}
/* Process a #define command. */ /* Process a #define command. */
static int static int
...@@ -348,47 +317,60 @@ do_define (pfile) ...@@ -348,47 +317,60 @@ do_define (pfile)
{ {
HASHNODE **slot; HASHNODE **slot;
DEFINITION *def = 0; DEFINITION *def = 0;
long here;
unsigned long hash; unsigned long hash;
int len; int len;
int funlike = 0, empty = 0; int funlike = 0, empty = 0;
U_CHAR *sym; U_CHAR *sym;
enum cpp_ttype token; cpp_toklist *list = &pfile->directbuf;
pfile->no_macro_expand++; pfile->no_macro_expand++;
pfile->parsing_define_directive++; pfile->parsing_define_directive++;
CPP_OPTION (pfile, discard_comments)++; CPP_OPTION (pfile, discard_comments)++;
here = CPP_WRITTEN (pfile); _cpp_scan_line (pfile, list);
len = get_macro_name (pfile);
if (len == 0)
goto out;
/* Copy out the name so we can pop the token buffer. */ /* First token on the line must be a NAME. There must be at least
len = CPP_WRITTEN (pfile) - here; one token (the VSPACE at the end). */
sym = (U_CHAR *) alloca (len + 1); if (list->tokens[0].type != CPP_NAME)
memcpy (sym, pfile->token_buffer + here, len); {
sym[len] = '\0'; cpp_error_with_line (pfile, list->line, list->tokens[0].col,
"#define must be followed by an identifier");
goto out;
}
sym = list->namebuf + list->tokens[0].val.name.offset;
len = list->tokens[0].val.name.len;
/* That NAME is not allowed to be "defined". (Not clear if the
standard requires this.) */
if (len == 7 && !strncmp (sym, "defined", 7))
{
cpp_error_with_line (pfile, list->line, list->tokens[0].col,
"\"defined\" is not a legal macro name");
goto out;
}
if (list->tokens_used == 2 && list->tokens[1].type == CPP_VSPACE)
empty = 0; /* Empty definition of object-like macro. */
/* If the next character, with no intervening whitespace, is '(', /* If the next character, with no intervening whitespace, is '(',
then this is a function-like macro. then this is a function-like macro. Otherwise it is an object-
XXX Layering violation. */ like macro, and C99 requires whitespace after the name
CPP_SET_MARK (pfile); (6.10.3 para 3). */
token = _cpp_get_directive_token (pfile); else if (!(list->tokens[1].flags & HSPACE_BEFORE))
if (token == CPP_VSPACE) {
empty = 0; /* Empty definition of object like macro. */ if (list->tokens[1].type == CPP_OPEN_PAREN)
else if (token == CPP_OPEN_PAREN && ADJACENT_TO_MARK (pfile)) funlike = 1;
funlike = 1; else
else if (ADJACENT_TO_MARK (pfile)) cpp_pedwarn (pfile,
/* If this is an object-like macro, C99 requires white space after "The C standard requires whitespace after #define %.*s",
the name. */ len, sym);
cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym); }
CPP_GOTO_MARK (pfile);
CPP_SET_WRITTEN (pfile, here);
if (! empty) if (! empty)
{ {
def = _cpp_create_definition (pfile, funlike); def = _cpp_create_definition (pfile, list, funlike);
if (def == 0) if (def == 0)
goto out; goto out;
} }
......
...@@ -135,6 +135,9 @@ struct cpp_name ...@@ -135,6 +135,9 @@ struct cpp_name
unsigned int offset; /* from list->namebuf */ unsigned int offset; /* from list->namebuf */
}; };
/* Per token flags. */
#define HSPACE_BEFORE (1 << 0) /* token preceded by hspace */
/* A preprocessing token. /* A preprocessing token.
This has been carefully packed and should occupy 16 bytes on This has been carefully packed and should occupy 16 bytes on
both 32- and 64-bit hosts. */ both 32- and 64-bit hosts. */
...@@ -146,7 +149,7 @@ struct cpp_token ...@@ -146,7 +149,7 @@ struct cpp_token
#else #else
unsigned char type; unsigned char type;
#endif #endif
unsigned char flags; /* flags - not presently used */ unsigned char flags; /* flags - see above */
unsigned int aux; /* hash of a NAME, or something - unsigned int aux; /* hash of a NAME, or something -
see uses in the code */ see uses in the code */
union union
...@@ -435,8 +438,12 @@ struct cpp_options ...@@ -435,8 +438,12 @@ struct cpp_options
struct cpp_reader struct cpp_reader
{ {
/* Top of buffer stack. */
cpp_buffer *buffer; cpp_buffer *buffer;
/* Token list used by get_directive_token. */
cpp_toklist directbuf;
/* A buffer used for both for cpp_get_token's output, and also internally. */ /* A buffer used for both for cpp_get_token's output, and also internally. */
unsigned char *token_buffer; unsigned char *token_buffer;
/* Allocated size of token_buffer. CPP_RESERVE allocates space. */ /* Allocated size of token_buffer. CPP_RESERVE allocates space. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment