diff options
author | Zack Weinberg <zack@wolery.cumb.org> | 2000-04-06 07:56:14 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2000-04-06 07:56:14 +0000 |
commit | ff2b53efb181ba999c0a4ceb4c473757c3ad8fda (patch) | |
tree | a3ed58746ede412e1a5592098f6237d21c4b4ed3 /gcc/cpplex.c | |
parent | edea3682660f51f996f0889202c029882a33788a (diff) | |
download | gcc-ff2b53efb181ba999c0a4ceb4c473757c3ad8fda.zip gcc-ff2b53efb181ba999c0a4ceb4c473757c3ad8fda.tar.gz gcc-ff2b53efb181ba999c0a4ceb4c473757c3ad8fda.tar.bz2 |
cpphash.c (CPP_IS_MACRO_BUFFER, [...]): Delete.
* cpphash.c (CPP_IS_MACRO_BUFFER, FORWARD, PEEKC): Delete.
(macro_cleanup): No need to cast pbuf->macro.
(collect_expansion): Use _cpp_get_define_token. Goto done if
it returns VSPACE. Remove check for trailing space after
CPP_COMMENT.
(_cpp_create_definition): Don't diddle flags here. Return
directly on error.
(unsafe_chars): Handle c1 being EOF.
(push_macro_expansion): Use unsafe_chars for both accidental-paste
checks. Don't push the buffer till after we're done with
them.
* cpplex.c (PEEKBUF, GETBUF, FORWARDBUF): New.
(PEEKN, FORWARD, GETC, PEEKC): Use them.
(cpp_push_buffer): Don't set new->alimit. Set new->mark
appropriately.
(_cpp_parse_assertion): Don't NUL terminate.
(_cpp_lex_token): Fix -traditional macro handling. Don't skip
hspace before calling _cpp_parse_assertion. Remove all sets
of only_seen_white. Treat '\f' as hspace. Don't do anything
special with '\n' here.
(maybe_macroexpand): Handle T_EMPTY hash entries without
pushing a buffer at all.
(cpp_get_token): Handle clearing only_seen_white here. Handle
incrementing the line number here. Clear
potential_control_macro as well as only_seen_white, if
appropriate.
(cpp_get_non_space_token): Don't eat CPP_POP tokens.
(_cpp_get_define_token): New function, basically like
_cpp_get_directive_token was but doesn't eat horizontal space.
Don't do anything with only_seen_white here.
(_cpp_get_directive_token): Just call _cpp_get_define_token
repeatedly till it returns non-hspace.
* cpplib.c (PEEKN, FORWARD, GETC, PEEKC): Delete.
(conditional_skip, skip_if_group): Return int.
(DIRECTIVE_TABLE): Change origin of all conditional directives
to "COND".
(TRAD_DIRECT_P): New macro.
(_cpp_handle_directive): Use _cpp_get_directive_token. Issue
an error for a bogus directive, unless -lang-asm. Use
TRAD_DIRECT_P. Loop calling handler functions till one returns
zero.
(get_macro_name): Don't diddle flags here.
(do_define): Diddle flags here. Use _cpp_get_directive_token.
Create T_EMPTY nodes for #define macro /* nothing */.
(do_undef): Don't copy the name. Use _cpp_get_directive_token.
Use hp->name when calling pass_thru_directive.
(do_if, do_else, do_elif, do_ifdef, do_ifndef, conditional_skip):
Return the result of conditional_skip and/or skip_if_group.
Don't call _cpp_output_line_command.
(consider_directive_while_skipping): Use _cpp_get_directive_token.
Issue -Wtraditional warnings as appropriate. Don't complain
about unrecognized directives. If we are to stop skipping,
return the number of the directive that ended the skip.
(skip_if_group): Use _cpp_get_directive_token. Turn off macro
expansion and line commands while skipping. Return the result
of consider_directive_while_skipping, if nonzero.
(do_endif): Just set potential_control_macro here.
(validate_else): Use _cpp_get_directive_token.
(do_assert, do_unassert): Don't save pointers into the
token_buffer across calls to the lexer. Use
_cpp_get_directive_token.
* cpplib.h (cpp_buffer): Remove alimit and colno. Make mark a
pointer, not an offset. Replace 'data', which was a generic
pointer, with 'macro', which points to a struct hashnode.
(cpp_reader): Add 'potential_control_macro' pointer.
* cpphash.h (T_UNUSED): Replace with T_EMPTY.
(CPP_BUF_GET, CPP_FORWARD): Delete.
(CPP_IN_COLUMN_1, ADJACENT_TO_MARK): New macros.
(CPP_IS_MACRO_BUFFER, CPP_SET_BUF_MARK, CPP_GOTO_BUF_MARK,
ACTIVE_MARK_P): Update.
(_cpp_get_define_token): New internal function.
* cppfiles.c (read_include_file): Don't set fp->alimit or fp->colno.
From-SVN: r32965
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r-- | gcc/cpplex.c | 181 |
1 files changed, 121 insertions, 60 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 56f061b..2e79120 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -25,11 +25,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cpplib.h" #include "cpphash.h" -#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \ - ? CPP_BUFFER (pfile)->cur[N] : EOF) -#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) -#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile)) -#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) +#define PEEKBUF(BUFFER, N) \ + ((BUFFER)->rlimit - (BUFFER)->cur > (N) ? (BUFFER)->cur[N] : EOF) +#define GETBUF(BUFFER) \ + ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF) +#define FORWARDBUF(BUFFER, N) ((BUFFER)->cur += (N)) + +#define PEEKN(N) PEEKBUF (CPP_BUFFER (pfile), N) +#define FORWARD(N) FORWARDBUF (CPP_BUFFER (pfile), (N)) +#define GETC() GETBUF (CPP_BUFFER (pfile)) +#define PEEKC() PEEKBUF (CPP_BUFFER (pfile), 0) static void skip_block_comment PARAMS ((cpp_reader *)); static void skip_line_comment PARAMS ((cpp_reader *)); @@ -87,9 +92,9 @@ cpp_push_buffer (pfile, buffer, length) new->if_stack = pfile->if_stack; new->cleanup = null_cleanup; new->buf = new->cur = buffer; - new->alimit = new->rlimit = buffer + length; + new->rlimit = buffer + length; new->prev = buf; - new->mark = -1; + new->mark = NULL; new->line_base = NULL; CPP_BUFFER (pfile) = new; @@ -667,7 +672,6 @@ _cpp_parse_assertion (pfile) else CPP_PUTC (pfile, ')'); - CPP_NUL_TERMINATE (pfile); return 2; } @@ -702,8 +706,16 @@ _cpp_lex_token (pfile) /* Comments are equivalent to spaces. For -traditional, a comment is equivalent to nothing. */ - if (CPP_TRADITIONAL (pfile) || !CPP_OPTION (pfile, discard_comments)) + if (!CPP_OPTION (pfile, discard_comments)) return CPP_COMMENT; + else if (CPP_TRADITIONAL (pfile) + && ! is_space (PEEKC ())) + { + if (pfile->parsing_define_directive) + return CPP_COMMENT; + else + goto get_next; + } else { CPP_PUTC (pfile, c); @@ -713,7 +725,6 @@ _cpp_lex_token (pfile) case '#': if (pfile->parsing_if_directive) { - _cpp_skip_hspace (pfile); if (_cpp_parse_assertion (pfile)) return CPP_ASSERTION; goto randomchar; @@ -740,7 +751,6 @@ _cpp_lex_token (pfile) case '\"': case '\'': parse_string (pfile, c); - pfile->only_seen_white = 0; return c == '\'' ? CPP_CHAR : CPP_STRING; case '$': @@ -787,7 +797,6 @@ _cpp_lex_token (pfile) { /* In C++, there's a ->* operator. */ token = CPP_OTHER; - pfile->only_seen_white = 0; CPP_RESERVE (pfile, 4); CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, GETC ()); @@ -851,7 +860,6 @@ _cpp_lex_token (pfile) if (c3 == '=') CPP_PUTC_Q (pfile, GETC ()); CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; return CPP_OTHER; case '.': @@ -876,14 +884,12 @@ _cpp_lex_token (pfile) CPP_PUTC_Q (pfile, '.'); FORWARD (2); CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; return CPP_3DOTS; } goto randomchar; op2: token = CPP_OTHER; - pfile->only_seen_white = 0; CPP_RESERVE(pfile, 3); CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, GETC ()); @@ -897,7 +903,6 @@ _cpp_lex_token (pfile) CPP_PUTC (pfile, c); c = GETC (); parse_string (pfile, c); - pfile->only_seen_white = 0; return c == '\'' ? CPP_WCHAR : CPP_WSTRING; } goto letter; @@ -923,13 +928,11 @@ _cpp_lex_token (pfile) c2= c; } CPP_NUL_TERMINATE_Q (pfile); - pfile->only_seen_white = 0; return CPP_NUMBER; case 'b': case 'c': case 'd': case 'h': case 'o': case 'B': case 'C': case 'D': case 'H': case 'O': if (CPP_OPTION (pfile, chill) && PEEKC () == '\'') { - pfile->only_seen_white = 0; CPP_RESERVE (pfile, 2); CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, '\''); @@ -970,11 +973,10 @@ _cpp_lex_token (pfile) case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': letter: - pfile->only_seen_white = 0; _cpp_parse_name (pfile, c); return CPP_MACRO; - case ' ': case '\t': case '\v': + case ' ': case '\t': case '\v': case '\f': for (;;) { CPP_PUTC (pfile, c); @@ -998,6 +1000,8 @@ _cpp_lex_token (pfile) } else if (c == ' ') { + /* "\r " means a space, but only if necessary to prevent + accidental token concatenation. */ CPP_RESERVE (pfile, 2); if (pfile->output_escapes) CPP_PUTC_Q (pfile, '\r'); @@ -1019,15 +1023,6 @@ _cpp_lex_token (pfile) case '\n': CPP_PUTC (pfile, c); - if (pfile->only_seen_white == 0) - pfile->only_seen_white = 1; - CPP_BUMP_LINE (pfile); - if (! CPP_OPTION (pfile, no_line_commands)) - { - pfile->lineno++; - if (CPP_BUFFER (pfile)->lineno != pfile->lineno) - _cpp_output_line_command (pfile, same_file); - } return CPP_VSPACE; case '(': token = CPP_LPAREN; goto char1; @@ -1041,7 +1036,6 @@ _cpp_lex_token (pfile) default: token = CPP_OTHER; char1: - pfile->only_seen_white = 0; CPP_PUTC (pfile, c); return token; } @@ -1075,6 +1069,13 @@ maybe_macroexpand (pfile, written) } return 0; } + if (hp->type == T_EMPTY) + { + /* Special case optimization: macro expands to nothing. */ + CPP_SET_WRITTEN (pfile, written); + CPP_PUTC_Q (pfile, ' '); + return 1; + } /* If macro wants an arglist, verify that a '(' follows. */ if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) @@ -1146,9 +1147,28 @@ cpp_get_token (pfile) switch (token) { default: + pfile->potential_control_macro = 0; + pfile->only_seen_white = 0; + return token; + + case CPP_VSPACE: + if (pfile->only_seen_white == 0) + pfile->only_seen_white = 1; + CPP_BUMP_LINE (pfile); + if (! CPP_OPTION (pfile, no_line_commands)) + { + pfile->lineno++; + if (CPP_BUFFER (pfile)->lineno != pfile->lineno) + _cpp_output_line_command (pfile, same_file); + } + return token; + + case CPP_HSPACE: + case CPP_COMMENT: return token; case CPP_DIRECTIVE: + pfile->potential_control_macro = 0; if (_cpp_handle_directive (pfile)) return CPP_DIRECTIVE; pfile->only_seen_white = 0; @@ -1156,6 +1176,8 @@ cpp_get_token (pfile) return CPP_OTHER; case CPP_MACRO: + pfile->potential_control_macro = 0; + pfile->only_seen_white = 0; if (! pfile->no_macro_expand && maybe_macroexpand (pfile, written)) goto get_next; @@ -1192,57 +1214,96 @@ cpp_get_non_space_token (pfile) for (;;) { enum cpp_token token = cpp_get_token (pfile); - if (token != CPP_COMMENT && token != CPP_POP - && token != CPP_HSPACE && token != CPP_VSPACE) + if (token != CPP_COMMENT && token != CPP_HSPACE && token != CPP_VSPACE) return token; CPP_SET_WRITTEN (pfile, old_written); } } -/* Like cpp_get_token, except that it does not read past end-of-line. - Also, horizontal space is skipped, and macros are popped. */ +/* Like cpp_get_token, except that it does not execute directives, + does not consume vertical space, and 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_token -_cpp_get_directive_token (pfile) +_cpp_get_define_token (pfile) cpp_reader *pfile; { - long old_written = CPP_WRITTEN (pfile); + long old_written; enum cpp_token token; - for (;;) + get_next: + old_written = CPP_WRITTEN (pfile); + token = _cpp_lex_token (pfile); + switch (token) { - _cpp_skip_hspace (pfile); - if (PEEKC () == '\n') - return CPP_VSPACE; + default: + return token; - token = cpp_get_token (pfile); - /* token could be hspace at the beginning of a macro. */ - if (token == CPP_HSPACE || token == CPP_COMMENT) - { - CPP_SET_WRITTEN (pfile, old_written); - continue; - } + case CPP_VSPACE: + /* Put it back and return VSPACE. */ + FORWARD(-1); + CPP_ADJUST_WRITTEN (pfile, -1); + return CPP_VSPACE; - /* token cannot be vspace, it would have been caught above. */ - if (token == CPP_VSPACE) + case CPP_HSPACE: + if (CPP_PEDANTIC (pfile)) { - cpp_ice (pfile, "VSPACE in get_directive_token"); - return token; + U_CHAR *p, *limit; + p = pfile->token_buffer + old_written; + limit = CPP_PWRITTEN (pfile); + while (p < limit) + { + if (*p == '\v' || *p == '\f') + cpp_pedwarn (pfile, "%s in preprocessing directive", + *p == '\f' ? "formfeed" : "vertical tab"); + p++; + } } + return CPP_HSPACE; - /* token cannot be POP unless the buffer is a macro buffer. */ - if (token != CPP_POP) - return token; + case CPP_DIRECTIVE: + /* Don't execute the directive, but don't smash it to OTHER either. */ + CPP_PUTC (pfile, '#'); + return CPP_DIRECTIVE; + + case CPP_MACRO: + if (! pfile->no_macro_expand + && maybe_macroexpand (pfile, old_written)) + goto get_next; + return CPP_NAME; - if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) + case CPP_EOF: + if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) { - cpp_ice (pfile, "POP of file buffer in get_directive_token"); - return token; + cpp_pop_buffer (pfile); + goto get_next; } + else + /* This can happen for files that don't end with a newline, + and for cpp_define and friends. Pretend they do, so + callers don't have to deal. A warning will be issued by + someone else, if necessary. */ + return CPP_VSPACE; + } +} + +/* Just like _cpp_get_define_token except that it discards horizontal + whitespace. */ - /* We must pop the buffer by hand, or else cpp_get_token might - hand us white space or newline on the next invocation. */ - cpp_pop_buffer (pfile); +enum cpp_token +_cpp_get_directive_token (pfile) + cpp_reader *pfile; +{ + int old_written = CPP_WRITTEN (pfile); + for (;;) + { + enum cpp_token token = _cpp_get_define_token (pfile); + if (token != CPP_COMMENT && token != CPP_HSPACE) + return token; + CPP_SET_WRITTEN (pfile, old_written); } } |