diff --git a/gcc/cpperror.c b/gcc/cpperror.c index a2769b6dbda..66921668b88 100644 --- a/gcc/cpperror.c +++ b/gcc/cpperror.c @@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void print_containing_files PARAMS ((cpp_reader *, cpp_buffer *)); static void print_file_and_line PARAMS ((const char *, unsigned int, unsigned int)); -static void v_message PARAMS ((cpp_reader *, int, - const char *, - unsigned int, unsigned int, - const char *, va_list)); + +#define v_message(msgid, ap) \ +do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0) /* Print the file names and line numbers of the #include commands which led to the current file. */ @@ -92,30 +91,83 @@ print_file_and_line (filename, line, column) const char *filename; unsigned int line, column; { - if (filename == 0 || *filename == '\0') - filename = ""; if (line == 0) fputs (_(": "), stderr); - else if (column > 0) - fprintf (stderr, "%s:%u:%u: ", filename, line, column); else - fprintf (stderr, "%s:%u: ", filename, line); + { + if (filename == 0 || *filename == '\0') + filename = ""; + if (column > 0) + fprintf (stderr, "%s:%u:%u: ", filename, line, column); + else + fprintf (stderr, "%s:%u: ", filename, line); + } } -/* IS_ERROR is 3 for ICE, 2 for merely "fatal" error, - 1 for error, 0 for warning. */ +/* Set up for an error message: print the file and line, bump the error + counter, etc. + If it returns 0, this error has been suppressed. */ -static void -v_message (pfile, is_error, file, line, col, msg, ap) +int +_cpp_begin_message (pfile, code, file, line, col) cpp_reader *pfile; - int is_error; + enum error_type code; const char *file; unsigned int line; unsigned int col; - const char *msg; - va_list ap; { cpp_buffer *ip = CPP_BUFFER (pfile); + int is_warning = 0; + + switch (code) + { + case WARNING: + if (! CPP_OPTION (pfile, warnings_are_errors)) + { + if (CPP_OPTION (pfile, inhibit_warnings)) + return 0; + is_warning = 1; + } + else + { + if (CPP_OPTION (pfile, inhibit_errors)) + return 0; + if (pfile->errors < CPP_FATAL_LIMIT) + pfile->errors++; + } + break; + + case PEDWARN: + if (! CPP_OPTION (pfile, pedantic_errors)) + { + if (CPP_OPTION (pfile, inhibit_warnings)) + return 0; + is_warning = 1; + } + else + { + if (CPP_OPTION (pfile, inhibit_errors)) + return 0; + if (pfile->errors < CPP_FATAL_LIMIT) + pfile->errors++; + } + break; + + case ERROR: + if (CPP_OPTION (pfile, inhibit_errors)) + return 0; + if (pfile->errors < CPP_FATAL_LIMIT) + pfile->errors++; + break; + /* Fatal errors cannot be inhibited. */ + case FATAL: + pfile->errors = CPP_FATAL_LIMIT; + break; + case ICE: + fprintf (stderr, _("internal error: ")); + pfile->errors = CPP_FATAL_LIMIT; + break; + } if (ip) { @@ -130,32 +182,10 @@ v_message (pfile, is_error, file, line, col, msg, ap) else fprintf (stderr, "%s: ", progname); - switch (is_error) - { - case 0: - if (! CPP_OPTION (pfile, warnings_are_errors)) - { - fprintf (stderr, _("warning: ")); - break; - } - /* else fall through */ - case 1: - if (pfile->errors < CPP_FATAL_LIMIT) - pfile->errors++; - break; - case 2: - pfile->errors = CPP_FATAL_LIMIT; - break; - case 3: - fprintf (stderr, _("internal error: ")); - pfile->errors = CPP_FATAL_LIMIT; - break; - default: - cpp_ice (pfile, "bad is_error(%d) in v_message", is_error); - } + if (is_warning) + fputs (_("warning: "), stderr); - vfprintf (stderr, _(msg), ap); - putc ('\n', stderr); + return 1; } /* Exported interface. */ @@ -179,7 +209,8 @@ cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...)) msgid = va_arg (ap, const char *); #endif - v_message (pfile, 3, NULL, 0, 0, msgid, ap); + if (_cpp_begin_message (pfile, ICE, NULL, 0, 0)) + v_message (msgid, ap); va_end(ap); } @@ -205,7 +236,8 @@ cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...)) msgid = va_arg (ap, const char *); #endif - v_message (pfile, 2, NULL, 0, 0, msgid, ap); + if (_cpp_begin_message (pfile, FATAL, NULL, 0, 0)) + v_message (msgid, ap); va_end(ap); } @@ -225,10 +257,8 @@ cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, inhibit_errors)) - return; - - v_message (pfile, 1, NULL, 0, 0, msgid, ap); + if (_cpp_begin_message (pfile, ERROR, NULL, 0, 0)) + v_message (msgid, ap); va_end(ap); } @@ -253,10 +283,8 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column, msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, inhibit_errors)) - return; - - v_message (pfile, 1, NULL, line, column, msgid, ap); + if (_cpp_begin_message (pfile, ERROR, NULL, line, column)) + v_message (msgid, ap); va_end(ap); } @@ -285,10 +313,8 @@ cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, inhibit_warnings)) - return; - - v_message (pfile, 0, NULL, 0, 0, msgid, ap); + if (_cpp_begin_message (pfile, WARNING, NULL, 0, 0)) + v_message (msgid, ap); va_end(ap); } @@ -313,10 +339,8 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column, msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, inhibit_warnings)) - return; - - v_message (pfile, 0, NULL, line, column, msgid, ap); + if (_cpp_begin_message (pfile, WARNING, NULL, line, column)) + v_message (msgid, ap); va_end(ap); } @@ -336,13 +360,8 @@ cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, pedantic_errors) - ? CPP_OPTION (pfile, inhibit_errors) - : CPP_OPTION (pfile, inhibit_warnings)) - return; - - v_message (pfile, CPP_OPTION (pfile, pedantic_errors), - NULL, 0, 0, msgid, ap); + if (_cpp_begin_message (pfile, PEDWARN, NULL, 0, 0)) + v_message (msgid, ap); va_end(ap); } @@ -367,13 +386,8 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column, msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, pedantic_errors) - ? CPP_OPTION (pfile, inhibit_errors) - : CPP_OPTION (pfile, inhibit_warnings)) - return; - - v_message (pfile, CPP_OPTION (pfile, pedantic_errors), - NULL, line, column, msgid, ap); + if (_cpp_begin_message (pfile, PEDWARN, NULL, line, column)) + v_message (msgid, ap); va_end(ap); } @@ -404,13 +418,8 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile, msgid = va_arg (ap, const char *); #endif - if (CPP_OPTION (pfile, pedantic_errors) - ? CPP_OPTION (pfile, inhibit_errors) - : CPP_OPTION (pfile, inhibit_warnings)) - return; - - v_message (pfile, CPP_OPTION (pfile, pedantic_errors), - file, line, col, msgid, ap); + if (_cpp_begin_message (pfile, PEDWARN, file, line, col)) + v_message (msgid, ap); va_end(ap); } diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index fe9f0262e3b..2a8f01c3835 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -370,6 +370,20 @@ cpp_make_system_header (pfile, pbuf, flag) pbuf->inc->sysp = flag; } +const char * +cpp_syshdr_flags (pfile, pbuf) + cpp_reader *pfile ATTRIBUTE_UNUSED; + cpp_buffer *pbuf; +{ +#ifndef NO_IMPLICIT_EXTERN_C + if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2) + return " 3 4"; +#endif + if (pbuf->inc->sysp) + return " 3"; + return ""; +} + /* Report on all files that might benefit from a multiple include guard. Triggered by -H. */ void @@ -594,11 +608,6 @@ read_include_file (pfile, inc) cpp_buffer *fp; int fd = inc->fd; - /* Ensures we dump our current line before entering an include file. */ - if (CPP_BUFFER (pfile) && pfile->printer) - cpp_output_tokens (pfile, pfile->printer, - CPP_BUF_LINE (CPP_BUFFER (pfile))); - fp = cpp_push_buffer (pfile, NULL, 0); if (fp == 0) @@ -683,6 +692,8 @@ read_include_file (pfile, inc) fp->actual_dir = actual_directory (pfile, inc->name); pfile->input_stack_listing_current = 0; + if (pfile->cb.enter_file) + (*pfile->cb.enter_file) (pfile); return 1; perror_fail: diff --git a/gcc/cpphash.h b/gcc/cpphash.h index c6c3f0a0b65..c5b024427ec 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -210,10 +210,15 @@ extern unsigned char _cpp_IStable[256]; #define DUMMY_TOKEN 0 #define NO_DUMMY_TOKEN 1 +/* In cpperror.c */ +enum error_type { WARNING = 0, PEDWARN, ERROR, FATAL, ICE }; +extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type, + const char *, unsigned int, + unsigned int)); + /* In cppmacro.c */ extern void _cpp_free_definition PARAMS ((cpp_hashnode *)); extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *)); -extern void _cpp_dump_definition PARAMS ((cpp_reader *, cpp_hashnode *)); /* In cpphash.c */ extern void _cpp_init_macros PARAMS ((cpp_reader *)); @@ -253,9 +258,6 @@ extern int _cpp_equiv_toklists PARAMS ((const cpp_toklist *, extern void _cpp_expand_token_space PARAMS ((cpp_toklist *, unsigned int)); extern void _cpp_reserve_name_space PARAMS ((cpp_toklist *, unsigned int)); extern void _cpp_expand_name_space PARAMS ((cpp_toklist *, unsigned int)); -extern void _cpp_dump_list PARAMS ((cpp_reader *, - const cpp_toklist *, - const cpp_token *, int)); extern int _cpp_equiv_tokens PARAMS ((const cpp_token *, const cpp_token *)); extern void _cpp_run_directive PARAMS ((cpp_reader *, @@ -279,6 +281,7 @@ extern struct answer **_cpp_find_answer PARAMS ((cpp_hashnode *, const cpp_toklist *)); extern void _cpp_init_stacks PARAMS ((cpp_reader *)); extern void _cpp_cleanup_stacks PARAMS ((cpp_reader *)); +extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *)); /* Utility routines and macros. */ #define xnew(T) (T *) xmalloc (sizeof(T)) @@ -295,6 +298,7 @@ static inline int ustrncmp PARAMS ((const U_CHAR *, const U_CHAR *, static inline size_t ustrlen PARAMS ((const U_CHAR *)); static inline U_CHAR *uxstrdup PARAMS ((const U_CHAR *)); static inline U_CHAR *ustrchr PARAMS ((const U_CHAR *, int)); +static inline int ufputs PARAMS ((const U_CHAR *, FILE *)); static inline int ustrcmp (s1, s2) @@ -333,4 +337,12 @@ ustrchr (s1, c) return (U_CHAR *) strchr ((const char *)s1, c); } +static inline int +ufputs (s, f) + const U_CHAR *s; + FILE *f; +{ + return fputs ((const char *)s, f); +} + #endif diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 5f5c6201423..e1bcda9e915 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -114,7 +114,6 @@ static int opt_comp PARAMS ((const void *, const void *)); static void sort_options PARAMS ((void)); #endif static int parse_option PARAMS ((const char *)); -static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *)); /* Fourth argument to append_include_chain: chain to use */ enum { QUOTE = 0, BRACKET, SYSTEM, AFTER }; @@ -415,10 +414,6 @@ cpp_reader_init (pfile) memset ((char *) pfile, 0, sizeof (cpp_reader)); - pfile->token_buffer_size = 200; - pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size); - CPP_SET_WRITTEN (pfile, 0); - CPP_OPTION (pfile, dollars_in_ident) = 1; CPP_OPTION (pfile, cplusplus_comments) = 1; CPP_OPTION (pfile, warn_import) = 1; @@ -434,6 +429,7 @@ cpp_reader_init (pfile) _cpp_init_macros (pfile); _cpp_init_stacks (pfile); _cpp_init_includes (pfile); + _cpp_init_internal_pragmas (pfile); } /* Initialize a cpp_printer structure. As a side effect, open the @@ -470,12 +466,6 @@ cpp_cleanup (pfile) while (CPP_BUFFER (pfile) != NULL) cpp_pop_buffer (pfile); - if (pfile->token_buffer) - { - free (pfile->token_buffer); - pfile->token_buffer = NULL; - } - if (pfile->deps) deps_free (pfile->deps); @@ -857,18 +847,6 @@ cpp_start_read (pfile, print, fname) initialize_dependency_output (pfile); - /* -D and friends may produce output, which should be identified - as line 0. */ - - CPP_BUFFER (pfile)->lineno = 0; - if (print) - { - print->last_fname = CPP_BUFFER (pfile)->nominal_fname; - print->last_id = pfile->include_depth; - print->written = CPP_WRITTEN (pfile); - print->lineno = 0; - } - /* Install __LINE__, etc. */ initialize_builtins (pfile); @@ -883,12 +861,12 @@ cpp_start_read (pfile, print, fname) } pfile->done_initializing = 1; - /* Now flush any output recorded during initialization, and advance - to line 1 of the main input file. */ - CPP_BUFFER (pfile)->lineno = 1; - - if (print && ! CPP_OPTION (pfile, no_output)) - cpp_output_tokens (pfile, print, 1); + /* We start at line 1 of the main input file. */ + if (print) + { + print->last_fname = CPP_BUFFER (pfile)->nominal_fname; + print->lineno = 1; + } /* The -imacros files can be scanned now, but the -include files have to be pushed onto the include stack and processed later, @@ -907,9 +885,7 @@ cpp_start_read (pfile, print, fname) p = CPP_OPTION (pfile, pending)->include_head; while (p) { - if (cpp_read_file (pfile, p->arg) - && print && ! CPP_OPTION (pfile, no_output)) - cpp_output_tokens (pfile, print, 1); /* record entry to file */ + cpp_read_file (pfile, p->arg); q = p->next; free (p); p = q; @@ -921,18 +897,6 @@ cpp_start_read (pfile, print, fname) return 1; } - -/* Dump out the hash table. */ -static int -dump_macros_helper (pfile, hp) - cpp_reader *pfile; - cpp_hashnode *hp; -{ - if (hp->type == T_MACRO) - _cpp_dump_definition (pfile, hp); - return 1; -} - /* This is called at the end of preprocessing. It pops the last buffer and writes dependency output. It should also clear macro definitions, such that you could call cpp_start_read @@ -975,13 +939,11 @@ cpp_finish (pfile, print) } } - if (CPP_OPTION (pfile, dump_macros) == dump_only) - cpp_forall_identifiers (pfile, dump_macros_helper); - /* Flush any pending output. */ if (print) { - cpp_output_tokens (pfile, print, print->lineno); + if (pfile->need_newline) + putc ('\n', print->outf); if (ferror (print->outf) || fclose (print->outf)) cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname)); } diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 0ee0a3d9e15..d7ae4949b62 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -24,13 +24,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Cleanups to do:- -o -dM and with _cpp_dump_list: too many \n output. -o Put a printer object in cpp_reader? o Check line numbers assigned to all errors. o Replace strncmp with memcmp almost everywhere. o lex_line's use of cur_token, flags and list->token_used is a bit opaque. -o Convert do_ functions to return void. Kaveh thinks its OK; and said he'll - give it a run when we've got some code. o Distinguish integers, floats, and 'other' pp-numbers. o Store ints and char constants as binary values. o New command-line assertion syntax. @@ -101,9 +97,7 @@ static void free_macro_args PARAMS ((macro_args *)); #define auto_expand_name_space(list) \ _cpp_expand_name_space ((list), 1 + (list)->name_cap / 2) -static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *, - size_t, FILE *)); -static void dump_param_spelling PARAMS ((cpp_reader *, const cpp_toklist *, +static void dump_param_spelling PARAMS ((FILE *, const cpp_toklist *, unsigned int)); static void output_line_command PARAMS ((cpp_reader *, cpp_printer *, unsigned int)); @@ -135,8 +129,8 @@ static cpp_token *stringify_arg PARAMS ((cpp_reader *, const cpp_token *)); static void expand_context_stack PARAMS ((cpp_reader *)); static unsigned char * spell_token PARAMS ((cpp_reader *, const cpp_token *, unsigned char *)); -static void output_token PARAMS ((cpp_reader *, const cpp_token *, - const cpp_token *)); +static void output_token PARAMS ((cpp_reader *, FILE *, const cpp_token *, + const cpp_token *, int)); typedef unsigned int (* speller) PARAMS ((unsigned char *, cpp_toklist *, cpp_token *)); static cpp_token *make_string_token PARAMS ((cpp_token *, const U_CHAR *, @@ -189,11 +183,21 @@ static void process_directive PARAMS ((cpp_reader *, const cpp_token *)); /* An upper bound on the number of bytes needed to spell a token, including preceding whitespace. */ -#define TOKEN_LEN(token) (5 + (TOKEN_SPELL(token) == SPELL_STRING \ - ? (token)->val.str.len \ - : (TOKEN_SPELL(token) == SPELL_IDENT \ - ? (token)->val.node->length \ - : 0))) +static inline size_t TOKEN_LEN PARAMS ((const cpp_token *)); +static inline size_t +TOKEN_LEN (token) + const cpp_token *token; +{ + size_t len; + + switch (TOKEN_SPELL (token)) + { + default: len = 0; break; + case SPELL_STRING: len = token->val.str.len; break; + case SPELL_IDENT: len = token->val.node->length; break; + } + return len + 5; +} #define IS_ARG_CONTEXT(c) ((c)->flags & CONTEXT_ARG) #define CURRENT_CONTEXT(pfile) ((pfile)->contexts + (pfile)->cur_context) @@ -246,44 +250,6 @@ END #undef END #undef s -/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */ - -void -_cpp_grow_token_buffer (pfile, n) - cpp_reader *pfile; - long n; -{ - long old_written = CPP_WRITTEN (pfile); - pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; - pfile->token_buffer = (U_CHAR *) - xrealloc(pfile->token_buffer, pfile->token_buffer_size); - CPP_SET_WRITTEN (pfile, old_written); -} - -/* Deal with the annoying semantics of fwrite. */ -static void -safe_fwrite (pfile, buf, len, fp) - cpp_reader *pfile; - const U_CHAR *buf; - size_t len; - FILE *fp; -{ - size_t count; - - while (len) - { - count = fwrite (buf, 1, len, fp); - if (count == 0) - goto error; - len -= count; - buf += count; - } - return; - - error: - cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname)); -} - /* Notify the compiler proper that the current line number has jumped, or the current file name has changed. */ @@ -294,51 +260,30 @@ output_line_command (pfile, print, line) unsigned int line; { cpp_buffer *ip = CPP_BUFFER (pfile); - enum { same = 0, enter, leave, rname } change; - static const char * const codes[] = { "", " 1", " 2", "" }; if (line == 0) return; /* End the previous line of text. */ if (pfile->need_newline) - putc ('\n', print->outf); + { + putc ('\n', print->outf); + print->lineno++; + } pfile->need_newline = 0; if (CPP_OPTION (pfile, no_line_commands)) return; - /* If ip is null, we've been called from cpp_finish, and they just - needed the final flush and trailing newline. */ - if (!ip) - return; - - if (pfile->include_depth == print->last_id) - { - /* Determine whether the current filename has changed, and if so, - how. 'nominal_fname' values are unique, so they can be compared - by comparing pointers. */ - if (ip->nominal_fname == print->last_fname) - change = same; - else - change = rname; - } - else - { - if (pfile->include_depth > print->last_id) - change = enter; - else - change = leave; - print->last_id = pfile->include_depth; - } - print->last_fname = ip->nominal_fname; - /* If the current file has not changed, we can output a few newlines instead if we want to increase the line number by a small amount. We cannot do this if print->lineno is zero, because that means we haven't output any line commands yet. (The very first line - command output is a `same_file' command.) */ - if (change == same && print->lineno > 0 + command output is a `same_file' command.) + + 'nominal_fname' values are unique, so they can be compared by + comparing pointers. */ + if (ip->nominal_fname == print->last_fname && print->lineno > 0 && line >= print->lineno && line < print->lineno + 8) { while (line > print->lineno) @@ -349,41 +294,41 @@ output_line_command (pfile, print, line) return; } -#ifndef NO_IMPLICIT_EXTERN_C - if (CPP_OPTION (pfile, cplusplus)) - fprintf (print->outf, "# %u \"%s\"%s%s%s\n", line, ip->nominal_fname, - codes[change], - ip->inc->sysp ? " 3" : "", - (ip->inc->sysp == 2) ? " 4" : ""); - else -#endif - fprintf (print->outf, "# %u \"%s\"%s%s\n", line, ip->nominal_fname, - codes[change], - ip->inc->sysp ? " 3" : ""); + fprintf (print->outf, "# %u \"%s\"%s\n", line, ip->nominal_fname, + cpp_syshdr_flags (pfile, ip)); + + print->last_fname = ip->nominal_fname; print->lineno = line; } -/* Write the contents of the token_buffer to the output stream, and - clear the token_buffer. Also handles generating line commands and - keeping track of file transitions. */ - +/* Like fprintf, but writes to a printer object. You should be sure + always to generate a complete line when you use this function. */ void -cpp_output_tokens (pfile, print, line) - cpp_reader *pfile; - cpp_printer *print; - unsigned int line; +cpp_printf VPARAMS ((cpp_reader *pfile, cpp_printer *print, + const char *fmt, ...)) { - if (CPP_WRITTEN (pfile) - print->written) - { - safe_fwrite (pfile, pfile->token_buffer, - CPP_WRITTEN (pfile) - print->written, print->outf); - pfile->need_newline = 1; - if (print->lineno) - print->lineno++; + va_list ap; +#ifndef ANSI_PROTOTYPES + cpp_reader *pfile; + cpp_printer *print; + const char *fmt; +#endif - CPP_SET_WRITTEN (pfile, print->written); - } - output_line_command (pfile, print, line); + VA_START (ap, fmt); + +#ifndef ANSI_PROTOTYPES + pfile = va_arg (ap, cpp_reader *); + print = va_arg (ap, cpp_printer *); + fmt = va_arg (ap, const char *); +#endif + + /* End the previous line of text. */ + if (pfile->need_newline) + putc ('\n', print->outf); + pfile->need_newline = 0; + + vfprintf (print->outf, fmt, ap); + va_end (ap); } /* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output. */ @@ -434,9 +379,6 @@ cpp_scan_buffer (pfile, print) { cpp_pop_buffer (pfile); - if (CPP_BUFFER (pfile)) - cpp_output_tokens (pfile, print, CPP_BUF_LINE (CPP_BUFFER (pfile))); - if (CPP_BUFFER (pfile) == stop) return; @@ -452,48 +394,18 @@ cpp_scan_buffer (pfile, print) continue; } - cpp_output_tokens (pfile, print, pfile->token_list.line); + output_line_command (pfile, print, pfile->token_list.line); prev = 0; } if (token->type != CPP_PLACEMARKER) - output_token (pfile, token, prev); - - prev = token; - } -} - -/* Scan a single line of the input into the token_buffer. */ -int -cpp_scan_line (pfile) - cpp_reader *pfile; -{ - const cpp_token *token, *prev = 0; - - if (pfile->buffer == NULL) - return 0; - - do - { - token = cpp_get_token (pfile); - if (token->type == CPP_EOF) { - cpp_pop_buffer (pfile); - break; + output_token (pfile, print->outf, token, prev, 1); + pfile->need_newline = 1; } - /* If the last token on a line results from a macro expansion, - the check below will fail to stop us from proceeding to the - next line - so make sure we stick in a newline, at least. */ - if (token->flags & BOL) - CPP_PUTC (pfile, '\n'); - - output_token (pfile, token, prev); prev = token; } - while (pfile->cur_context > 0 - || pfile->contexts[0].posn < pfile->contexts[0].count); - return 1; } /* Helper routine used by parse_include, which can't see spell_token. @@ -503,11 +415,14 @@ const cpp_token * _cpp_glue_header_name (pfile) cpp_reader *pfile; { - unsigned int written = CPP_WRITTEN (pfile); const cpp_token *t; cpp_token *hdr; - U_CHAR *buf; - size_t len; + U_CHAR *buf, *p; + size_t len, avail; + + avail = 40; + len = 0; + buf = xmalloc (avail); for (;;) { @@ -515,19 +430,23 @@ _cpp_glue_header_name (pfile) if (t->type == CPP_GREATER || t->type == CPP_EOF) break; - CPP_RESERVE (pfile, TOKEN_LEN (t)); + if (len + TOKEN_LEN (t) > avail) + { + avail = len + TOKEN_LEN (t) + 40; + buf = xrealloc (buf, avail); + } + if (t->flags & PREV_WHITE) - CPP_PUTC_Q (pfile, ' '); - pfile->limit = spell_token (pfile, t, pfile->limit); + buf[len++] = ' '; + + p = spell_token (pfile, t, buf + len); + len = (size_t) (p - buf); /* p known >= buf */ } if (t->type == CPP_EOF) cpp_error (pfile, "missing terminating > character"); - len = CPP_WRITTEN (pfile) - written; - buf = xmalloc (len); - memcpy (buf, pfile->token_buffer + written, len); - CPP_SET_WRITTEN (pfile, written); + buf = xrealloc (buf, len); hdr = get_temp_token (pfile); hdr->type = CPP_HEADER_NAME; @@ -1894,51 +1813,150 @@ lex_line (pfile, list) } /* Write the spelling of a token TOKEN, with any appropriate - whitespace before it, to the token_buffer. PREV is the previous - token, which is used to determine if we need to shove in an extra - space in order to avoid accidental token paste. */ + whitespace before it, to FP. PREV is the previous token, which + is used to determine if we need to shove in an extra space in order + to avoid accidental token paste. If WHITE is 0, do not insert any + leading whitespace. */ static void -output_token (pfile, token, prev) +output_token (pfile, fp, token, prev, white) cpp_reader *pfile; + FILE *fp; const cpp_token *token, *prev; + int white; { - int dummy; - - if (token->col && (token->flags & BOL)) + if (white) { - /* Supply enough whitespace to put this token in its original - column. Don't bother trying to reconstruct tabs; we can't - get it right in general, and nothing ought to care. (Yes, - some things do care; the fault lies with them.) */ - unsigned char *buffer; - unsigned int spaces = token->col - 1; + int dummy; - CPP_RESERVE (pfile, token->col); - buffer = pfile->limit; + if (token->col && (token->flags & BOL)) + { + /* Supply enough whitespace to put this token in its original + column. Don't bother trying to reconstruct tabs; we can't + get it right in general, and nothing ought to care. (Yes, + some things do care; the fault lies with them.) */ + unsigned int spaces = token->col - 1; + + while (spaces--) + putc (' ', fp); + } + else if (token->flags & PREV_WHITE) + putc (' ', fp); + else + /* Check for and prevent accidental token pasting. + In addition to the cases handled by can_paste, consider - while (spaces--) - *buffer++ = ' '; - pfile->limit = buffer; - } - else if (token->flags & PREV_WHITE) - CPP_PUTC (pfile, ' '); - else if (prev) - { - /* Check for and prevent accidental token pasting. */ - if (can_paste (pfile, prev, token, &dummy) != CPP_EOF) - CPP_PUTC (pfile, ' '); - /* can_paste doesn't catch all the accidental pastes. - Consider a + ++b - if there is not a space between the + and ++, it - will be misparsed as a++ + b. */ - else if ((prev->type == CPP_PLUS && token->type == CPP_PLUS_PLUS) - || (prev->type == CPP_MINUS && token->type == CPP_MINUS_MINUS)) - CPP_PUTC (pfile, ' '); + a + ++b - if there is not a space between the + and ++, it + will be misparsed as a++ + b. But + ## ++ doesn't produce + a valid token. */ + if (prev + && (can_paste (pfile, prev, token, &dummy) != CPP_EOF + || (prev->type == CPP_PLUS && token->type == CPP_PLUS_PLUS) + || (prev->type == CPP_MINUS && token->type == CPP_MINUS_MINUS))) + putc (' ', fp); } - CPP_RESERVE (pfile, TOKEN_LEN (token)); - pfile->limit = spell_token (pfile, token, pfile->limit); + switch (TOKEN_SPELL (token)) + { + case SPELL_OPERATOR: + { + const unsigned char *spelling; + + if (token->flags & DIGRAPH) + spelling = digraph_spellings[token->type - CPP_FIRST_DIGRAPH]; + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + ufputs (spelling, fp); + } + break; + + case SPELL_IDENT: + spell_ident: + ufputs (token->val.node->name, fp); + break; + + case SPELL_STRING: + { + if (token->type == CPP_WSTRING || token->type == CPP_WCHAR) + putc ('L', fp); + + if (token->type == CPP_STRING || token->type == CPP_WSTRING) + putc ('"', fp); + if (token->type == CPP_CHAR || token->type == CPP_WCHAR) + putc ('\'', fp); + + fwrite (token->val.str.text, 1, token->val.str.len, fp); + + if (token->type == CPP_STRING || token->type == CPP_WSTRING) + putc ('"', fp); + if (token->type == CPP_CHAR || token->type == CPP_WCHAR) + putc ('\'', fp); + } + break; + + case SPELL_CHAR: + putc (token->val.aux, fp); + break; + + case SPELL_NONE: + /* Placemarker or EOF - no output. (Macro args are handled + elsewhere. */ + break; + } } +/* Dump the original user's spelling of argument index ARG_NO to the + macro whose expansion is LIST. */ +static void +dump_param_spelling (fp, list, arg_no) + FILE *fp; + const cpp_toklist *list; + unsigned int arg_no; +{ + const U_CHAR *param = list->namebuf; + + while (arg_no--) + param += ustrlen (param) + 1; + ufputs (param, fp); +} + +/* Output all the tokens of LIST, starting at TOKEN, to FP. */ +void +cpp_output_list (pfile, fp, list, token) + cpp_reader *pfile; + FILE *fp; + const cpp_toklist *list; + const cpp_token *token; +{ + const cpp_token *limit = list->tokens + list->tokens_used; + const cpp_token *prev = 0; + int white = 0; + + while (token < limit) + { + /* XXX Find some way we can write macro args from inside + output_token/spell_token. */ + if (token->type == CPP_MACRO_ARG) + { + if (white && token->flags & PREV_WHITE) + putc (' ', fp); + if (token->flags & STRINGIFY_ARG) + putc ('#', fp); + dump_param_spelling (fp, list, token->val.aux); + } + else + output_token (pfile, fp, token, prev, white); + if (token->flags & PASTE_LEFT) + fputs (" ##", fp); + prev = token; + token++; + white = 1; + } +} + + /* Write the spelling of a token TOKEN to BUFFER. The buffer must already contain the enough space to hold the token's spelling. Returns a pointer to the character after the last character @@ -3033,12 +3051,6 @@ process_directive (pfile, token) else if (token[1].type != CPP_NUMBER) cpp_ice (pfile, "directive begins with %s?!", TOKEN_NAME (token)); - /* Flush pending tokens at this point, in case the directive produces - output. XXX Directive output won't be visible to a direct caller of - cpp_get_token. */ - if (pfile->printer && CPP_WRITTEN (pfile) - pfile->printer->written) - cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line); - if (! (d->flags & EXPAND)) prev_nme = prevent_macro_expansion (pfile); (void) (*d->handler) (pfile); @@ -3464,58 +3476,6 @@ special_symbol (pfile, node, token) } #undef DSC -/* Dump the original user's spelling of argument index ARG_NO to the - macro whose expansion is LIST. */ -static void -dump_param_spelling (pfile, list, arg_no) - cpp_reader *pfile; - const cpp_toklist *list; - unsigned int arg_no; -{ - const U_CHAR *param = list->namebuf; - - while (arg_no--) - param += ustrlen (param) + 1; - CPP_PUTS (pfile, param, ustrlen (param)); -} - -/* Dump a token list to the output. */ -void -_cpp_dump_list (pfile, list, token, flush) - cpp_reader *pfile; - const cpp_toklist *list; - const cpp_token *token; - int flush; -{ - const cpp_token *limit = list->tokens + list->tokens_used; - const cpp_token *prev = 0; - - /* Avoid the CPP_EOF. */ - if (list->directive) - limit--; - - while (token < limit) - { - if (token->type == CPP_MACRO_ARG) - { - if (token->flags & PREV_WHITE) - CPP_PUTC (pfile, ' '); - if (token->flags & STRINGIFY_ARG) - CPP_PUTC (pfile, '#'); - dump_param_spelling (pfile, list, token->val.aux); - } - else if (token->type != CPP_PLACEMARKER) - output_token (pfile, token, prev); - if (token->flags & PASTE_LEFT) - CPP_PUTS (pfile, " ##", 3); - prev = token; - token++; - } - - if (flush && pfile->printer) - cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line); -} - /* Allocate pfile->input_buffer, and initialize trigraph_map[] if it hasn't happened already. */ diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 7d7bbc2fb1a..ade5ee3a621 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[] = -{ - {"once", do_pragma_once}, - {"implementation", do_pragma_implementation}, - {"poison", do_pragma_poison}, - {"GCC", do_pragma_gcc}, - {NULL, NULL} -}; - -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} -}; - -static int pragma_dispatch (pfile, table, node) +void +cpp_register_pragma (pfile, space, name, handler) cpp_reader *pfile; - const struct pragma_entry *table; - const cpp_hashnode *node; + const char *space; + const char *name; + void (*handler) PARAMS ((cpp_reader *)); { - const U_CHAR *p = node->name; - size_t len = node->length; + struct pragma_entry **x, *new; + size_t len; + + 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; +} + +void +cpp_register_pragma_space (pfile, space) + cpp_reader *pfile; + const char *space; +{ + 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); + 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; + } + + if (pfile->cb.def_pragma) + (*pfile->cb.def_pragma) (pfile); } -static int -do_pragma_gcc (pfile) - cpp_reader *pfile; -{ - const cpp_token *tok; - - 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); -} - -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); } diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 62755a9eb9b..20bea99a19e 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -432,19 +432,9 @@ struct cpp_options struct cpp_reader { - /* HACK FIXME. Maybe make into cpp_printer printer later. */ - cpp_printer *printer; - /* Top of buffer stack. */ cpp_buffer *buffer; - /* A buffer used for both for cpp_get_token's output, and also internally. */ - unsigned char *token_buffer; - /* Allocated size of token_buffer. CPP_RESERVE allocates space. */ - unsigned int token_buffer_size; - /* End of the written part of token_buffer. */ - unsigned char *limit; - /* Error counter for exit code */ unsigned int errors; @@ -523,6 +513,23 @@ struct cpp_reader real stack. See cpplib.c */ struct obstack *buffer_ob; + /* Pragma table - dynamic, because a library user can add to the + list of recognized pragmas. */ + struct pragma_entry *pragmas; + + /* Call backs. */ + struct { + void (*enter_file) PARAMS ((cpp_reader *)); + void (*leave_file) PARAMS ((cpp_reader *)); + void (*include) PARAMS ((cpp_reader *, const unsigned char *, + const unsigned char *, unsigned int, int)); + void (*define) PARAMS ((cpp_reader *, cpp_hashnode *)); + void (*undef) PARAMS ((cpp_reader *, cpp_hashnode *)); + void (*poison) PARAMS ((cpp_reader *)); + void (*ident) PARAMS ((cpp_reader *, const cpp_token *)); + void (*def_pragma) PARAMS ((cpp_reader *)); + } cb; + /* User visible options. */ struct cpp_options opts; @@ -563,23 +570,13 @@ struct cpp_printer { FILE *outf; /* stream to write to */ const char *last_fname; /* previous file name */ - unsigned int last_id; /* did we just push? */ unsigned int lineno; /* line currently being written */ - unsigned int written; /* low water mark in token buffer */ }; #define CPP_FATAL_LIMIT 1000 /* True if we have seen a "fatal" error. */ #define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT) -/* Macros for manipulating the token_buffer. */ - -/* Number of characters currently in PFILE's output buffer. */ -#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer)) -#define CPP_PWRITTEN(PFILE) ((PFILE)->limit) -#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA)) -#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N)) - #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION) #define CPP_BUFFER(PFILE) ((PFILE)->buffer) #define CPP_BUF_LINE(BUF) ((BUF)->lineno) @@ -641,6 +638,12 @@ extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **)); extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **)); extern void cpp_reader_init PARAMS ((cpp_reader *)); extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *)); + +extern void cpp_register_pragma PARAMS ((cpp_reader *, + const char *, const char *, + void (*) PARAMS ((cpp_reader *)))); +extern void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *)); + extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *)); extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *, unsigned int)); @@ -695,9 +698,14 @@ extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *, extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *)); extern void cpp_scan_buffer PARAMS ((cpp_reader *, cpp_printer *)); extern void cpp_scan_buffer_nooutput PARAMS ((cpp_reader *)); -extern int cpp_scan_line PARAMS ((cpp_reader *)); extern int cpp_ideq PARAMS ((const cpp_token *, const char *)); +extern void cpp_printf PARAMS ((cpp_reader *, cpp_printer *, + const char *, ...)); + +extern void cpp_output_list PARAMS ((cpp_reader *, FILE *, + const cpp_toklist *, + const cpp_token *)); /* In cpphash.c */ extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *, @@ -705,11 +713,15 @@ extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *, extern void cpp_forall_identifiers PARAMS ((cpp_reader *, int (*) PARAMS ((cpp_reader *, cpp_hashnode *)))); +/* In cppmacro.c */ +extern void cpp_dump_definition PARAMS ((cpp_reader *, FILE *, + const cpp_hashnode *)); /* In cppfiles.c */ extern int cpp_included PARAMS ((cpp_reader *, const char *)); extern int cpp_read_file PARAMS ((cpp_reader *, const char *)); extern void cpp_make_system_header PARAMS ((cpp_reader *, cpp_buffer *, int)); +extern const char *cpp_syshdr_flags PARAMS ((cpp_reader *, cpp_buffer *)); #ifdef __cplusplus } diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index 8d53baf71f6..5ff49a8d4df 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -40,7 +40,7 @@ struct macro_info unsigned char flags; }; -static void dump_funlike_macro PARAMS ((cpp_reader *, cpp_hashnode *)); +static void dump_macro_args PARAMS ((FILE *, const cpp_toklist *)); static void count_params PARAMS ((cpp_reader *, struct macro_info *)); static int is__va_args__ PARAMS ((cpp_reader *, const cpp_token *)); @@ -554,66 +554,53 @@ _cpp_create_definition (pfile, hp) return 1; } -/* Dump the definition of macro MACRO on stdout. The format is suitable - to be read back in again. */ +/* Dump the definition of macro MACRO on FP. The format is suitable + to be read back in again. Caller is expected to generate the + "#define NAME" bit. */ void -_cpp_dump_definition (pfile, hp) +cpp_dump_definition (pfile, fp, hp) cpp_reader *pfile; - cpp_hashnode *hp; + FILE *fp; + const cpp_hashnode *hp; { - CPP_RESERVE (pfile, hp->length + sizeof "#define "); - CPP_PUTS_Q (pfile, "#define ", sizeof "#define " - 1); - CPP_PUTS_Q (pfile, hp->name, hp->length); + const cpp_toklist *list = hp->value.expansion; - if (hp->type == T_MACRO) + if (hp->type != T_MACRO) { - if (hp->value.expansion->paramc >= 0) - dump_funlike_macro (pfile, hp); - else - { - const cpp_toklist *list = hp->value.expansion; - list->tokens[0].flags &= ~BOL; - list->tokens[0].flags |= PREV_WHITE; - _cpp_dump_list (pfile, list, list->tokens, 1); - } + cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type); + return; } - else - cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type); - if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing) - CPP_PUTC (pfile, '\n'); + if (list->paramc >= 0) + dump_macro_args (fp, list); + + putc (' ', fp); + cpp_output_list (pfile, fp, list, list->tokens); } static void -dump_funlike_macro (pfile, node) - cpp_reader *pfile; - cpp_hashnode *node; +dump_macro_args (fp, list) + FILE *fp; + const cpp_toklist *list; { - int i = 0; - const cpp_toklist * list = node->value.expansion; - const U_CHAR *param; + int i; + const U_CHAR *param = list->namebuf; - param = list->namebuf; - CPP_PUTC_Q (pfile, '('); + putc ('(', fp); for (i = 0; i++ < list->paramc;) { unsigned int len; len = ustrlen (param); - CPP_PUTS (pfile, param, len); + if (!list->flags & VAR_ARGS || ustrcmp (param, U"__VA_ARGS__")) + ufputs (param, fp); if (i < list->paramc) - CPP_PUTS(pfile, ", ", 2); + fputs (", ", fp); else if (list->flags & VAR_ARGS) - { - if (!ustrcmp (param, U"__VA_ARGS__")) - pfile->limit -= sizeof (U"__VA_ARGS__") - 1; - CPP_PUTS_Q (pfile, "...", 3); - } + fputs ("...", fp); + param += len + 1; } - CPP_PUTC (pfile, ')'); - list->tokens[0].flags &= ~BOL; - list->tokens[0].flags |= PREV_WHITE; - _cpp_dump_list (pfile, list, list->tokens, 1); + putc (')', fp); } diff --git a/gcc/cppmain.c b/gcc/cppmain.c index 8be2a1df63e..0af5442f3f8 100644 --- a/gcc/cppmain.c +++ b/gcc/cppmain.c @@ -30,8 +30,23 @@ const char *progname; cpp_reader parse_in; cpp_printer parse_out; - -extern int main PARAMS ((int, char **)); +int main PARAMS ((int, char **)); + +/* Callback routines for the parser. Most of these are active only + in specific modes. */ +static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *)); +static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *)); +static void cb_include PARAMS ((cpp_reader *, const unsigned char *, + const unsigned char *, unsigned int, int)); + +static void cb_ident PARAMS ((cpp_reader *, const cpp_token *)); +static void cb_enter_file PARAMS ((cpp_reader *)); +static void cb_leave_file PARAMS ((cpp_reader *)); +static void cb_def_pragma PARAMS ((cpp_reader *)); + +static void do_pragma_implementation PARAMS ((cpp_reader *)); +static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *)); + int main (argc, argv) int argc; @@ -68,8 +83,30 @@ main (argc, argv) print = cpp_printer_init (pfile, &parse_out); if (! print) return (FATAL_EXIT_CODE); - if (! CPP_OPTION (pfile, no_output)) - pfile->printer = print; + + /* Set callbacks. */ + if (! CPP_OPTION (pfile, no_line_commands) + && ! CPP_OPTION (pfile, no_output)) + { + pfile->cb.enter_file = cb_enter_file; + pfile->cb.leave_file = cb_leave_file; + } + if (CPP_OPTION (pfile, dump_includes)) + pfile->cb.include = cb_include; + if (CPP_OPTION (pfile, debug_output) + || CPP_OPTION (pfile, dump_macros) == dump_names + || CPP_OPTION (pfile, dump_macros) == dump_definitions) + { + pfile->cb.define = cb_define; + pfile->cb.undef = cb_undef; + pfile->cb.poison = cb_def_pragma; + } + pfile->cb.ident = cb_ident; + pfile->cb.def_pragma = cb_def_pragma; + + /* Register one #pragma which needs special handling. */ + cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation); + cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation); if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname))) return (FATAL_EXIT_CODE); @@ -81,6 +118,9 @@ main (argc, argv) while (CPP_BUFFER (pfile) != NULL) cpp_scan_buffer (pfile, print); + if (CPP_OPTION (pfile, dump_macros) == dump_only) + cpp_forall_identifiers (pfile, dump_macros_helper); + cpp_finish (pfile, print); cpp_cleanup (pfile); @@ -88,3 +128,137 @@ main (argc, argv) return (FATAL_EXIT_CODE); return (SUCCESS_EXIT_CODE); } + +/* Callbacks */ + +static void +cb_ident (pfile, token) + cpp_reader *pfile; + const cpp_token *token; +{ + cpp_printf (pfile, &parse_out, "#ident \"%.*s\"\n", + (int) token->val.str.len, token->val.str.text); +} + +static void +cb_define (pfile, hash) + cpp_reader *pfile; + cpp_hashnode *hash; +{ + cpp_printf (pfile, &parse_out, "#define %s", hash->name); + if (CPP_OPTION (pfile, debug_output) + || CPP_OPTION (pfile, dump_macros) == dump_definitions) + cpp_dump_definition (pfile, parse_out.outf, hash); + putc ('\n', parse_out.outf); +} + +static void +cb_undef (pfile, hash) + cpp_reader *pfile; + cpp_hashnode *hash; +{ + cpp_printf (pfile, &parse_out, "#undef %s\n", hash->name); +} + +static void +cb_include (pfile, dir, str, len, ab) + cpp_reader *pfile; + const unsigned char *dir; + const unsigned char *str; + unsigned int len; + int ab; +{ + int l, r; + if (ab) + l = '<', r = '>'; + else + l = '"', r = '"'; + + cpp_printf (pfile, &parse_out, "#%s %c%.*s%c\n", dir, l, (int) len, str, r); +} + +static void +cb_enter_file (pfile) + cpp_reader *pfile; +{ + cpp_buffer *ip = CPP_BUFFER (pfile); + + cpp_printf (pfile, &parse_out, "# 1 \"%s\"%s%s\n", ip->nominal_fname, + pfile->done_initializing ? " 1" : "", + cpp_syshdr_flags (pfile, ip)); + + parse_out.lineno = 1; + parse_out.last_fname = ip->nominal_fname; +} + +static void +cb_leave_file (pfile) + cpp_reader *pfile; +{ + cpp_buffer *ip = CPP_BUFFER (pfile); + + cpp_printf (pfile, &parse_out, "# %u \"%s\" 2%s\n", ip->lineno, + ip->nominal_fname, cpp_syshdr_flags (pfile, ip)); + + parse_out.lineno = ip->lineno; + parse_out.last_fname = ip->nominal_fname; +} + +static void +cb_def_pragma (pfile) + cpp_reader *pfile; +{ + cpp_printf (pfile, &parse_out, "#pragma "); + cpp_output_list (pfile, parse_out.outf, &pfile->token_list, + pfile->first_directive_token); + putc ('\n', parse_out.outf); +} + +static void +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) + { + if (tok->type != CPP_STRING || cpp_get_token (pfile)->type != CPP_EOF) + { + cpp_error (pfile, "malformed #pragma implementation"); + return; + } + + /* 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); + } + + /* forward to default-pragma handler. */ + cb_def_pragma (pfile); +} + +/* Dump out the hash table. */ +static int +dump_macros_helper (pfile, hp) + cpp_reader *pfile; + cpp_hashnode *hp; +{ + if (hp->type == T_MACRO) + { + cpp_printf (pfile, &parse_out, "#define %s", hp->name); + cpp_dump_definition (pfile, parse_out.outf, hp); + putc ('\n', parse_out.outf); + } + + return 1; +} + diff --git a/gcc/testsuite/g77.f-torture/compile/20000629-1.x b/gcc/testsuite/g77.f-torture/compile/20000629-1.x deleted file mode 100644 index c09b84270eb..00000000000 --- a/gcc/testsuite/g77.f-torture/compile/20000629-1.x +++ /dev/null @@ -1,3 +0,0 @@ -set torture_compile_xfail "*-*-*" - -return 0