aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplib.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2000-08-02 01:13:45 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-08-02 01:13:45 +0000
commit58fea6afd912f7c309c156522391b20462372ceb (patch)
treeaf945d1943c9c6b458fec03b961f8f0d523896bf /gcc/cpplib.c
parent8cd8f856b33bbd6c6627eb0a18e34b046e2163f1 (diff)
downloadgcc-58fea6afd912f7c309c156522391b20462372ceb.zip
gcc-58fea6afd912f7c309c156522391b20462372ceb.tar.gz
gcc-58fea6afd912f7c309c156522391b20462372ceb.tar.bz2
cpperror.c (v_message): Split into _cpp_begin_message and v_message macro.
* cpperror.c (v_message): Split into _cpp_begin_message and v_message macro. All callers updated. (_cpp_begin_message): Do inhibit_errors/inhibit_warnings checks here. * cppfiles.c (cpp_syshdr_flags): New function. (read_include_file): Don't call cpp_output_tokens. Call enter_file hook. * cppinit.c (dump_macros_helper): Moved to cppmain.c. (cpp_reader_init): Don't initialize token_buffer. Call _cpp_init_internal_pragmas. (cpp_cleanup): Don't clear token_buffer. (cpp_start_read): Don't worry about output from -D processing. Don't call cpp_output_tokens. (cpp_finish): Don't dump macros here. Don't call cpp_output_tokens. * cppmacro.c (_cpp_dump_definition): Rename cpp_dump_definition. Write directly to a FILE *. (dump_funlike_macro): Delete. (dump_macro_args): New. * cpplex.c (TOKEN_LEN): Convert to inline function. (_cpp_grow_token_buffer, safe_fwrite, cpp_output_tokens, cpp_scan_line, _cpp_dump_list): Delete. (cpp_printf, cpp_output_list): New. (output_line_command): Don't worry about entering or leaving files. (cpp_scan_buffer): Just output each token as we hit it. (process_directive): Don't call cpp_output_tokens. (_cpp_glue_header_name): Don't use token_buffer. (output_token, dump_param_spelling): Write directly to a FILE *. * cpplib.c (pass_thru_directive, dump_macro_name, pragma_dispatch, do_pragma_gcc): Delete. (do_define, do_undef, parse_include, do_line, do_ident, do_pragma, do_pragma_poison, cpp_pop_buffer): Call the appropriate hook functions. (do_error, do_warning, pragma_dependency): Call _cpp_begin_message, then cpp_output_list. (cpp_register_pragma, cpp_register_pragma_space, _cpp_init_internal_pragmas): New. (do_pragma): Walk the pragmas table here. (do_pragma_once, do_pragma_poison, do_pragma_system_header, do_pragma_dependency): Return void. (do_pragma_implementation): Moved to cppmain.c. * cpplib.h: Update prototypes. (struct cpp_reader): Remove printer, token_buffer, token_buffer_size, and limit. Add struct cb, and pragmas. (struct cpp_printer): Remove last_id and written. (CPP_WRITTEN, CPP_PWRITTEN, CPP_SET_WRITTEN, CPP_ADJUST_WRITTEN): Delete. * cpphash.h: Update prototypes. (ufputs): New wrapper. * cppmain.c (cb_define, cb_undef, cb_include, cb_ident, cb_enter_file, cb_leave_file, cb_def_pragma): New functions. (main): Set up callbacks. Register #pragma implementation. Dump macros from here. From-SVN: r35415
Diffstat (limited to 'gcc/cpplib.c')
-rw-r--r--gcc/cpplib.c360
1 files changed, 174 insertions, 186 deletions
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 7d7bbc2..ade5ee3 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -49,7 +49,6 @@ static int parse_include PARAMS ((cpp_reader *, const U_CHAR *, int,
int *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
-static void pass_thru_directive PARAMS ((cpp_reader *));
static int read_line_number PARAMS ((cpp_reader *, int *));
static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
unsigned long *));
@@ -60,7 +59,6 @@ static const cpp_hashnode *
detect_if_not_defined PARAMS ((cpp_reader *));
static cpp_hashnode *
get_define_node PARAMS ((cpp_reader *));
-static void dump_macro_name PARAMS ((cpp_reader *, cpp_hashnode *));
static void unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
/* Utility. */
@@ -214,29 +212,6 @@ _cpp_check_linemarker (pfile, token, bol)
return &dtable[T_LINE];
}
-static void
-dump_macro_name (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
-{
- CPP_PUTS (pfile, "#define ", sizeof "#define " - 1);
- CPP_PUTS (pfile, node->name, node->length);
-}
-
-/* Pass the current directive through to the output file. */
-static void
-pass_thru_directive (pfile)
- cpp_reader *pfile;
-{
- /* XXX This output may be genuinely needed even when there is no
- printer. */
- if (! pfile->printer)
- return;
- /* Flush first (temporary). */
- cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line);
- _cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 1);
-}
-
static cpp_hashnode *
get_define_node (pfile)
cpp_reader *pfile;
@@ -288,13 +263,8 @@ do_define (pfile)
if ((node = get_define_node (pfile)))
if (_cpp_create_definition (pfile, node))
- {
- if (CPP_OPTION (pfile, debug_output)
- || CPP_OPTION (pfile, dump_macros) == dump_definitions)
- _cpp_dump_definition (pfile, node);
- else if (CPP_OPTION (pfile, dump_macros) == dump_names)
- dump_macro_name (pfile, node);
- }
+ if (pfile->cb.define)
+ (*pfile->cb.define) (pfile, node);
}
/* Remove the definition of a symbol from the symbol table. */
@@ -311,12 +281,8 @@ do_undef (pfile)
is not currently defined as a macro name. */
if (node && node->type != T_VOID)
{
- /* If we are generating additional info for debugging (with -g) we
- need to pass through all effective #undef commands. */
- if (CPP_OPTION (pfile, debug_output)
- || CPP_OPTION (pfile, dump_macros) == dump_definitions
- || CPP_OPTION (pfile, dump_macros) == dump_names)
- pass_thru_directive (pfile);
+ if (pfile->cb.undef)
+ (*pfile->cb.undef) (pfile, node);
if (node->type != T_MACRO)
cpp_warning (pfile, "undefining \"%s\"", node->name);
@@ -362,6 +328,9 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
*lenp = name->val.str.len;
*strp = name->val.str.text;
*abp = (name->type == CPP_HEADER_NAME);
+
+ if (pfile->cb.include)
+ (*pfile->cb.include) (pfile, dir, *strp, *lenp, *abp);
return 0;
}
@@ -377,8 +346,6 @@ do_include (pfile)
return;
_cpp_execute_include (pfile, str, len, 0, 0, ab);
- if (CPP_OPTION (pfile, dump_includes))
- pass_thru_directive (pfile);
}
static void
@@ -401,8 +368,6 @@ do_import (pfile)
return;
_cpp_execute_include (pfile, str, len, 1, 0, ab);
- if (CPP_OPTION (pfile, dump_includes))
- pass_thru_directive (pfile);
}
static void
@@ -436,8 +401,6 @@ do_include_next (pfile)
cpp_warning (pfile, "#include_next in primary source file");
_cpp_execute_include (pfile, str, len, 0, search_start, ab);
- if (CPP_OPTION (pfile, dump_includes))
- pass_thru_directive (pfile);
}
/* Subroutine of do_line. Read next token from PFILE without adding it to
@@ -504,6 +467,7 @@ do_line (pfile)
/* C99 raised the minimum limit on #line numbers. */
unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
int action_number = 0;
+ int enter = 0, leave = 0;
enum cpp_ttype type;
const U_CHAR *str;
char *fname;
@@ -558,18 +522,15 @@ do_line (pfile)
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "garbage at end of #line");
- /* This is somewhat questionable: change the buffer stack
- depth so that output_line_command thinks we've stacked
- another buffer. */
if (action_number == 1)
{
- pfile->buffer_stack_depth++;
+ enter = 1;
cpp_make_system_header (pfile, ip, 0);
read_line_number (pfile, &action_number);
}
else if (action_number == 2)
{
- pfile->buffer_stack_depth--;
+ leave = 1;
cpp_make_system_header (pfile, ip, 0);
read_line_number (pfile, &action_number);
}
@@ -584,6 +545,11 @@ do_line (pfile)
read_line_number (pfile, &action_number);
}
+ if (enter && pfile->cb.enter_file)
+ (*pfile->cb.enter_file) (pfile);
+ if (leave && pfile->cb.leave_file)
+ (*pfile->cb.leave_file) (pfile);
+
done:
return;
}
@@ -598,13 +564,12 @@ static void
do_error (pfile)
cpp_reader *pfile;
{
- U_CHAR *text, *limit;
-
- text = pfile->limit;
- _cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 0);
- limit = pfile->limit;
- pfile->limit = text;
- cpp_error (pfile, "%.*s", (int)(limit - text), text);
+ if (_cpp_begin_message (pfile, ERROR, NULL, 0, 0))
+ {
+ cpp_output_list (pfile, stderr, &pfile->token_list,
+ pfile->first_directive_token);
+ putc ('\n', stderr);
+ }
}
/*
@@ -616,13 +581,12 @@ static void
do_warning (pfile)
cpp_reader *pfile;
{
- U_CHAR *text, *limit;
-
- text = pfile->limit;
- _cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 0);
- limit = pfile->limit;
- pfile->limit = text;
- cpp_warning (pfile, "%.*s", (int)(limit - text), text);
+ if (_cpp_begin_message (pfile, WARNING, NULL, 0, 0))
+ {
+ cpp_output_list (pfile, stderr, &pfile->token_list,
+ pfile->first_directive_token);
+ putc ('\n', stderr);
+ }
}
/* Report program identification. */
@@ -631,15 +595,14 @@ static void
do_ident (pfile)
cpp_reader *pfile;
{
- /* Next token should be a string constant. */
- if (_cpp_get_token (pfile)->type == CPP_STRING)
- /* And then a newline. */
- if (_cpp_get_token (pfile)->type == CPP_EOF)
- {
- /* Good - ship it. */
- pass_thru_directive (pfile);
- return;
- }
+ const cpp_token *str = _cpp_get_token (pfile);
+
+ if (str->type == CPP_STRING && _cpp_get_token (pfile)->type == CPP_EOF)
+ {
+ if (pfile->cb.ident)
+ (*pfile->cb.ident) (pfile, str);
+ return;
+ }
cpp_error (pfile, "invalid #ident");
}
@@ -659,88 +622,154 @@ do_ident (pfile)
They return 1 if the token buffer is to be popped, 0 if not. */
struct pragma_entry
{
+ struct pragma_entry *next;
const char *name;
- int (*handler) PARAMS ((cpp_reader *));
+ size_t len;
+ int isnspace;
+ union {
+ void (*handler) PARAMS ((cpp_reader *));
+ struct pragma_entry *space;
+ } u;
};
-static int pragma_dispatch
- PARAMS ((cpp_reader *, const struct pragma_entry *, const cpp_hashnode *));
-static int do_pragma_once PARAMS ((cpp_reader *));
-static int do_pragma_implementation PARAMS ((cpp_reader *));
-static int do_pragma_poison PARAMS ((cpp_reader *));
-static int do_pragma_system_header PARAMS ((cpp_reader *));
-static int do_pragma_gcc PARAMS ((cpp_reader *));
-static int do_pragma_dependency PARAMS ((cpp_reader *));
-
-static const struct pragma_entry top_pragmas[] =
+void
+cpp_register_pragma (pfile, space, name, handler)
+ cpp_reader *pfile;
+ const char *space;
+ const char *name;
+ void (*handler) PARAMS ((cpp_reader *));
{
- {"once", do_pragma_once},
- {"implementation", do_pragma_implementation},
- {"poison", do_pragma_poison},
- {"GCC", do_pragma_gcc},
- {NULL, NULL}
-};
+ struct pragma_entry **x, *new;
+ size_t len;
-static const struct pragma_entry gcc_pragmas[] =
-{
- {"implementation", do_pragma_implementation},
- {"poison", do_pragma_poison},
- {"system_header", do_pragma_system_header},
- {"dependency", do_pragma_dependency},
- {NULL, NULL}
-};
+ x = &pfile->pragmas;
+ if (space)
+ {
+ struct pragma_entry *p = pfile->pragmas;
+ len = strlen (space);
+ while (p)
+ {
+ if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
+ {
+ x = &p->u.space;
+ goto found;
+ }
+ p = p->next;
+ }
+ cpp_ice (pfile, "unknown #pragma namespace %s", space);
+ return;
+ }
+
+ found:
+ new = xnew (struct pragma_entry);
+ new->name = name;
+ new->len = strlen (name);
+ new->isnspace = 0;
+ new->u.handler = handler;
+
+ new->next = *x;
+ *x = new;
+}
-static int pragma_dispatch (pfile, table, node)
+void
+cpp_register_pragma_space (pfile, space)
cpp_reader *pfile;
- const struct pragma_entry *table;
- const cpp_hashnode *node;
+ const char *space;
{
- const U_CHAR *p = node->name;
- size_t len = node->length;
+ struct pragma_entry *new;
+ const struct pragma_entry *p = pfile->pragmas;
+ size_t len = strlen (space);
+
+ while (p)
+ {
+ if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
+ {
+ cpp_ice (pfile, "#pragma namespace %s already registered", space);
+ return;
+ }
+ p = p->next;
+ }
+
+ new = xnew (struct pragma_entry);
+ new->name = space;
+ new->len = len;
+ new->isnspace = 1;
+ new->u.space = 0;
+
+ new->next = pfile->pragmas;
+ pfile->pragmas = new;
+}
- for (; table->name; table++)
- if (strlen (table->name) == len && !memcmp (p, table->name, len))
- return (*table->handler) (pfile);
- return 0;
+static void do_pragma_once PARAMS ((cpp_reader *));
+static void do_pragma_poison PARAMS ((cpp_reader *));
+static void do_pragma_system_header PARAMS ((cpp_reader *));
+static void do_pragma_dependency PARAMS ((cpp_reader *));
+
+void
+_cpp_init_internal_pragmas (pfile)
+ cpp_reader *pfile;
+{
+ /* top level */
+ cpp_register_pragma (pfile, 0, "poison", do_pragma_poison);
+ cpp_register_pragma (pfile, 0, "once", do_pragma_once);
+
+ /* GCC namespace */
+ cpp_register_pragma_space (pfile, "GCC");
+
+ cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
+ cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
+ cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
}
static void
do_pragma (pfile)
cpp_reader *pfile;
{
+ const struct pragma_entry *p;
const cpp_token *tok;
- int pop;
+ const cpp_hashnode *node;
+ const U_CHAR *name;
+ size_t len;
+ p = pfile->pragmas;
+
+ new_space:
tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF)
return;
- else if (tok->type != CPP_NAME)
+
+ if (tok->type != CPP_NAME)
{
cpp_error (pfile, "malformed #pragma directive");
return;
}
- pop = pragma_dispatch (pfile, top_pragmas, tok->val.node);
- if (!pop)
- pass_thru_directive (pfile);
-}
-
-static int
-do_pragma_gcc (pfile)
- cpp_reader *pfile;
-{
- const cpp_token *tok;
+ node = tok->val.node;
+ name = node->name;
+ len = node->length;
+ while (p)
+ {
+ if (strlen (p->name) == len && !memcmp (p->name, name, len))
+ {
+ if (p->isnspace)
+ {
+ p = p->u.space;
+ goto new_space;
+ }
+ else
+ {
+ (*p->u.handler) (pfile);
+ return;
+ }
+ }
+ p = p->next;
+ }
- tok = _cpp_get_token (pfile);
- if (tok->type == CPP_EOF)
- return 1;
- else if (tok->type != CPP_NAME)
- return 0;
-
- return pragma_dispatch (pfile, gcc_pragmas, tok->val.node);
+ if (pfile->cb.def_pragma)
+ (*pfile->cb.def_pragma) (pfile);
}
-static int
+static void
do_pragma_once (pfile)
cpp_reader *pfile;
{
@@ -755,41 +784,9 @@ do_pragma_once (pfile)
cpp_warning (pfile, "#pragma once outside include file");
else
ip->inc->cmacro = NEVER_REREAD;
-
- return 1;
}
-static int
-do_pragma_implementation (pfile)
- cpp_reader *pfile;
-{
- /* Be quiet about `#pragma implementation' for a file only if it hasn't
- been included yet. */
- const cpp_token *tok = _cpp_get_token (pfile);
- char *copy;
-
- if (tok->type == CPP_EOF)
- return 0;
- else if (tok->type != CPP_STRING
- || _cpp_get_token (pfile)->type != CPP_EOF)
- {
- cpp_error (pfile, "malformed #pragma implementation");
- return 1;
- }
-
- /* Make a NUL-terminated copy of the string. */
- copy = alloca (tok->val.str.len + 1);
- memcpy (copy, tok->val.str.text, tok->val.str.len);
- copy[tok->val.str.len] = '\0';
-
- if (cpp_included (pfile, copy))
- cpp_warning (pfile,
- "#pragma implementation for %s appears after file is included",
- copy);
- return 0;
-}
-
-static int
+static void
do_pragma_poison (pfile)
cpp_reader *pfile;
{
@@ -797,13 +794,6 @@ do_pragma_poison (pfile)
error message. */
const cpp_token *tok;
cpp_hashnode *hp;
- int writeit;
-
- /* As a rule, don't include #pragma poison commands in output,
- unless the user asks for them. */
- writeit = (CPP_OPTION (pfile, debug_output)
- || CPP_OPTION (pfile, dump_macros) == dump_definitions
- || CPP_OPTION (pfile, dump_macros) == dump_names);
for (;;)
{
@@ -813,7 +803,7 @@ do_pragma_poison (pfile)
if (tok->type != CPP_NAME)
{
cpp_error (pfile, "invalid #pragma poison directive");
- return 1;
+ return;
}
hp = tok->val.node;
@@ -827,7 +817,9 @@ do_pragma_poison (pfile)
hp->type = T_POISON;
}
}
- return !writeit;
+
+ if (pfile->cb.poison)
+ (*pfile->cb.poison) (pfile);
}
/* Mark the current header as a system header. This will suppress
@@ -836,7 +828,7 @@ do_pragma_poison (pfile)
conforming C, but cannot be certain that their headers appear in a
system include directory. To prevent abuse, it is rejected in the
primary source file. */
-static int
+static void
do_pragma_system_header (pfile)
cpp_reader *pfile;
{
@@ -845,14 +837,12 @@ do_pragma_system_header (pfile)
cpp_warning (pfile, "#pragma system_header outside include file");
else
cpp_make_system_header (pfile, ip, 1);
-
- return 1;
}
/* Check the modified date of the current include file against a specified
file. Issue a diagnostic, if the specified file is newer. We use this to
determine if a fixed header should be refixed. */
-static int
+static void
do_pragma_dependency (pfile)
cpp_reader *pfile;
{
@@ -862,7 +852,7 @@ do_pragma_dependency (pfile)
char left, right;
if (parse_include (pfile, U"pragma dependency", 1, &name, &len, &ab))
- return 1;
+ return;
left = ab ? '<' : '"';
right = ab ? '>' : '"';
@@ -876,21 +866,13 @@ do_pragma_dependency (pfile)
cpp_warning (pfile, "current file is older than %c%.*s%c",
left, (int)len, name, right);
- if (msg->type != CPP_EOF)
+ if (msg->type != CPP_EOF
+ && _cpp_begin_message (pfile, WARNING, NULL, msg->line, msg->col))
{
- U_CHAR *text, *limit;
-
- text = pfile->limit;
- _cpp_dump_list (pfile, &pfile->token_list, msg, 0);
- limit = pfile->limit;
- pfile->limit = text;
- /* There must be something non-whitespace after. */
- while (*text == ' ')
- text++;
- cpp_warning (pfile, "%.*s", (int)(limit - text), text);
+ cpp_output_list (pfile, stderr, &pfile->token_list, msg);
+ putc ('\n', stderr);
}
}
- return 1;
}
/* Just ignore #sccs, on systems where we define it at all. */
@@ -1513,15 +1495,21 @@ cpp_buffer *
cpp_pop_buffer (pfile)
cpp_reader *pfile;
{
+ int wfb;
cpp_buffer *buf = CPP_BUFFER (pfile);
unwind_if_stack (pfile, buf);
- if (buf->inc)
+ wfb = (buf->inc != 0);
+ if (wfb)
_cpp_pop_file_buffer (pfile, buf);
CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
obstack_free (pfile->buffer_ob, buf);
pfile->buffer_stack_depth--;
+
+ if (wfb && pfile->cb.leave_file && CPP_BUFFER (pfile))
+ (*pfile->cb.leave_file) (pfile);
+
return CPP_BUFFER (pfile);
}