aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r--gcc/cpplex.c181
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);
}
}