aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplib.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cpplib.c')
-rw-r--r--gcc/cpplib.c340
1 files changed, 157 insertions, 183 deletions
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 9f96297..8cdc241 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -46,7 +46,8 @@ extern HOST_WIDEST_INT cpp_parse_expr PARAMS ((cpp_reader *));
/* `struct directive' defines one #-directive, including how to handle it. */
-struct directive {
+struct directive
+{
int length; /* Length of name */
int (*func) /* Function to handle directive */
PARAMS ((cpp_reader *, const struct directive *));
@@ -93,7 +94,7 @@ static enum cpp_token null_underflow PARAMS ((cpp_reader *));
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_string PARAMS ((cpp_reader *, int));
static void skip_rest_of_line PARAMS ((cpp_reader *));
static void cpp_skip_hspace PARAMS ((cpp_reader *));
static int handle_directive PARAMS ((cpp_reader *));
@@ -108,6 +109,7 @@ static void skip_block_comment PARAMS ((cpp_reader *));
static void skip_line_comment PARAMS ((cpp_reader *));
static void parse_set_mark PARAMS ((cpp_reader *));
static void parse_goto_mark PARAMS ((cpp_reader *));
+static int get_macro_name PARAMS ((cpp_reader *));
/* Here is the actual list of #-directives.
This table is ordered by frequency of occurrence; the numbers
@@ -410,10 +412,13 @@ copy_comment (pfile, m)
if (skip_comment (pfile, m) == m)
return m;
- CPP_PUTC (pfile, m);
- for (limit = CPP_BUFFER (pfile)->cur; start <= limit; start++)
+ limit = CPP_BUFFER (pfile)->cur;
+ CPP_RESERVE (pfile, limit - start + 2);
+ CPP_PUTC_Q (pfile, m);
+ for (; start <= limit; start++)
if (*start != '\r')
- CPP_PUTC (pfile, *start);
+ CPP_PUTC_Q (pfile, *start);
+
return ' ';
}
@@ -447,7 +452,7 @@ cpp_skip_hspace (pfile)
break;
}
else
- CPP_BUFFER (pfile)->lineno++;
+ CPP_BUMP_LINE (pfile);
}
else if (c == '/' || c == '-')
{
@@ -461,11 +466,10 @@ cpp_skip_hspace (pfile)
FORWARD(-1);
}
-/* Read the rest of the current line.
- The line is appended to PFILE's output buffer. */
+/* Read and discard the rest of the current line. */
static void
-copy_rest_of_line (pfile)
+skip_rest_of_line (pfile)
cpp_reader *pfile;
{
for (;;)
@@ -476,32 +480,21 @@ copy_rest_of_line (pfile)
case '\n':
FORWARD(-1);
case EOF:
- CPP_NUL_TERMINATE (pfile);
return;
case '\r':
- if (CPP_BUFFER (pfile)->has_escapes)
- break;
- else
- {
- CPP_BUFFER (pfile)->lineno++;
- continue;
- }
+ if (! CPP_BUFFER (pfile)->has_escapes)
+ CPP_BUMP_LINE (pfile);
+ break;
+
case '\'':
case '\"':
- parse_string (pfile, c);
- continue;
+ skip_string (pfile, c);
+ break;
+
case '/':
- if (PEEKC() == '*')
- {
- if (CPP_TRADITIONAL (pfile))
- CPP_PUTS (pfile, "/**/", 4);
- skip_block_comment (pfile);
- continue;
- }
- /* else fall through */
case '-':
- c = skip_comment (pfile, c);
+ skip_comment (pfile, c);
break;
case '\f':
@@ -512,23 +505,9 @@ copy_rest_of_line (pfile)
break;
}
- CPP_PUTC (pfile, c);
}
}
-/* FIXME: It is almost definitely a performance win to make this do
- 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. */
-static void
-skip_rest_of_line (pfile)
- cpp_reader *pfile;
-{
- long old = CPP_WRITTEN (pfile);
- copy_rest_of_line (pfile);
- CPP_SET_WRITTEN (pfile, old);
-}
-
/* Handle a possible # directive.
'#' has already been read. */
@@ -542,6 +521,12 @@ handle_directive (pfile)
U_CHAR *ident;
long old_written = CPP_WRITTEN (pfile);
+ if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ {
+ cpp_ice (pfile, "handle_directive called on macro buffer");
+ return 0;
+ }
+
cpp_skip_hspace (pfile);
c = PEEKC ();
@@ -629,71 +614,88 @@ pass_thru_directive (buf, len, pfile, keyword)
CPP_PUTS_Q (pfile, buf, len);
}
-/* Check a purported macro name SYMNAME, and yield its length. */
+/* Subroutine of do_define: determine the name of the macro to be
+ defined. */
-int
-check_macro_name (pfile, symname)
+static int
+get_macro_name (pfile)
cpp_reader *pfile;
- const U_CHAR *symname;
{
- const U_CHAR *p;
- int sym_length;
-
- for (p = symname; is_idchar(*p); p++)
- ;
- sym_length = p - symname;
- if (sym_length == 0
- || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- cpp_error (pfile, "invalid macro name");
- else if (!is_idstart(*symname)
- || (! strncmp (symname, "defined", 7) && sym_length == 7)) {
- U_CHAR *msg; /* what pain... */
- msg = (U_CHAR *) alloca (sym_length + 1);
- bcopy (symname, msg, sym_length);
- msg[sym_length] = 0;
- cpp_error (pfile, "invalid macro name `%s'", msg);
- }
- return sym_length;
+ long here, len;
+
+ here = CPP_WRITTEN (pfile);
+ pfile->no_macro_expand++;
+ if (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;
+ }
+
+ pfile->no_macro_expand--;
+ return len;
+
+ invalid:
+ skip_rest_of_line (pfile);
+ pfile->no_macro_expand--;
+ return 0;
}
/* Process a #define command.
KEYWORD is the keyword-table entry for #define,
- or NULL for a "predefined" macro,
- or the keyword-table entry for #pragma in the case of a #pragma poison. */
+ or NULL for a "predefined" macro. */
static int
do_define (pfile, keyword)
cpp_reader *pfile;
const struct directive *keyword;
{
- MACRODEF mdef;
HASHNODE *hp;
+ DEFINITION *def;
long here;
- U_CHAR *macro, *buf, *end;
+ int len, c;
+ int funlike = 0;
+ U_CHAR *sym;
here = CPP_WRITTEN (pfile);
- copy_rest_of_line (pfile);
-
- /* Copy out the line so we can pop the token buffer. */
- buf = pfile->token_buffer + here;
- end = CPP_PWRITTEN (pfile);
- macro = (U_CHAR *) alloca (end - buf + 1);
- memcpy (macro, buf, end - buf + 1);
- end = macro + (end - buf);
+ len = get_macro_name (pfile);
+ if (len == 0)
+ return 0;
+ /* Copy out the name so we can pop the token buffer. */
+ len = CPP_WRITTEN (pfile) - here;
+ sym = (U_CHAR *) alloca (len + 1);
+ memcpy (sym, pfile->token_buffer + here, len);
+ sym[len] = '\0';
CPP_SET_WRITTEN (pfile, here);
- mdef = create_definition (macro, end, pfile);
- if (mdef.defn == 0)
+ /* If the next character, with no intervening whitespace, is '(',
+ then this is a function-like macro. */
+ c = PEEKC ();
+ if (c == '(')
+ funlike = 1;
+ else if (c != '\n' && !is_hspace (c))
+ /* Otherwise, C99 requires white space after the name. We treat it
+ as an object-like macro if this happens, with a warning. */
+ cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym);
+
+ def = create_definition (pfile, funlike);
+ if (def == 0)
return 0;
- if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL)
+ if ((hp = cpp_lookup (pfile, sym, len)) != NULL)
{
int ok;
/* Redefining a macro is ok if the definitions are the same. */
if (hp->type == T_MACRO)
- ok = ! compare_defs (pfile, mdef.defn, hp->value.defn);
+ ok = ! compare_defs (pfile, def, hp->value.defn);
/* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST || hp->type == T_STDC)
ok = ! CPP_OPTIONS (pfile)->done_initializing;
@@ -704,14 +706,15 @@ do_define (pfile, keyword)
if (! ok)
{
if (hp->type == T_POISON)
- cpp_error (pfile, "redefining poisoned `%.*s'",
- mdef.symlen, mdef.symnam);
+ cpp_error (pfile, "redefining poisoned `%.*s'", len, sym);
else
- cpp_pedwarn (pfile, "`%.*s' redefined", mdef.symlen, mdef.symnam);
+ cpp_pedwarn (pfile, "`%.*s' redefined", len, sym);
if (hp->type == T_MACRO && CPP_OPTIONS (pfile)->done_initializing)
- cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file,
- hp->value.defn->line, -1,
+ {
+ DEFINITION *d = hp->value.defn;
+ cpp_pedwarn_with_file_and_line (pfile, d->file, d->line, d->col,
"this is the location of the previous definition");
+ }
}
if (hp->type != T_POISON)
{
@@ -719,19 +722,19 @@ do_define (pfile, keyword)
if (hp->type == T_MACRO)
free_definition (hp->value.defn);
hp->type = T_MACRO;
- hp->value.defn = mdef.defn;
+ hp->value.defn = def;
}
}
else
- cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO, (char *)mdef.defn);
+ cpp_install (pfile, sym, len, T_MACRO, (char *) def);
if (keyword != NULL && keyword->type == T_DEFINE)
{
if (CPP_OPTIONS (pfile)->debug_output
|| CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
- dump_definition (pfile, mdef.symnam, mdef.symlen, mdef.defn);
+ dump_definition (pfile, sym, len, def);
else if (CPP_OPTIONS (pfile)->dump_macros == dump_names)
- pass_thru_directive (mdef.symnam, mdef.symlen, pfile, keyword);
+ pass_thru_directive (sym, len, pfile, keyword);
}
return 0;
@@ -766,6 +769,7 @@ cpp_push_buffer (pfile, buffer, length)
new->alimit = new->rlimit = buffer + length;
new->prev = buf;
new->mark = -1;
+ new->line_base = NULL;
CPP_BUFFER (pfile) = new;
return new;
@@ -1309,7 +1313,7 @@ read_line_number (pfile, num)
}
else
{
- if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
+ if (token != CPP_VSPACE && token != CPP_EOF)
cpp_error (pfile, "invalid format `#line' command");
return 0;
}
@@ -1467,15 +1471,14 @@ do_undef (pfile, keyword)
len = limit - buf;
name = (U_CHAR *) alloca (len + 1);
memcpy (name, buf, len);
- name[limit - buf] = '\0';
+ name[len] = '\0';
token = get_directive_token (pfile);
- if (token != CPP_VSPACE && token != CPP_POP)
+ if (token != CPP_VSPACE)
{
cpp_pedwarn (pfile, "junk on line after #undef");
skip_rest_of_line (pfile);
}
-
CPP_SET_WRITTEN (pfile, here);
while ((hp = cpp_lookup (pfile, name, len)) != NULL)
@@ -1950,11 +1953,9 @@ 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;
-
+ pfile->parsing_if_directive++;
value = cpp_parse_expr (pfile);
+ pfile->parsing_if_directive--;
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, old_written); /* Pop */
@@ -2148,13 +2149,6 @@ skip_if_group (pfile)
U_CHAR *beg_of_line;
long old_written;
- if (CPP_OPTIONS (pfile)->output_conditionals)
- {
- CPP_PUTS (pfile, "#failed\n", 8);
- pfile->lineno++;
- output_line_command (pfile, same_file);
- }
-
old_written = CPP_WRITTEN (pfile);
for (;;)
@@ -2166,8 +2160,6 @@ skip_if_group (pfile)
c = GETC();
if (c == '\n')
{
- if (CPP_OPTIONS (pfile)->output_conditionals)
- CPP_PUTC (pfile, c);
CPP_BUMP_LINE (pfile);
continue;
}
@@ -2180,41 +2172,19 @@ skip_if_group (pfile)
return; /* Caller will issue error. */
FORWARD(-1);
- if (CPP_OPTIONS (pfile)->output_conditionals)
- {
- CPP_PUTS (pfile, beg_of_line, CPP_BUFFER (pfile)->cur - beg_of_line);
- copy_rest_of_line (pfile);
- }
- else
- {
- copy_rest_of_line (pfile);
- CPP_SET_WRITTEN (pfile, old_written); /* discard it */
- }
+ skip_rest_of_line (pfile);
c = GETC();
if (c == EOF)
return; /* Caller will issue error. */
else
- {
- /* \n */
- if (CPP_OPTIONS (pfile)->output_conditionals)
- {
- CPP_PUTC (pfile, c);
- pfile->lineno++;
- }
- CPP_BUMP_LINE (pfile);
- }
+ CPP_BUMP_LINE (pfile);
}
/* Back up to the beginning of this line. Caller will process the
directive. */
CPP_BUFFER (pfile)->cur = beg_of_line;
pfile->only_seen_white = 1;
- if (CPP_OPTIONS (pfile)->output_conditionals)
- {
- CPP_PUTS (pfile, "#endfailed\n", 11);
- pfile->lineno++;
- }
}
/*
@@ -2443,6 +2413,27 @@ cpp_get_token (pfile)
}
case '#':
+ if (pfile->parsing_if_directive)
+ {
+ cpp_skip_hspace (pfile);
+ parse_assertion (pfile);
+ return CPP_ASSERTION;
+ }
+
+ if (pfile->parsing_define_directive && ! CPP_TRADITIONAL (pfile))
+ {
+ CPP_RESERVE (pfile, 3);
+ CPP_PUTC_Q (pfile, '#');
+ CPP_NUL_TERMINATE_Q (pfile);
+ if (PEEKC () != '#')
+ return CPP_STRINGIZE;
+
+ FORWARD (1);
+ CPP_PUTC_Q (pfile, '#');
+ CPP_NUL_TERMINATE_Q (pfile);
+ return CPP_TOKPASTE;
+ }
+
if (!pfile->only_seen_white)
goto randomchar;
/* -traditional directives are recognized only with the # in
@@ -2886,35 +2877,24 @@ parse_name (pfile, c)
return;
}
-/* Parse a string starting with C. A single quoted string is treated
- like a double -- some programs (e.g., troff) are perverse this way.
- (However, a single quoted string is not allowed to extend over
- multiple lines.) */
+/* Parse and skip over a string starting with C. A single quoted
+ string is treated like a double -- some programs (e.g., troff) are
+ perverse this way. (However, a single quoted string is not allowed
+ to extend over multiple lines.) */
static void
-parse_string (pfile, c)
+skip_string (pfile, c)
cpp_reader *pfile;
int c;
{
long start_line, start_column;
-
cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
- CPP_PUTC (pfile, c);
while (1)
{
int cc = GETC();
- if (cc == EOF)
+ switch (cc)
{
- if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
- {
- /* try harder: this string crosses a macro expansion
- boundary. This can happen naturally if -traditional.
- Otherwise, only -D can make a macro with an unmatched
- quote. */
- cpp_pop_buffer (pfile);
- continue;
- }
-
+ case EOF:
cpp_error_with_line (pfile, start_line, start_column,
"unterminated string or character constant");
if (pfile->multiline_string_line != start_line
@@ -2923,22 +2903,20 @@ parse_string (pfile, c)
pfile->multiline_string_line, -1,
"possible real start of unterminated constant");
pfile->multiline_string_line = 0;
- break;
- }
- CPP_PUTC (pfile, cc);
- switch (cc)
- {
+ return;
+
case '\n':
CPP_BUMP_LINE (pfile);
- pfile->lineno++;
-
/* In Fortran and assembly language, silently terminate
strings of either variety at end of line. This is a
kludge around not knowing where comments are in these
languages. */
if (CPP_OPTIONS (pfile)->lang_fortran
|| CPP_OPTIONS (pfile)->lang_asm)
- return;
+ {
+ FORWARD(-1);
+ return;
+ }
/* Character constants may not extend over multiple lines.
In Standard C, neither may strings. We accept multiline
strings as an extension. */
@@ -2946,6 +2924,7 @@ parse_string (pfile, c)
{
cpp_error_with_line (pfile, start_line, start_column,
"unterminated character constant");
+ FORWARD(-1);
return;
}
if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0)
@@ -2956,7 +2935,6 @@ parse_string (pfile, c)
break;
case '\r':
- CPP_ADJUST_WRITTEN (pfile, -1);
if (CPP_BUFFER (pfile)->has_escapes)
{
cpp_ice (pfile, "\\r escape inside string constant");
@@ -2968,9 +2946,7 @@ parse_string (pfile, c)
break;
case '\\':
- cc = GETC();
- if (cc != EOF)
- CPP_PUTC (pfile, cc);
+ FORWARD(1);
break;
case '\"':
@@ -2982,6 +2958,26 @@ parse_string (pfile, c)
}
}
+/* Parse a string and copy it to the output. */
+
+static void
+parse_string (pfile, c)
+ cpp_reader *pfile;
+ int c;
+{
+ U_CHAR *start = CPP_BUFFER (pfile)->cur; /* XXX Layering violation */
+ U_CHAR *limit;
+
+ skip_string (pfile, c);
+
+ limit = CPP_BUFFER (pfile)->cur;
+ CPP_RESERVE (pfile, limit - start + 2);
+ CPP_PUTC_Q (pfile, c);
+ for (; start < limit; start++)
+ if (*start != '\r')
+ CPP_PUTC_Q (pfile, *start);
+}
+
/* Read an assertion into the token buffer, converting to
canonical form: `#predicate(a n swe r)' The next non-whitespace
character to read should be the first letter of the predicate.
@@ -3199,33 +3195,11 @@ cpp_unassert (pfile, str)
{
if (cpp_push_buffer (pfile, str, strlen (str)) != NULL)
{
- do_assert (pfile, NULL);
+ do_unassert (pfile, NULL);
cpp_pop_buffer (pfile);
}
}
-int
-cpp_read_check_assertion (pfile)
- cpp_reader *pfile;
-{
- U_CHAR *name;
- int result;
- long written = CPP_WRITTEN (pfile);
-
- FORWARD (1); /* Skip '#' */
- cpp_skip_hspace (pfile);
- if (! parse_assertion (pfile))
- result = 0;
- else
- {
- name = pfile->token_buffer + written;
- result = cpp_defined (pfile, name, CPP_PWRITTEN (pfile) - name);
- }
-
- CPP_SET_WRITTEN (pfile, written);
- return result;
-}
-
/* Remember the current position of PFILE so it may be returned to
after looking ahead a bit.