diff options
Diffstat (limited to 'contrib/gcclibs/libcpp')
-rw-r--r-- | contrib/gcclibs/libcpp/ChangeLog.gcc43 | 57 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/Makefile.in | 12 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/charset.c | 2 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/directives-only.c | 229 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/directives.c | 7 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/errors.c | 15 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/expr.c | 24 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/files.c | 80 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/include/cpplib.h | 7 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/init.c | 27 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/internal.h | 15 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/lex.c | 40 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/macro.c | 39 | ||||
-rw-r--r-- | contrib/gcclibs/libcpp/pch.c | 74 |
14 files changed, 530 insertions, 98 deletions
diff --git a/contrib/gcclibs/libcpp/ChangeLog.gcc43 b/contrib/gcclibs/libcpp/ChangeLog.gcc43 new file mode 100644 index 0000000..da70d1c --- /dev/null +++ b/contrib/gcclibs/libcpp/ChangeLog.gcc43 @@ -0,0 +1,57 @@ +2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> (r250566) + + PR preprocessor/23479 + * expr.c (cpp_classify_number): Implement 0b-prefixed binary + integer constants. + (append_digit): Likewise. + * include/cpplib.h: Add CPP_N_BINARY, to be used for 0b-prefixed + binary integer constants. + +2007-05-31 Dave Korn <dave.korn@artimi.com> (r125212) + + PR preprocessor/14331 + * lex.c (_cpp_get_fresh_line): Don't warn if no newline at EOF. + +2007-05-21 Ian Lance Taylor <iant@google.com> (r124929) + + * internal.h (struct cpp_reader): Add new fields: + nonexistent_file_hash and nonexistent_file_ob. + * files.c: Include "obstack.h". + (find_file_in_dir): Before trying to open the file, look up the + path name in the hash table of nonexistent files. After failing + to open the file, add the path name to the hash table. + (_cpp_find_file): Cache the results of looking up the file name + starting with the quote and bracket chain heads, if we can. + (nonexistent_file_hash_eq): New static function. + (_cpp_init_files): Initialize pfile->nonexistent_file_hash and + pfile->nonexistent_file_ob. + (_cpp_cleanup_files): Free pfile->nonexistent_file_hash and + pfile->nonexistent_file_ob. + +2007-05-14 Janis Johnson <janis187@us.ibm.com> (r124731) + + PR c/31924 + * expr.c (interpret_float_suffix): Check for invalid suffix. + +2007-05-02 Eric Christopher <echristo@apple.com> (r124358) + + * expr.c (num_div_op): Don't overflow if the result is + zero. + +2007-05-02 Tom Tromey <tromey@redhat.com> (r124356) + + PR preprocessor/28709: + * macro.c (paste_tokens): Remove PASTE_LEFT from the old lhs. + +2007-01-30 Tom Tromey <tromey@redhat.com> (r121340) + + PR preprocessor/29966: + * macro.c (lex_expansion_token): Save and restore cpp_reader's + cur_token. + (_cpp_create_definition): Don't restore cur_token here. + * lex.c (_cpp_lex_token): Added assertion. + +2006-12-29 Ian Lance Taylor <iant@google.com> (r120263) + + * lex.c (_cpp_clean_line): Add uses of __builtin_expect. Don't + look backward at the end of the line unless we saw a backslash. diff --git a/contrib/gcclibs/libcpp/Makefile.in b/contrib/gcclibs/libcpp/Makefile.in index 7a0b74f..697318d 100644 --- a/contrib/gcclibs/libcpp/Makefile.in +++ b/contrib/gcclibs/libcpp/Makefile.in @@ -69,14 +69,14 @@ INCLUDES = -I$(srcdir) -I. -I$(srcdir)/../include @INCINTL@ \ ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS) -libcpp_a_OBJS = charset.o directives.o errors.o expr.o files.o \ - identifiers.o init.o lex.o line-map.o macro.o mkdeps.o \ - pch.o symtab.o traditional.o +libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \ + expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \ + mkdeps.o pch.o symtab.o traditional.o makedepend_OBJS = makedepend.o -libcpp_a_SOURCES = charset.c directives.c errors.c expr.c files.c \ - identifiers.c init.c lex.c line-map.c macro.c mkdeps.c \ - pch.c symtab.c traditional.c +libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \ + expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \ + mkdeps.c pch.c symtab.c traditional.c all: libcpp.a makedepend$(EXEEXT) $(USED_CATALOGS) diff --git a/contrib/gcclibs/libcpp/charset.c b/contrib/gcclibs/libcpp/charset.c index 78c8981..6361f8c 100644 --- a/contrib/gcclibs/libcpp/charset.c +++ b/contrib/gcclibs/libcpp/charset.c @@ -1628,7 +1628,7 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, terminate with another \r, not an \n, so that we do not mistake the \r\n sequence for a single DOS line ending and erroneously issue the "No newline at end of file" diagnostic. */ - if (to.text[to.len - 1] == '\r') + if (to.len > 0 && to.text[to.len - 1] == '\r') to.text[to.len] = '\r'; else to.text[to.len] = '\n'; diff --git a/contrib/gcclibs/libcpp/directives-only.c b/contrib/gcclibs/libcpp/directives-only.c new file mode 100644 index 0000000..5990fbf --- /dev/null +++ b/contrib/gcclibs/libcpp/directives-only.c @@ -0,0 +1,229 @@ +/* CPP Library - directive only preprocessing for distributed compilation. + Copyright (C) 2007 + Free Software Foundation, Inc. + Contributed by Ollie Wild <aaw@google.com>. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +/* DO (Directive only) flags. */ +#define DO_BOL (1 << 0) /* At the beginning of a logical line. */ +#define DO_STRING (1 << 1) /* In a string constant. */ +#define DO_CHAR (1 << 2) /* In a character constant. */ +#define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */ +#define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */ + +#define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT) +#define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT) + +/* Writes out the preprocessed file, handling spacing and paste + avoidance issues. */ +void +_cpp_preprocess_dir_only (cpp_reader *pfile, + const struct _cpp_dir_only_callbacks *cb) +{ + struct cpp_buffer *buffer; + const unsigned char *cur, *base, *next_line, *rlimit; + cppchar_t c, last_c; + unsigned flags; + int lines, col; + source_location loc; + + restart: + /* Buffer initialization ala _cpp_clean_line(). */ + buffer = pfile->buffer; + buffer->cur_note = buffer->notes_used = 0; + buffer->cur = buffer->line_base = buffer->next_line; + buffer->need_line = false; + + /* This isn't really needed. It prevents a compiler warning, though. */ + loc = pfile->line_table->highest_line; + + /* Scan initialization. */ + next_line = cur = base = buffer->cur; + rlimit = buffer->rlimit; + flags = DO_BOL; + lines = 0; + col = 1; + + for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col) + { + /* Skip over escaped newlines. */ + if (__builtin_expect (c == '\\', false)) + { + const unsigned char *tmp = cur + 1; + + while (is_nvspace (*tmp) && tmp < rlimit) + tmp++; + if (*tmp == '\r') + tmp++; + if (*tmp == '\n' && tmp < rlimit) + { + CPP_INCREMENT_LINE (pfile, 0); + lines++; + col = 0; + cur = tmp; + c = last_c; + continue; + } + } + + if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL)) + { + if (c != '#' && (flags & DO_BOL)) + { + struct line_maps *line_table; + + if (!pfile->state.skipping && next_line != base) + cb->print_lines (lines, base, next_line - base); + + /* Prep things for directive handling. */ + buffer->next_line = cur; + buffer->need_line = true; + _cpp_get_fresh_line (pfile); + + /* Ensure proper column numbering for generated error messages. */ + buffer->line_base -= col - 1; + + _cpp_handle_directive (pfile, 0 /* ignore indented */); + + /* Sanitize the line settings. Duplicate #include's can mess + things up. */ + line_table = pfile->line_table; + line_table->highest_location = line_table->highest_line; + + /* The if block prevents us from outputing line information when + the file ends with a directive and no newline. Note that we + must use pfile->buffer, not buffer. */ + if (pfile->buffer->cur != pfile->buffer->rlimit) + cb->maybe_print_line (pfile->line_table->highest_line); + + goto restart; + } + + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + else if (__builtin_expect (last_c == '/', false) \ + && !(flags & DO_SPECIAL) && c != '*' && c != '/') + { + /* If a previous slash is not starting a block comment, clear the + DO_BOL flag. */ + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + + switch (c) + { + case '/': + if ((flags & DO_BLOCK_COMMENT) && last_c == '*') + { + flags &= ~DO_BLOCK_COMMENT; + c = 0; + } + else if (!(flags & DO_SPECIAL) && last_c == '/') + flags |= DO_LINE_COMMENT; + else if (!(flags & DO_SPECIAL)) + /* Mark the position for possible error reporting. */ + LINEMAP_POSITION_FOR_COLUMN (loc, pfile->line_table, col); + + break; + + case '*': + if (!(flags & DO_SPECIAL)) + { + if (last_c == '/') + flags |= DO_BLOCK_COMMENT; + else + { + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + } + + break; + + case '\'': + case '"': + { + unsigned state = (c == '"') ? DO_STRING : DO_CHAR; + + if (!(flags & DO_SPECIAL)) + { + flags |= state; + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + else if ((flags & state) && last_c != '\\') + flags &= ~state; + + break; + } + + case '\\': + { + if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\') + c = 0; + + if (!(flags & DO_SPECIAL)) + { + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + + break; + } + + case '\n': + CPP_INCREMENT_LINE (pfile, 0); + lines++; + col = 0; + flags &= ~DO_LINE_SPECIAL; + if (!(flags & DO_SPECIAL)) + flags |= DO_BOL; + break; + + case '#': + next_line = cur; + /* Don't update DO_BOL yet. */ + break; + + case ' ': case '\t': case '\f': case '\v': case '\0': + break; + + default: + if (!(flags & DO_SPECIAL)) + { + flags &= ~DO_BOL; + pfile->mi_valid = false; + } + break; + } + } + + if (flags & DO_BLOCK_COMMENT) + cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment"); + + if (!pfile->state.skipping && cur != base) + cb->print_lines (lines, base, cur - base); + + _cpp_pop_buffer (pfile); + if (pfile->buffer) + goto restart; +} diff --git a/contrib/gcclibs/libcpp/directives.c b/contrib/gcclibs/libcpp/directives.c index 7fb142e..7011842 100644 --- a/contrib/gcclibs/libcpp/directives.c +++ b/contrib/gcclibs/libcpp/directives.c @@ -423,8 +423,13 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) does not cause '#define foo bar' to get executed when compiled with -save-temps, we recognize directives in -fpreprocessed mode only if the # is in column 1. macro.c - puts a space in front of any '#' at the start of a macro. */ + puts a space in front of any '#' at the start of a macro. + + We exclude the -fdirectives-only case because macro expansion + has not been performed yet, and block comments can cause spaces + to preceed the directive. */ if (CPP_OPTION (pfile, preprocessed) + && !CPP_OPTION (pfile, directives_only) && (indented || !(dir->flags & IN_I))) { skip = 0; diff --git a/contrib/gcclibs/libcpp/errors.c b/contrib/gcclibs/libcpp/errors.c index 97de490..c8efd53 100644 --- a/contrib/gcclibs/libcpp/errors.c +++ b/contrib/gcclibs/libcpp/errors.c @@ -153,7 +153,20 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) } else { - src_loc = pfile->cur_token[-1].src_loc; + /* Find actual previous token. */ + cpp_token *t; + + if (pfile->cur_token != pfile->cur_run->base) + t = pfile->cur_token - 1; + else + { + if (pfile->cur_run->prev != NULL) + t = pfile->cur_run->prev->limit; + else + t = NULL; + } + /* Retrieve corresponding source location, unless we failed. */ + src_loc = t ? t->src_loc : 0; } if (_cpp_begin_message (pfile, level, src_loc, 0)) diff --git a/contrib/gcclibs/libcpp/expr.c b/contrib/gcclibs/libcpp/expr.c index 24fcb1b8..ac7252f 100644 --- a/contrib/gcclibs/libcpp/expr.c +++ b/contrib/gcclibs/libcpp/expr.c @@ -87,16 +87,19 @@ interpret_float_suffix (const uchar *s, size_t len) while (len--) switch (s[len]) { - case 'f': case 'F': f++; break; - case 'l': case 'L': l++; break; - case 'i': case 'I': - case 'j': case 'J': i++; break; - case 'd': case 'D': - /* Disallow fd, ld suffixes. */ - if (d && (f || l)) + case 'f': case 'F': + if (d > 0) + return 0; + f++; + break; + case 'l': case 'L': + if (d > 0) return 0; - d++; + l++; break; + case 'i': case 'I': + case 'j': case 'J': i++; break; + case 'd': case 'D': d++; break; default: return 0; } @@ -494,7 +497,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision) if (add_low + digit < add_low) add_high++; add_low += digit; - + if (result.low + add_low < result.low) add_high++; if (result.high + add_high < result.high) @@ -1580,7 +1583,8 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) { if (negate) result = num_negate (result, precision); - result.overflow = num_positive (result, precision) ^ !negate; + result.overflow = (num_positive (result, precision) ^ !negate + && !num_zerop (result)); } return result; diff --git a/contrib/gcclibs/libcpp/files.c b/contrib/gcclibs/libcpp/files.c index 8334218..0e9f977 100644 --- a/contrib/gcclibs/libcpp/files.c +++ b/contrib/gcclibs/libcpp/files.c @@ -1,6 +1,7 @@ /* Part of CPP library. File handling. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Written by Per Bothner, 1994. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -26,6 +27,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "cpplib.h" #include "internal.h" #include "mkdeps.h" +#include "obstack.h" #include "hashtab.h" #include "md5.h" #include <dirent.h> @@ -322,6 +324,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (path) { + hashval_t hv = htab_hash_string (path); + char *copy; + void **pp; + + if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL) + { + file->err_no = ENOENT; + return false; + } + file->path = path; if (pch_open_file (pfile, file, invalid_pch)) return true; @@ -335,7 +347,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) return true; } + /* We copy the path name onto an obstack partly so that we don't + leak the memory, but mostly so that we don't fragment the + heap. */ + copy = obstack_copy0 (&pfile->nonexistent_file_ob, path, + strlen (path)); free (path); + pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash, + copy, hv, INSERT); + *pp = copy; + file->path = file->name; } else @@ -396,6 +417,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f struct file_hash_entry *entry, **hash_slot; _cpp_file *file; bool invalid_pch = false; + bool saw_bracket_include = false; + bool saw_quote_include = false; + struct cpp_dir *found_in_cache = NULL; /* Ensure we get no confusion between cached files and directories. */ if (start_dir == NULL) @@ -448,13 +472,19 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f /* Only check the cache for the starting location (done above) and the quote and bracket chain heads because there are no other possible starting points for searches. */ - if (file->dir != pfile->bracket_include - && file->dir != pfile->quote_include) + if (file->dir == pfile->bracket_include) + saw_bracket_include = true; + else if (file->dir == pfile->quote_include) + saw_quote_include = true; + else continue; entry = search_cache (*hash_slot, file->dir); if (entry) - break; + { + found_in_cache = file->dir; + break; + } } if (entry) @@ -478,6 +508,29 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f entry->u.file = file; *hash_slot = entry; + /* If we passed the quote or bracket chain heads, cache them also. + This speeds up processing if there are lots of -I options. */ + if (saw_bracket_include + && pfile->bracket_include != start_dir + && found_in_cache != pfile->bracket_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->bracket_include; + entry->u.file = file; + *hash_slot = entry; + } + if (saw_quote_include + && pfile->quote_include != start_dir + && found_in_cache != pfile->quote_include) + { + entry = new_file_hash_entry (pfile); + entry->next = *hash_slot; + entry->start_dir = pfile->quote_include; + entry->u.file = file; + *hash_slot = entry; + } + return file; } @@ -722,7 +775,8 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) /* Stack the buffer. */ buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size, - CPP_OPTION (pfile, preprocessed)); + CPP_OPTION (pfile, preprocessed) + && !CPP_OPTION (pfile, directives_only)); buffer->file = file; buffer->sysp = sysp; @@ -997,6 +1051,14 @@ file_hash_eq (const void *p, const void *q) return strcmp (hname, fname) == 0; } +/* Compare entries in the nonexistent file hash table. These are just + strings. */ +static int +nonexistent_file_hash_eq (const void *p, const void *q) +{ + return strcmp (p, q) == 0; +} + /* Initialize everything in this source file. */ void _cpp_init_files (cpp_reader *pfile) @@ -1006,6 +1068,12 @@ _cpp_init_files (cpp_reader *pfile) pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, NULL, xcalloc, free); allocate_file_hash_entries (pfile); + pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, + nonexistent_file_hash_eq, + NULL, xcalloc, free); + _obstack_begin (&pfile->nonexistent_file_ob, 0, 0, + (void *(*) (long)) xmalloc, + (void (*) (void *)) free); } /* Finalize everything in this source file. */ @@ -1014,6 +1082,8 @@ _cpp_cleanup_files (cpp_reader *pfile) { htab_delete (pfile->file_hash); htab_delete (pfile->dir_hash); + htab_delete (pfile->nonexistent_file_hash); + obstack_free (&pfile->nonexistent_file_ob, 0); } /* Enter a file name in the hash for the sake of cpp_included. */ diff --git a/contrib/gcclibs/libcpp/include/cpplib.h b/contrib/gcclibs/libcpp/include/cpplib.h index 7fd73b8..5acef41 100644 --- a/contrib/gcclibs/libcpp/include/cpplib.h +++ b/contrib/gcclibs/libcpp/include/cpplib.h @@ -440,6 +440,9 @@ struct cpp_options /* True means error callback should be used for diagnostics. */ bool client_diagnostic; + + /* True disables tokenization outside of preprocessing directives. */ + bool directives_only; }; /* Callback for header lookup for HEADER, which is the name of a @@ -644,6 +647,10 @@ extern struct deps *cpp_get_deps (cpp_reader *); too. If there was an error opening the file, it returns NULL. */ extern const char *cpp_read_main_file (cpp_reader *, const char *); +/* Set up built-ins with special behavior. Use cpp_init_builtins() + instead unless your know what you are doing. */ +extern void cpp_init_special_builtins (cpp_reader *); + /* Set up built-ins like __FILE__. */ extern void cpp_init_builtins (cpp_reader *, int); diff --git a/contrib/gcclibs/libcpp/init.c b/contrib/gcclibs/libcpp/init.c index 8280f2f..248d84f 100644 --- a/contrib/gcclibs/libcpp/init.c +++ b/contrib/gcclibs/libcpp/init.c @@ -348,11 +348,8 @@ mark_named_operators (cpp_reader *pfile) } } -/* Read the builtins table above and enter them, and language-specific - macros, into the hash table. HOSTED is true if this is a hosted - environment. */ void -cpp_init_builtins (cpp_reader *pfile, int hosted) +cpp_init_special_builtins (cpp_reader *pfile) { const struct builtin *b; size_t n = ARRAY_SIZE (builtin_array); @@ -361,10 +358,7 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) n -= 2; else if (! CPP_OPTION (pfile, stdc_0_in_system_headers) || CPP_OPTION (pfile, std)) - { - n--; - _cpp_define_builtin (pfile, "__STDC__ 1"); - } + n--; for (b = builtin_array; b < builtin_array + n; b++) { @@ -373,6 +367,20 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) hp->flags |= NODE_BUILTIN | NODE_WARN; hp->value.builtin = (enum builtin_type) b->value; } +} + +/* Read the builtins table above and enter them, and language-specific + macros, into the hash table. HOSTED is true if this is a hosted + environment. */ +void +cpp_init_builtins (cpp_reader *pfile, int hosted) +{ + cpp_init_special_builtins (pfile); + + if (!CPP_OPTION (pfile, traditional) + && (! CPP_OPTION (pfile, stdc_0_in_system_headers) + || CPP_OPTION (pfile, std))) + _cpp_define_builtin (pfile, "__STDC__ 1"); if (CPP_OPTION (pfile, cplusplus)) _cpp_define_builtin (pfile, "__cplusplus 1"); @@ -620,7 +628,8 @@ post_options (cpp_reader *pfile) preprocessed text. Read preprocesed source in ISO mode. */ if (CPP_OPTION (pfile, preprocessed)) { - pfile->state.prevent_expansion = 1; + if (!CPP_OPTION (pfile, directives_only)) + pfile->state.prevent_expansion = 1; CPP_OPTION (pfile, traditional) = 0; } diff --git a/contrib/gcclibs/libcpp/internal.h b/contrib/gcclibs/libcpp/internal.h index addff61..ebc2ca9 100644 --- a/contrib/gcclibs/libcpp/internal.h +++ b/contrib/gcclibs/libcpp/internal.h @@ -355,6 +355,10 @@ struct cpp_reader struct file_hash_entry *file_hash_entries; unsigned int file_hash_entries_allocated, file_hash_entries_used; + /* Negative path lookup hash table. */ + struct htab *nonexistent_file_hash; + struct obstack nonexistent_file_ob; + /* Nonzero means don't look for #include "foo" the source-file directory. */ bool quote_ignores_source_dir; @@ -563,6 +567,17 @@ extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *, unsigned int, unsigned int); extern void _cpp_pop_buffer (cpp_reader *); +/* In directives.c */ +struct _cpp_dir_only_callbacks +{ + /* Called to print a block of lines. */ + void (*print_lines) (int, const void *, size_t); + void (*maybe_print_line) (source_location); +}; + +extern void _cpp_preprocess_dir_only (cpp_reader *, + const struct _cpp_dir_only_callbacks *); + /* In traditional.c. */ extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *); extern bool _cpp_read_logical_line_trad (cpp_reader *); diff --git a/contrib/gcclibs/libcpp/lex.c b/contrib/gcclibs/libcpp/lex.c index df09bd6..ef59f900 100644 --- a/contrib/gcclibs/libcpp/lex.c +++ b/contrib/gcclibs/libcpp/lex.c @@ -111,31 +111,39 @@ _cpp_clean_line (cpp_reader *pfile) if (!buffer->from_stage3) { + const uchar *pbackslash = NULL; + /* Short circuit for the common case of an un-escaped line with no trigraphs. The primary win here is by not writing any data back to memory until we have to. */ for (;;) { c = *++s; - if (c == '\n' || c == '\r') + if (__builtin_expect (c == '\n', false) + || __builtin_expect (c == '\r', false)) { d = (uchar *) s; - if (s == buffer->rlimit) + if (__builtin_expect (s == buffer->rlimit, false)) goto done; /* DOS line ending? */ - if (c == '\r' && s[1] == '\n') - s++; + if (__builtin_expect (c == '\r', false) + && s[1] == '\n') + { + s++; + if (s == buffer->rlimit) + goto done; + } - if (s == buffer->rlimit) + if (__builtin_expect (pbackslash == NULL, true)) goto done; - /* check for escaped newline */ + /* Check for escaped newline. */ p = d; - while (p != buffer->next_line && is_nvspace (p[-1])) + while (is_nvspace (p[-1])) p--; - if (p == buffer->next_line || p[-1] != '\\') + if (p - 1 != pbackslash) goto done; /* Have an escaped newline; process it and proceed to @@ -145,7 +153,11 @@ _cpp_clean_line (cpp_reader *pfile) buffer->next_line = p - 1; break; } - if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) + if (__builtin_expect (c == '\\', false)) + pbackslash = s; + else if (__builtin_expect (c == '?', false) + && __builtin_expect (s[1] == '?', false) + && _cpp_trigraph_map[s[2]]) { /* Have a trigraph. We may or may not have to convert it. Add a line note regardless, for -Wtrigraphs. */ @@ -754,6 +766,11 @@ _cpp_lex_token (cpp_reader *pfile) pfile->cur_run = next_tokenrun (pfile->cur_run); pfile->cur_token = pfile->cur_run->base; } + /* We assume that the current token is somewhere in the current + run. */ + if (pfile->cur_token < pfile->cur_run->base + || pfile->cur_token >= pfile->cur_run->limit) + abort (); if (pfile->lookaheads) { @@ -835,11 +852,8 @@ _cpp_get_fresh_line (cpp_reader *pfile) && buffer->next_line > buffer->rlimit && !buffer->from_stage3) { - /* Only warn once. */ + /* Clip to buffer size. */ buffer->next_line = buffer->rlimit; - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, - CPP_BUF_COLUMN (buffer, buffer->cur), - "no newline at end of file"); } return_at_eof = buffer->return_at_eof; diff --git a/contrib/gcclibs/libcpp/macro.c b/contrib/gcclibs/libcpp/macro.c index 1eec578..e9d4681 100644 --- a/contrib/gcclibs/libcpp/macro.c +++ b/contrib/gcclibs/libcpp/macro.c @@ -1,6 +1,7 @@ /* Part of CPP library. (Macro and #define handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006 Free Software Foundation, Inc. Written by Per Bothner, 1994. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -264,6 +265,9 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) break; case BT_COUNTER: + if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive) + cpp_error (pfile, CPP_DL_ERROR, + "__COUNTER__ expanded inside directive with -fdirectives-only"); number = pfile->nextcounter++; break; } @@ -435,19 +439,18 @@ static bool paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) { unsigned char *buf, *end, *lhsend; - const cpp_token *lhs; + cpp_token *lhs; unsigned int len; - lhs = *plhs; - len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1; + len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1; buf = (unsigned char *) alloca (len); - end = lhsend = cpp_spell_token (pfile, lhs, buf, false); + end = lhsend = cpp_spell_token (pfile, *plhs, buf, false); /* Avoid comment headers, since they are still processed in stage 3. It is simpler to insert a space here, rather than modifying the lexer to ignore comments in some circumstances. Simply returning false doesn't work, since we want to clear the PASTE_LEFT flag. */ - if (lhs->type == CPP_DIV && rhs->type != CPP_EQ) + if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) *end++ = ' '; end = cpp_spell_token (pfile, rhs, end, false); *end = '\n'; @@ -457,13 +460,22 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); - *plhs = _cpp_lex_direct (pfile); + lhs = _cpp_lex_direct (pfile); if (pfile->buffer->cur != pfile->buffer->rlimit) { + source_location saved_loc = lhs->src_loc; + _cpp_pop_buffer (pfile); _cpp_backup_tokens (pfile, 1); *lhsend = '\0'; + /* We have to remove the PASTE_LEFT flag from the old lhs, but + we want to keep the new location. */ + *lhs = **plhs; + *plhs = lhs; + lhs->src_loc = saved_loc; + lhs->flags &= ~PASTE_LEFT; + /* Mandatory error for all apart from assembler. */ if (CPP_OPTION (pfile, lang) != CLK_ASM) cpp_error (pfile, CPP_DL_ERROR, @@ -472,6 +484,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) return false; } + *plhs = lhs; _cpp_pop_buffer (pfile); return true; } @@ -1402,10 +1415,12 @@ alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro) static cpp_token * lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) { - cpp_token *token; + cpp_token *token, *saved_cur_token; + saved_cur_token = pfile->cur_token; pfile->cur_token = alloc_expansion_token (pfile, macro); token = _cpp_lex_direct (pfile); + pfile->cur_token = saved_cur_token; /* Is this a parameter? */ if (token->type == CPP_NAME @@ -1594,18 +1609,12 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ok = _cpp_create_trad_definition (pfile, macro); else { - cpp_token *saved_cur_token = pfile->cur_token; - ok = create_iso_definition (pfile, macro); - /* Restore lexer position because of games lex_expansion_token() - plays lexing the macro. We set the type for SEEN_EOL() in - directives.c. + /* We set the type for SEEN_EOL() in directives.c. Longer term we should lex the whole line before coming here, and just copy the expansion. */ - saved_cur_token[-1].type = pfile->cur_token[-1].type; - pfile->cur_token = saved_cur_token; /* Stop the lexer accepting __VA_ARGS__. */ pfile->state.va_args_ok = 0; diff --git a/contrib/gcclibs/libcpp/pch.c b/contrib/gcclibs/libcpp/pch.c index cc23b4e..624befd 100644 --- a/contrib/gcclibs/libcpp/pch.c +++ b/contrib/gcclibs/libcpp/pch.c @@ -35,14 +35,14 @@ static int write_defs (cpp_reader *, cpp_hashnode *, void *); static int save_macros (cpp_reader *, cpp_hashnode *, void *); /* This structure represents a macro definition on disk. */ -struct macrodef_struct +struct macrodef_struct { unsigned int definition_length; unsigned short name_length; unsigned short flags; }; -/* This is how we write out a macro definition. +/* This is how we write out a macro definition. Suitable for being called by cpp_forall_identifiers. */ static int @@ -54,7 +54,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) case NT_VOID: if (! (hn->flags & NODE_POISONED)) return 1; - + case NT_MACRO: if ((hn->flags & NODE_BUILTIN)) return 1; @@ -76,7 +76,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) defn = NODE_NAME (hn); s.definition_length = s.name_length; } - + if (fwrite (&s, sizeof (s), 1, f) != 1 || fwrite (defn, 1, s.definition_length, f) != s.definition_length) { @@ -86,7 +86,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) } } return 1; - + case NT_ASSERTION: /* Not currently implemented. */ return 1; @@ -123,7 +123,7 @@ static int save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) { struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; - + if (hn->type != NT_VOID) { struct cpp_string news; @@ -136,7 +136,7 @@ save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) { struct cpp_string *sp; unsigned char *text; - + sp = XNEW (struct cpp_string); *slot = sp; @@ -157,7 +157,7 @@ hashmem (const void *p_p, size_t sz) const unsigned char *p = (const unsigned char *)p_p; size_t i; hashval_t h; - + h = 0; for (i = 0; i < sz; i++) h = h * 67 - (*p++ - 113); @@ -194,10 +194,10 @@ cpp_save_state (cpp_reader *r, FILE *f) { /* Save the list of non-void identifiers for the dependency checking. */ r->savedstate = XNEW (struct cpp_savedstate); - r->savedstate->definedhash = htab_create (100, cpp_string_hash, + r->savedstate->definedhash = htab_create (100, cpp_string_hash, cpp_string_eq, NULL); cpp_forall_identifiers (r, save_idents, r->savedstate); - + /* Write out the list of defined identifiers. */ cpp_forall_identifiers (r, write_macdef, f); @@ -210,20 +210,20 @@ static int count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) { struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; - + switch (hn->type) { case NT_MACRO: if (hn->flags & NODE_BUILTIN) return 1; - + /* else fall through. */ case NT_VOID: { struct cpp_string news; void **slot; - + news.len = NODE_LEN (hn); news.text = NODE_NAME (hn); slot = (void **) htab_find (ss->definedhash, &news); @@ -249,20 +249,20 @@ static int write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) { struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; - + switch (hn->type) { case NT_MACRO: if (hn->flags & NODE_BUILTIN) return 1; - + /* else fall through. */ case NT_VOID: { struct cpp_string news; void **slot; - + news.len = NODE_LEN (hn); news.text = NODE_NAME (hn); slot = (void **) htab_find (ss->definedhash, &news); @@ -303,7 +303,7 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f) struct cpp_savedstate *const ss = r->savedstate; unsigned char *definedstrs; size_t i; - + /* Collect the list of identifiers which have been seen and weren't defined to anything previously. */ ss->hashsize = 0; @@ -404,7 +404,7 @@ collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, with the preprocessor's current definitions. It will be consistent when: - - anything that was defined just before the PCH was generated + - anything that was defined just before the PCH was generated is defined the same way now; and - anything that was not defined then, but is defined now, was not used by the PCH. @@ -430,10 +430,10 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) { cpp_hashnode *h; const unsigned char *newdefn; - + if (read (fd, &m, sizeof (m)) != sizeof (m)) goto error; - + if (m.name_length == 0) break; @@ -453,10 +453,10 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) namebuf = XNEWVEC (unsigned char, namebufsz); } - if ((size_t)read (fd, namebuf, m.definition_length) + if ((size_t)read (fd, namebuf, m.definition_length) != m.definition_length) goto error; - + h = cpp_lookup (r, namebuf, m.name_length); if (m.flags & NODE_POISONED || h->type != NT_MACRO @@ -470,7 +470,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) } newdefn = cpp_macro_definition (r, h); - + if (m.definition_length != ustrlen (newdefn) || memcmp (namebuf, newdefn, m.definition_length) != 0) { @@ -498,17 +498,17 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) nl.defs = XNEWVEC (cpp_hashnode *, nl.asize); cpp_forall_identifiers (r, &collect_ht_nodes, &nl); qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); - + /* Loop through nl.defs and undeftab, both of which are sorted lists. There should be no matches. */ first = undeftab; last = undeftab + m.definition_length; i = 0; - + while (first < last && i < nl.n_defs) { int cmp = ustrcmp (first, NODE_NAME (nl.defs[i])); - + if (cmp < 0) first += ustrlen (first) + 1; else if (cmp > 0) @@ -516,13 +516,13 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) else { if (CPP_OPTION (r, warn_invalid_pch)) - cpp_error (r, CPP_DL_WARNING_SYSHDR, + cpp_error (r, CPP_DL_WARNING_SYSHDR, "%s: not used because `%s' is defined", name, first); goto fail; } } - + free(nl.defs); free (undeftab); @@ -545,7 +545,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) /* Save all the existing macros. */ -struct save_macro_data +struct save_macro_data { uchar **defns; size_t count; @@ -567,7 +567,7 @@ struct save_macro_data file were not saved in this way, but this is not done (yet), except for builtins, and for #assert by default. */ -static int +static int save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) { struct save_macro_data *data = (struct save_macro_data *)data_p; @@ -577,9 +577,9 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) if (data->count == data->array_size) { data->array_size *= 2; - data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); + data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); } - + switch (h->type) { case NT_ASSERTION: @@ -596,7 +596,7 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) data->defns[data->count][defnlen] = '\n'; } break; - + default: abort (); } @@ -612,7 +612,7 @@ void cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) { struct save_macro_data *d = XNEW (struct save_macro_data); - + d->array_size = 512; d->defns = XNEWVEC (uchar *, d->array_size); d->count = 0; @@ -622,7 +622,7 @@ cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) } /* Given a precompiled header that was previously determined to be valid, - apply all its definitions (and undefinitions) to the current state. + apply all its definitions (and undefinitions) to the current state. DEPNAME is passed to deps_restore. */ int @@ -632,7 +632,7 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f, size_t i; struct lexer_state old_state; - /* Restore spec_nodes, which will be full of references to the old + /* Restore spec_nodes, which will be full of references to the old hashtable entries and so will now be invalid. */ { struct spec_nodes *s = &r->spec_nodes; @@ -691,7 +691,7 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f, goto error; return 0; - + error: cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); return -1; |