aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog38
-rw-r--r--gcc/cppexp.c62
-rw-r--r--gcc/cppfiles.c89
-rw-r--r--gcc/cpplib.c93
-rw-r--r--gcc/cpplib.h33
5 files changed, 181 insertions, 134 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 84a79ba..f2f0aaf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,41 @@
+1998-11-26 01:17 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * cpplib.h (struct cpp_buffer): Replace dir and dlen members
+ with a struct file_name_list pointer.
+ (struct cpp_reader): Add pointer to chain of `actual
+ directory' include searchpath entries.
+ (struct file_name_list): Add *alloc pointer for the sake of
+ the actual-directory chain.
+
+ Move definition of HOST_WIDE_INT here.
+ (cpp_parse_escape): Change prototype to match changes in
+ cppexp.c.
+
+ * cppfiles.c (actual_directory): New function.
+ (finclude): Use it to initialize the buffer's actual_dir
+ entry.
+ (find_include_file): We don't need to fix up max_include_len
+ here.
+
+ * cpplib.c (do_include): Don't allocate a file_name_list on
+ the fly for current directory "" includes, use the one that's
+ been preallocated in pfile->buffer->actual_dir. Hoist out
+ duplicate code from the search_start selection logic.
+ (cpp_reader_init): Initialize pfile->actual_dirs.
+
+ Remove definition of HOST_WIDE_INT. Change calls
+ to cpp_parse_escape to match changes in cppexp.c (note
+ hardcoded MASK, which is safe since this is the source
+ character set).
+
+ * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c
+ to handle wide character constants in #if directives. The
+ function now returns a HOST_WIDE_INT, and takes a third
+ argument which is a binary mask for all legal values (0x00ff
+ for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.) Define
+ MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK. Change callers of
+ cpp_parse_escape to match. [Fixes c-torture/execute/widechar-1.c]
+
Mon Dec 7 15:38:25 1998 Dave Brolley <brolley@cygnus.com>
* gcc.c (default_compilers): Fix typo in USE_CPPLIB spec for cc1.
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 419e5bd..87b84a6 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -72,6 +72,14 @@ struct arglist {
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+ ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDE_INT) 0)
+
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+ ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+ : ~ (HOST_WIDE_INT) 0)
+
/* Yield nonzero if adding two numbers with A's and B's signs can yield a
number with SUM's sign, where A, B, and SUM are all C integers. */
#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
@@ -101,28 +109,6 @@ static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long));
#define SKIP_OPERAND 8
/*#define UNSIGNEDP 16*/
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
- && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
- || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
-
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
@@ -275,7 +261,7 @@ cpp_lex (pfile, skip_evaluation)
cpp_reader *pfile;
int skip_evaluation;
{
- register int c;
+ register HOST_WIDE_INT c;
register struct token *toktab;
enum cpp_token token;
struct operation op;
@@ -359,7 +345,9 @@ cpp_lex (pfile, skip_evaluation)
{
if (c == '\\')
{
- c = cpp_parse_escape (pfile, (char **) &ptr);
+ c = cpp_parse_escape (pfile, (char **) &ptr,
+ wide_flag ? MAX_WCHAR_TYPE_MASK
+ : MAX_CHAR_TYPE_MASK);
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= (unsigned)(1 << width))
cpp_pedwarn (pfile,
@@ -480,10 +468,11 @@ cpp_lex (pfile, skip_evaluation)
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
-int
-cpp_parse_escape (pfile, string_ptr)
+HOST_WIDE_INT
+cpp_parse_escape (pfile, string_ptr, result_mask)
cpp_reader *pfile;
char **string_ptr;
+ HOST_WIDE_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@@ -494,7 +483,7 @@ cpp_parse_escape (pfile, string_ptr)
return TARGET_BS;
case 'e':
case 'E':
- if (CPP_PEDANTIC (pfile))
+ if (CPP_OPTIONS (pfile)->pedantic)
cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
return 033;
case 'f':
@@ -522,7 +511,7 @@ cpp_parse_escape (pfile, string_ptr)
case '6':
case '7':
{
- register int i = c - '0';
+ register HOST_WIDE_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@@ -535,17 +524,17 @@ cpp_parse_escape (pfile, string_ptr)
break;
}
}
- if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
+ if (i != (i & result_mask))
{
- i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
- cpp_pedwarn (pfile,
- "octal character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "octal escape sequence out of range");
}
return i;
}
case 'x':
{
- register unsigned i = 0, overflow = 0, digits_found = 0, digit;
+ register unsigned HOST_WIDE_INT i = 0, overflow = 0;
+ register int digits_found = 0, digit;
for (;;)
{
c = *(*string_ptr)++;
@@ -566,11 +555,10 @@ cpp_parse_escape (pfile, string_ptr)
}
if (!digits_found)
cpp_error (pfile, "\\x used with no following hex digits");
- if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
+ if (overflow | (i != (i & result_mask)))
{
- i &= (1 << BITS_PER_UNIT) - 1;
- cpp_pedwarn (pfile,
- "hex character constant does not fit in a byte");
+ i &= result_mask;
+ cpp_pedwarn (pfile, "hex escape sequence out of range");
}
return i;
}
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 8a4a0ef..8c01cdd 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -42,6 +42,7 @@ static char *remap_filename PROTO ((cpp_reader *, char *,
struct file_name_list *));
static long safe_read PROTO ((int, char *, int));
static void simplify_pathname PROTO ((char *));
+static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
#if 0
static void hack_vms_include_specification PROTO ((char *));
@@ -422,11 +423,6 @@ find_include_file (pfile, fname, search_start, ihash, before)
/* Search directory path, trying to open the file. */
- /* The first entry in the search list may be a buffer-specific entry,
- and its directory name may be longer than max_include_len. Adjust
- as appropriate. */
- if (pfile->max_include_len < search_start->nlen)
- pfile->max_include_len = search_start->nlen;
len = strlen (fname);
name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
@@ -690,34 +686,11 @@ finclude (pfile, fd, ihash)
fp->colno = 1;
fp->cleanup = file_cleanup;
- /* The ->dir field is only used when ignore_srcdir is not in effect;
+ /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
see do_include */
if (!CPP_OPTIONS (pfile)->ignore_srcdir)
- {
- char *last_slash;
- fp->dir = savestring (fp->fname);
- last_slash = rindex (fp->dir, '/');
- if (last_slash)
- {
- if (last_slash == fp->dir)
- {
- fp->dlen = 1;
- last_slash[1] = '\0';
- }
- else
- {
- fp->dlen = last_slash - fp->dir;
- *last_slash = '\0';
- }
- }
- else
- {
- fp->dir[0] = '.';
- fp->dir[1] = '\0';
- fp->dlen = 1;
- }
- }
-
+ fp->actual_dir = actual_directory (pfile, fp->fname);
+
if (S_ISREG (st.st_mode))
{
st_size = (size_t) st.st_size;
@@ -790,6 +763,60 @@ finclude (pfile, fd, ihash)
return 0;
}
+static struct file_name_list *
+actual_directory (pfile, fname)
+ cpp_reader *pfile;
+ char *fname;
+{
+ char *last_slash, *dir;
+ size_t dlen;
+ struct file_name_list *x;
+
+ dir = savestring (fname);
+ last_slash = rindex (dir, '/');
+ if (last_slash)
+ {
+ if (last_slash == dir)
+ {
+ dlen = 1;
+ last_slash[1] = '\0';
+ }
+ else
+ {
+ dlen = last_slash - dir;
+ *last_slash = '\0';
+ }
+ }
+ else
+ {
+ dir[0] = '.';
+ dir[1] = '\0';
+ dlen = 1;
+ }
+
+ if (dlen > pfile->max_include_len)
+ pfile->max_include_len = dlen;
+
+ for (x = pfile->actual_dirs; x; x = x->alloc)
+ if (!strcmp (x->name, dir))
+ {
+ free (dir);
+ return x;
+ }
+
+ /* Not found, make a new one. */
+ x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
+ x->name = dir;
+ x->nlen = dlen;
+ x->next = CPP_OPTIONS (pfile)->quote_include;
+ x->alloc = pfile->actual_dirs;
+ x->sysp = 0;
+ x->name_map = NULL;
+
+ pfile->actual_dirs = x;
+ return x;
+}
+
/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
retrying if necessary. If MAX_READ_LEN is defined, read at most
that bytes at a time. Return a negative value if an error occurs,
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index a9bb550..dbdf2f4 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -50,27 +50,6 @@ extern char *update_path PARAMS ((char *, char *));
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
-/* Find the largest host integer type and set its size and type.
- Watch out: on some crazy hosts `long' is shorter than `int'. */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# define HOST_WIDE_INT intmax_t
-# else
-# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
- && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-# define HOST_WIDE_INT int
-# else
-# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
- || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-# define HOST_WIDE_INT long
-# else
-# define HOST_WIDE_INT long long
-# endif
-# endif
-# endif
-#endif
/* By default, colon separates directories in a path. */
#ifndef PATH_SEPARATOR
@@ -2932,7 +2911,7 @@ do_include (pfile, keyword, unused1, unused2)
int before; /* included before? */
long flen;
char *fbeg, *fend;
- struct file_name_list *srcdir = 0; /* for "" includes */
+ cpp_buffer *fp;
enum cpp_token token;
@@ -3015,48 +2994,39 @@ do_include (pfile, keyword, unused1, unused2)
cpp_error (pfile, "empty file name in `#%s'", keyword->name);
return 0;
}
+
+ search_start = 0;
+
+ for (fp = CPP_BUFFER (pfile);
+ fp != CPP_NULL_BUFFER (pfile);
+ fp = CPP_PREV_BUFFER (fp))
+ if (fp->fname != NULL)
+ break;
+
+ if (fp == CPP_NULL_BUFFER (pfile))
+ fp = NULL;
/* For #include_next, skip in the search path
past the dir in which the containing file was found. */
if (skip_dirs)
{
- cpp_buffer *fp = CPP_BUFFER (pfile);
- for (; fp != CPP_NULL_BUFFER (pfile); fp = CPP_PREV_BUFFER (fp))
- if (fp->fname != NULL)
- {
- /* Don't skip anything if the containing file was found
- by an absolute path. */
- if (fp->ihash->foundhere == ABSOLUTE_PATH)
- search_start = angle_brackets
- ? CPP_OPTIONS (pfile)->bracket_include
- : CPP_OPTIONS (pfile)->quote_include;
- else
- search_start = fp->ihash->foundhere->next;
- break;
- }
+ if (fp)
+ search_start = fp->ihash->foundhere->next;
}
else
- search_start = angle_brackets
- ? CPP_OPTIONS (pfile)->bracket_include
- : CPP_OPTIONS (pfile)->quote_include;
-
- /* For "" includes when ignore_srcdir is off, tack the actual directory
- of the current file onto the beginning of the search path.
- The block must be permanently allocated since it may wind up
- in the include hash. */
- if (!angle_brackets
- && search_start == CPP_OPTIONS (pfile)->quote_include
- && !CPP_OPTIONS (pfile)->ignore_srcdir)
{
- srcdir = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
- srcdir->next = CPP_OPTIONS (pfile)->quote_include;
- srcdir->name = CPP_BUFFER (pfile)->dir;
- srcdir->nlen = CPP_BUFFER (pfile)->dlen;
- srcdir->sysp = 0;
- srcdir->name_map = NULL;
-
- search_start = srcdir;
+ if (angle_brackets)
+ search_start = CPP_OPTIONS (pfile)->bracket_include;
+ else
+ {
+ if (!CPP_OPTIONS (pfile)->ignore_srcdir)
+ {
+ if (fp)
+ search_start = fp->actual_dir;
+ }
+ else
+ search_start = CPP_OPTIONS (pfile)->quote_include;
+ }
}
if (!search_start)
@@ -3067,10 +3037,6 @@ do_include (pfile, keyword, unused1, unused2)
fd = find_include_file (pfile, fbeg, search_start, &ihash, &before);
- if (srcdir
- && (ihash == (struct include_hash *)-1 || srcdir != ihash->foundhere))
- free (srcdir);
-
if (fd == -2)
return 0;
@@ -3128,8 +3094,8 @@ do_include (pfile, keyword, unused1, unused2)
/* Handle -H option. */
if (CPP_OPTIONS(pfile)->print_include_names)
{
- cpp_buffer *buf = CPP_BUFFER (pfile);
- while ((buf = CPP_PREV_BUFFER (buf)) != CPP_NULL_BUFFER (pfile))
+ fp = CPP_BUFFER (pfile);
+ while ((fp = CPP_PREV_BUFFER (fp)) != CPP_NULL_BUFFER (pfile))
putc ('.', stderr);
fprintf (stderr, " %s\n", ihash->name);
}
@@ -3282,7 +3248,7 @@ convert_string (pfile, result, in, limit, handle_escapes)
if (handle_escapes)
{
char *bpc = (char *) in;
- int i = (U_CHAR) cpp_parse_escape (pfile, &bpc);
+ int i = (U_CHAR) cpp_parse_escape (pfile, &bpc, 0x00ffU);
in = (U_CHAR *) bpc;
if (i >= 0)
*result++ = (U_CHAR)c;
@@ -5380,6 +5346,7 @@ cpp_reader_init (pfile)
pfile->timebuf = NULL;
pfile->only_seen_white = 1;
pfile->buffer = CPP_NULL_BUFFER(pfile);
+ pfile->actual_dirs = NULL;
}
static struct cpp_pending *
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index fe28102..3cb2753 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -110,8 +110,7 @@ struct cpp_buffer {
/* Filename specified with #line command. */
char *nominal_fname;
/* Actual directory of this file, used only for "" includes */
- char *dir;
- size_t dlen;
+ struct file_name_list *actual_dir;
/* Pointer into the include hash table. Used for include_next and
to record control macros.
@@ -182,6 +181,10 @@ struct cpp_reader {
#define ALL_INCLUDE_HASHSIZE 71
struct include_hash *all_include_files[ALL_INCLUDE_HASHSIZE];
+ /* Chain of `actual directory' file_name_list entries,
+ for "" inclusion. */
+ struct file_name_list *actual_dirs;
+
/* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */
unsigned int max_include_len;
@@ -485,6 +488,8 @@ struct cpp_options {
struct file_name_list
{
struct file_name_list *next;
+ struct file_name_list *alloc; /* for the cache of
+ current directory entries */
char *name;
unsigned int nlen;
/* We use these to tell if the directory mentioned here is a duplicate
@@ -656,6 +661,28 @@ struct if_stack {
};
typedef struct if_stack IF_STACK_FRAME;
+/* Find the largest host integer type and set its size and type.
+ Watch out: on some crazy hosts `long' is shorter than `int'. */
+
+#ifndef HOST_WIDE_INT
+# if HAVE_INTTYPES_H
+# include <inttypes.h>
+# define HOST_WIDE_INT intmax_t
+# else
+# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
+ && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
+# define HOST_WIDE_INT int
+# else
+# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
+ || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
+# define HOST_WIDE_INT long
+# else
+# define HOST_WIDE_INT long long
+# endif
+# endif
+# endif
+#endif
+
extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *));
extern void cpp_define PARAMS ((cpp_reader*, unsigned char *));
@@ -678,7 +705,7 @@ extern void cpp_perror_with_name PROTO ((cpp_reader *, const char *));
extern void v_cpp_message PROTO ((cpp_reader *, int, const char *, va_list));
extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
-extern int cpp_parse_escape PARAMS ((cpp_reader *, char **));
+extern HOST_WIDE_INT cpp_parse_escape PARAMS ((cpp_reader *, char **, HOST_WIDE_INT));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
unsigned char *, long));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));