+2000-05-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.h: Add accessor macros for token lists.
+ * cpplib.c, cpphash.c, cpplex.c: Use them.
+
Wed May 3 09:29:17 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (expand_expr, case COMPONENT_REF): Don't check for checking
for (i = 1; i < list->tokens_used; i++)
{
- switch (list->tokens[i].type)
+ switch (TOK_TYPE (list, i))
{
case CPP_EOF:
cpp_ice (pfile, "EOF in collect_expansion");
default:;
}
- if (i > 1 && !last_was_paste
- && (list->tokens[i].flags & PREV_WHITESPACE))
+ if (i > 1 && !last_was_paste && TOK_PREV_WHITE (list, i))
CPP_PUTC (pfile, ' ');
- CPP_PUTS (pfile,
- list->tokens[i].val.name.offset + list->namebuf,
- list->tokens[i].val.name.len);
+ CPP_PUTS (pfile, TOK_NAME (list, i), TOK_LEN (list, i));
last_was_paste = 0;
}
done:
for (i = replacement; i < list->tokens_used; i++)
{
- token = list->tokens[i].type;
- tok = list->tokens[i].val.name.offset + list->namebuf;
- len = list->tokens[i].val.name.len;
+ token = TOK_TYPE (list, i);
+ tok = TOK_NAME (list, i);
+ len = TOK_LEN (list, i);
switch (token)
{
case CPP_EOF:
}
if (last_token != PASTE && last_token != START
- && (list->tokens[i].flags & PREV_WHITESPACE))
+ && TOK_PREV_WHITE (list, i))
CPP_PUTC (pfile, ' ');
if (last_token == ARG && CPP_TRADITIONAL (pfile)
- && !(list->tokens[i].flags & PREV_WHITESPACE))
+ && !TOK_PREV_WHITE (list, i))
endpat->raw_after = 1;
switch (token)
{
int raw_before = (last_token == PASTE
|| (CPP_TRADITIONAL (pfile)
- && !(list->tokens[i].flags & PREV_WHITESPACE)));
+ && ! TOK_PREV_WHITE (list, j)));
add_pat (&pat, &endpat,
CPP_WRITTEN (pfile) - last /* nchars */, j /* argno */,
unsigned int argc, a, i, j;
/* The formal parameters list starts at token 1. */
- if (list->tokens[1].type != CPP_OPEN_PAREN)
+ if (TOK_TYPE (list, 1) != CPP_OPEN_PAREN)
{
cpp_ice (pfile, "first token = %d not %d in collect_formal_parameters",
- list->tokens[1].type, CPP_OPEN_PAREN);
+ TOK_TYPE (list, 1), CPP_OPEN_PAREN);
return 0;
}
argc = 0;
argslen = 0;
for (i = 2; i < list->tokens_used; i++)
- switch (list->tokens[i].type)
+ switch (TOK_TYPE (list, i))
{
case CPP_NAME:
- argslen += list->tokens[i].val.name.len + 1;
+ argslen += TOK_LEN (list, i) + 1;
argc++;
break;
case CPP_COMMA:
case CPP_CLOSE_PAREN:
goto scanned;
case CPP_VSPACE:
- cpp_error_with_line (pfile, list->line, list->tokens[i].col,
+ cpp_error_with_line (pfile, list->line, TOK_COL (list, i),
"missing right paren in macro argument list");
return 0;
default:
- cpp_error_with_line (pfile, list->line, list->tokens[i].col,
- "syntax error in #define");
+ cpp_error_with_line (pfile, list->line, TOK_COL (list, i),
+ "illegal token in macro argument list");
return 0;
case CPP_ELLIPSIS:
- if (list->tokens[i-1].type != CPP_NAME)
+ if (TOK_TYPE (list, i-1) != CPP_NAME)
{
argslen += sizeof "__VA_ARGS__";
argc++;
}
i++;
- if (list->tokens[i].type != CPP_CLOSE_PAREN)
+ if (TOK_TYPE (list, i) != CPP_CLOSE_PAREN)
{
- cpp_error_with_line (pfile, list->line, list->tokens[i].col,
+ cpp_error_with_line (pfile, list->line, TOK_COL (list, i),
"another parameter follows \"...\"");
return 0;
}
}
cpp_ice (pfile, "collect_params: unreachable - i=%d, ntokens=%d, type=%d",
- i, list->tokens_used, list->tokens[i-1].type);
+ i, list->tokens_used, TOK_TYPE (list, i-1));
return 0;
scanned:
p = namebuf;
a = 0;
for (j = 2; j < i; j++)
- switch (list->tokens[j].type)
+ switch (TOK_TYPE (list, j))
{
case CPP_NAME:
- tok = list->tokens[j].val.name.offset + list->namebuf;
- len = list->tokens[j].val.name.len;
+ tok = TOK_NAME (list, j);
+ len = TOK_LEN (list, j);
memcpy (p, tok, len);
p[len] = '\0';
if (duplicate_arg_p (namebuf, p))
break;
case CPP_ELLIPSIS:
- if (list->tokens[j-1].type != CPP_NAME)
+ if (TOK_TYPE (list, j-1) != CPP_NAME)
{
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99))
cpp_pedwarn (pfile, "C89 does not permit varargs macros");
default:
cpp_ice (pfile, "collect_params: impossible token type %d",
- list->tokens[j].type);
+ TOK_TYPE (list, j));
}
arglist->argc = argc;
if (list->tokens_used == 2)
ntype = T_EMPTY; /* Empty definition of object-like macro. */
- else if (list->tokens_used == 3 && list->tokens[1].type == CPP_NAME
- && list->tokens[0].val.name.len == list->tokens[1].val.name.len
- && !strncmp (list->tokens[0].val.name.offset + list->namebuf,
- list->tokens[1].val.name.offset + list->namebuf,
- list->tokens[0].val.name.len))
+ else if (list->tokens_used == 3 && TOK_TYPE (list, 1) == CPP_NAME
+ && TOK_LEN (list, 0) == TOK_LEN (list, 1)
+ && !strncmp (TOK_NAME (list, 0), TOK_NAME (list, 1),
+ TOK_LEN (list, 0)))
ntype = T_IDENTITY; /* Object like macro defined to itself. */
/* The macro is function-like only if the next character,
with no intervening whitespace, is '('. */
- else if (list->tokens[1].type == CPP_OPEN_PAREN
- && ! (list->tokens[1].flags & PREV_WHITESPACE))
+ else if (TOK_TYPE (list, 1) == CPP_OPEN_PAREN
+ && ! TOK_PREV_WHITE (list, 1))
{
struct arglist args;
int replacement;
whitespace after the name (6.10.3 para 3). */
else
{
- if (! (list->tokens[1].flags & PREV_WHITESPACE))
+ if (! TOK_PREV_WHITE (list, 1))
cpp_pedwarn (pfile,
"The C standard requires whitespace after #define %s",
hp->name);
{
fdefn->file = CPP_BUFFER (pfile)->nominal_fname;
fdefn->line = list->line;
- fdefn->col = list->tokens[0].col;
+ fdefn->col = TOK_COL (list, 0);
hp->value.fdefn = fdefn;
}
else
{
odefn->file = CPP_BUFFER (pfile)->nominal_fname;
odefn->line = list->line;
- odefn->col = list->tokens[0].col;
+ odefn->col = TOK_COL (list, 0);
hp->value.odefn = odefn;
}
return 1;
for (i = 0; i < list->tokens_used; i++)
{
- if (list->tokens[i].type == CPP_VSPACE)
+ if (TOK_TYPE (list, i) == CPP_VSPACE)
{
output_line_command (pfile, print, list->tokens[i].aux);
continue;
}
- if (curcol < list->tokens[i].col)
+ if (curcol < TOK_COL (list, i))
{
/* Insert space to bring the column to what it should be. */
- bump_column (print, curcol - 1, list->tokens[i].col);
- curcol = list->tokens[i].col;
+ bump_column (print, curcol - 1, TOK_COL (list, i));
+ curcol = TOK_COL (list, i);
}
/* XXX We may have to insert space to prevent an accidental
token paste. */
- safe_fwrite (pfile, list->namebuf + list->tokens[i].val.name.offset,
- list->tokens[i].val.name.len, print->outf);
- curcol += list->tokens[i].val.name.len;
+ safe_fwrite (pfile, TOK_NAME (list, i), TOK_LEN (list, i), print->outf);
+ curcol += TOK_LEN (list, i);
}
}
type = CPP_NAME;
list->tokens_used++;
- list->tokens[i].type = type;
- list->tokens[i].col = col;
- list->tokens[i].flags = space_before ? PREV_WHITESPACE : 0;
+ TOK_TYPE (list, i) = type;
+ TOK_COL (list, i) = col;
+ TOK_FLAGS (list, i) = space_before ? PREV_WHITESPACE : 0;
if (type == CPP_VSPACE)
break;
- list->tokens[i].val.name.len = len;
- list->tokens[i].val.name.offset = list->name_used;
- memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len);
+ TOK_LEN (list, i) = len;
+ TOK_OFFSET (list, i) = list->name_used;
+ memcpy (TOK_NAME (list, i), CPP_PWRITTEN (pfile), len);
list->name_used += len;
i++;
space_before = 0;
}
- list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1;
+ TOK_AUX (list, i) = CPP_BUFFER (pfile)->lineno + 1;
/* XXX Temporary kluge: put back the newline. */
FORWARD(-1);
#define INIT_NAME(list, name) \
do {(name).len = 0; (name).offset = (list)->name_used;} while (0)
-#define IS_DIRECTIVE(list) (list->tokens[0].type == CPP_HASH)
+#define IS_DIRECTIVE(list) (TOK_TYPE (list, 0) == CPP_HASH)
#define COLUMN(cur) ((cur) - buffer->line_base)
/* Maybe put these in the ISTABLE eventually. */
/* Do we have a wide string? */
if (cur_token[-1].type == CPP_NAME && IMMED_TOKEN ()
&& cur_token[-1].val.name.len == 1
- && TOK_NAME (list, cur_token - 1)[0] == 'L'
+ && *(list->namebuf + cur_token[-1].val.name.offset) == 'L'
&& !CPP_TRADITIONAL (pfile))
{
/* No need for 'L' any more. */
*buffer++ = c;
len = token->val.name.len;
- memcpy (buffer, TOK_NAME (list, token), len);
+ memcpy (buffer, list->namebuf + token->val.name.offset, len);
buffer += len;
*buffer++ = c;
return buffer - orig_buff;
}
len = token->val.name.len;
- memcpy (buffer, TOK_NAME (list, token), len);
+ memcpy (buffer, list->namebuf + token->val.name.offset, len);
return len + 2;
}
size_t len;
len = token->val.name.len;
- memcpy (buffer, TOK_NAME (list, token), len);
+ memcpy (buffer, list->namebuf + token->val.name.offset, len);
buffer += len;
return len;
/* First token on the line must be a NAME. There must be at least
one token (the VSPACE at the end). */
- if (list->tokens[0].type != CPP_NAME)
+ if (TOK_TYPE (list, 0) != CPP_NAME)
{
- cpp_error_with_line (pfile, list->line, list->tokens[0].col,
+ cpp_error_with_line (pfile, list->line, TOK_COL (list, 0),
"#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;
+ sym = TOK_NAME (list, 0);
+ len = TOK_LEN (list, 0);
/* 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,
+ cpp_error_with_line (pfile, list->line, TOK_COL (list, 0),
"\"defined\" is not a legal macro name");
goto out;
}
unsigned int offset; /* from list->namebuf */
};
-#define TOK_NAME(list, token) ((list)->namebuf + (token)->val.name.offset)
+/* Accessor macros for token lists - all expect you have a
+ list and an index. */
+
+#define TOK_TYPE(l_, i_) ((l_)->tokens[i_].type)
+#define TOK_FLAGS(l_, i_) ((l_)->tokens[i_].flags)
+#define TOK_AUX(l_, i_) ((l_)->tokens[i_].aux)
+#define TOK_COL(l_, i_) ((l_)->tokens[i_].col)
+#define TOK_INT(l_, i_) ((l_)->tokens[i_].val.integer)
+#define TOK_OFFSET(l_, i_) ((l_)->tokens[i_].val.name.offset)
+#define TOK_NAME(l_, i_) ((l_)->tokens[i_].val.name.offset + (l_)->namebuf)
+#define TOK_LEN(l_, i_) ((l_)->tokens[i_].val.name.len)
+
+#define TOK_PREV_WHITE(l_, i_) (TOK_FLAGS(l_, i_) & PREV_WHITESPACE)
/* Flags for the cpp_token structure. */
#define PREV_WHITESPACE 1 /* If whitespace before this token. */
#define DIGRAPH 2 /* If it was a digraph. */
#define UNSIGNED_INT 4 /* If int preprocessing token unsigned. */
-/* A preprocessing token.
- This has been carefully packed and should occupy 16 bytes on
- both 32- and 64-bit hosts. */
+/* A preprocessing token. This has been carefully packed and should
+ occupy 16 bytes on both 32- and 64-bit hosts. */
struct cpp_token
{
unsigned short col; /* starting column of this token */
-#ifdef ENUM_BITFIELDS_ARE_UNSIGNED
- enum cpp_ttype type : CHAR_BIT; /* node type */
-#else
- unsigned char type;
-#endif
+ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* node type */
unsigned char flags; /* flags - see above */
unsigned int aux; /* CPP_OTHER character. Hash of a
NAME, or something - see uses