From 156f898b7ee419e0956fc06f191625033a27b0c4 Mon Sep 17 00:00:00 2001 From: borutr Date: Mon, 31 Mar 2008 18:10:22 +0000 Subject: [PATCH] * support/cpp2 renamed to support/cpp * support/cpp2/libiberty/filenames.h, support/cpp2/libiberty/hex.c, support/cpp2/libiberty/splay-tree.c, support/cpp2/libiberty/splay-tree.h, support/cpp2/libcpp/macro.c, support/cpp2/libcpp/directives.c, support/cpp2/libcpp/include/cpplib.h, support/cpp2/libcpp/include/symtab.h, support/cpp2/libcpp/include/line-map.h, support/cpp2/libcpp/line-map.c, support/cpp2/libcpp/files.c, support/cpp2/libcpp/init.c, support/cpp2/libcpp/traditional.c, support/cpp2/libcpp/expr.c, support/cpp2/libcpp/internal.h, support/cpp2/libcpp/lex.c, support/cpp2/libcpp/system.h, support/cpp2/libcpp/charset.c: SDCPP synchronized with GCC CPP release version 4.3.0 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5132 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 17 + support/{cpp2 => cpp}/Makefile.bcc | 0 support/{cpp2 => cpp}/Makefile.in | 0 support/{cpp2 => cpp}/acconfig.h | 0 support/{cpp2 => cpp}/aclocal.m4 | 0 support/{cpp2 => cpp}/ansidecl.h | 0 support/{cpp2 => cpp}/auto-host_vc_in.h | 0 support/{cpp2 => cpp}/c-incpath.c | 0 support/{cpp2 => cpp}/c-incpath.h | 0 support/{cpp2 => cpp}/c-ppoutput.c | 0 support/{cpp2 => cpp}/config.h | 0 support/{cpp2 => cpp}/config.in | 0 support/{cpp2 => cpp}/configure | 0 support/{cpp2 => cpp}/configure.in | 0 support/{cpp2 => cpp}/cppdefault.c | 0 support/{cpp2 => cpp}/cppdefault.h | 0 support/{cpp2 => cpp}/except.h | 0 support/{cpp2 => cpp}/hwint.h | 0 support/{cpp2 => cpp}/intl.h | 0 support/{cpp2 => cpp}/libcpp/charset.c | 501 +++--- support/{cpp2 => cpp}/libcpp/directives.c | 922 +++++----- support/{cpp2 => cpp}/libcpp/errors.c | 0 support/{cpp2 => cpp}/libcpp/expr.c | 1165 +++++++------ support/{cpp2 => cpp}/libcpp/files.c | 679 +++++--- support/{cpp2 => cpp}/libcpp/identifiers.c | 0 .../libcpp/include/cpp-id-data.h | 0 support/{cpp2 => cpp}/libcpp/include/cpplib.h | 376 +++-- .../{cpp2 => cpp}/libcpp/include/line-map.h | 27 +- support/{cpp2 => cpp}/libcpp/include/mkdeps.h | 0 support/{cpp2 => cpp}/libcpp/include/symtab.h | 12 +- support/{cpp2 => cpp}/libcpp/init.c | 182 +- support/{cpp2 => cpp}/libcpp/internal.h | 124 +- support/{cpp2 => cpp}/libcpp/lex.c | 1084 ++++++------ support/{cpp2 => cpp}/libcpp/line-map.c | 147 +- support/{cpp2 => cpp}/libcpp/macro.c | 1486 +++++++++-------- support/{cpp2 => cpp}/libcpp/mkdeps.c | 0 support/{cpp2 => cpp}/libcpp/symtab.c | 0 support/{cpp2 => cpp}/libcpp/system.h | 2 +- support/{cpp2 => cpp}/libcpp/traditional.c | 910 +++++----- support/{cpp2 => cpp}/libcpp/ucnid.h | 0 support/{cpp2 => cpp}/libiberty.h | 0 support/{cpp2 => cpp}/libiberty/concat.c | 0 support/{cpp2 => cpp}/libiberty/filenames.h | 15 +- .../{cpp2 => cpp}/libiberty/fopen_unlocked.c | 0 support/{cpp2 => cpp}/libiberty/getpwd.c | 0 support/{cpp2 => cpp}/libiberty/hashtab.c | 0 support/{cpp2 => cpp}/libiberty/hashtab.h | 0 support/{cpp2 => cpp}/libiberty/hex.c | 48 +- support/{cpp2 => cpp}/libiberty/lbasename.c | 0 support/{cpp2 => cpp}/libiberty/md5.c | 0 support/{cpp2 => cpp}/libiberty/obstack.c | 0 support/{cpp2 => cpp}/libiberty/obstack.h | 0 support/{cpp2 => cpp}/libiberty/safe-ctype.c | 0 support/{cpp2 => cpp}/libiberty/safe-ctype.h | 0 support/{cpp2 => cpp}/libiberty/splay-tree.c | 164 +- support/{cpp2 => cpp}/libiberty/splay-tree.h | 64 +- support/{cpp2 => cpp}/libiberty/vasprintf.c | 0 support/{cpp2 => cpp}/libiberty/xexit.c | 0 support/{cpp2 => cpp}/libiberty/xmalloc.c | 0 support/{cpp2 => cpp}/libiberty/xmemdup.c | 0 support/{cpp2 => cpp}/libiberty/xstrdup.c | 0 support/{cpp2 => cpp}/libiberty/xstrerror.c | 0 support/{cpp2 => cpp}/md5.h | 0 support/{cpp2 => cpp}/move-if-change | 0 support/{cpp2 => cpp}/opt-functions.awk | 0 support/{cpp2 => cpp}/opt-gather.awk | 0 support/{cpp2 => cpp}/optc-gen.awk | 0 support/{cpp2 => cpp}/opth-gen.awk | 0 support/{cpp2 => cpp}/opts-common.c | 0 support/{cpp2 => cpp}/opts.c | 0 support/{cpp2 => cpp}/opts.h | 0 support/{cpp2 => cpp}/output.h | 0 support/{cpp2 => cpp}/prefix.c | 0 support/{cpp2 => cpp}/prefix.h | 0 support/{cpp2 => cpp}/sdcpp-opts.c | 0 support/{cpp2 => cpp}/sdcpp.c | 0 support/{cpp2 => cpp}/sdcpp.dsp | 0 support/{cpp2 => cpp}/sdcpp.h | 0 support/{cpp2 => cpp}/sdcpp.opt | 0 support/{cpp2 => cpp}/sdcppa.dsp | 0 support/{cpp2 => cpp}/symcat.h | 0 support/{cpp2 => cpp}/system.h | 0 support/{cpp2 => cpp}/version.c | 0 support/{cpp2 => cpp}/version.h | 0 support/{cpp2 => cpp}/win32/dirent.c | 0 support/{cpp2 => cpp}/win32/dirent.h | 0 86 files changed, 4329 insertions(+), 3596 deletions(-) rename support/{cpp2 => cpp}/Makefile.bcc (100%) rename support/{cpp2 => cpp}/Makefile.in (100%) rename support/{cpp2 => cpp}/acconfig.h (100%) rename support/{cpp2 => cpp}/aclocal.m4 (100%) rename support/{cpp2 => cpp}/ansidecl.h (100%) rename support/{cpp2 => cpp}/auto-host_vc_in.h (100%) rename support/{cpp2 => cpp}/c-incpath.c (100%) rename support/{cpp2 => cpp}/c-incpath.h (100%) rename support/{cpp2 => cpp}/c-ppoutput.c (100%) rename support/{cpp2 => cpp}/config.h (100%) rename support/{cpp2 => cpp}/config.in (100%) rename support/{cpp2 => cpp}/configure (100%) rename support/{cpp2 => cpp}/configure.in (100%) rename support/{cpp2 => cpp}/cppdefault.c (100%) rename support/{cpp2 => cpp}/cppdefault.h (100%) rename support/{cpp2 => cpp}/except.h (100%) rename support/{cpp2 => cpp}/hwint.h (100%) rename support/{cpp2 => cpp}/intl.h (100%) rename support/{cpp2 => cpp}/libcpp/charset.c (81%) rename support/{cpp2 => cpp}/libcpp/directives.c (71%) rename support/{cpp2 => cpp}/libcpp/errors.c (100%) rename support/{cpp2 => cpp}/libcpp/expr.c (55%) rename support/{cpp2 => cpp}/libcpp/files.c (72%) rename support/{cpp2 => cpp}/libcpp/identifiers.c (100%) rename support/{cpp2 => cpp}/libcpp/include/cpp-id-data.h (100%) rename support/{cpp2 => cpp}/libcpp/include/cpplib.h (66%) rename support/{cpp2 => cpp}/libcpp/include/line-map.h (92%) rename support/{cpp2 => cpp}/libcpp/include/mkdeps.h (100%) rename support/{cpp2 => cpp}/libcpp/include/symtab.h (89%) rename support/{cpp2 => cpp}/libcpp/init.c (79%) rename support/{cpp2 => cpp}/libcpp/internal.h (85%) rename support/{cpp2 => cpp}/libcpp/lex.c (67%) rename support/{cpp2 => cpp}/libcpp/line-map.c (72%) rename support/{cpp2 => cpp}/libcpp/macro.c (51%) rename support/{cpp2 => cpp}/libcpp/mkdeps.c (100%) rename support/{cpp2 => cpp}/libcpp/symtab.c (100%) rename support/{cpp2 => cpp}/libcpp/system.h (99%) rename support/{cpp2 => cpp}/libcpp/traditional.c (53%) rename support/{cpp2 => cpp}/libcpp/ucnid.h (100%) rename support/{cpp2 => cpp}/libiberty.h (100%) rename support/{cpp2 => cpp}/libiberty/concat.c (100%) rename support/{cpp2 => cpp}/libiberty/filenames.h (79%) rename support/{cpp2 => cpp}/libiberty/fopen_unlocked.c (100%) rename support/{cpp2 => cpp}/libiberty/getpwd.c (100%) rename support/{cpp2 => cpp}/libiberty/hashtab.c (100%) rename support/{cpp2 => cpp}/libiberty/hashtab.h (100%) rename support/{cpp2 => cpp}/libiberty/hex.c (86%) rename support/{cpp2 => cpp}/libiberty/lbasename.c (100%) rename support/{cpp2 => cpp}/libiberty/md5.c (100%) rename support/{cpp2 => cpp}/libiberty/obstack.c (100%) rename support/{cpp2 => cpp}/libiberty/obstack.h (100%) rename support/{cpp2 => cpp}/libiberty/safe-ctype.c (100%) rename support/{cpp2 => cpp}/libiberty/safe-ctype.h (100%) rename support/{cpp2 => cpp}/libiberty/splay-tree.c (81%) rename support/{cpp2 => cpp}/libiberty/splay-tree.h (72%) rename support/{cpp2 => cpp}/libiberty/vasprintf.c (100%) rename support/{cpp2 => cpp}/libiberty/xexit.c (100%) rename support/{cpp2 => cpp}/libiberty/xmalloc.c (100%) rename support/{cpp2 => cpp}/libiberty/xmemdup.c (100%) rename support/{cpp2 => cpp}/libiberty/xstrdup.c (100%) rename support/{cpp2 => cpp}/libiberty/xstrerror.c (100%) rename support/{cpp2 => cpp}/md5.h (100%) rename support/{cpp2 => cpp}/move-if-change (100%) rename support/{cpp2 => cpp}/opt-functions.awk (100%) rename support/{cpp2 => cpp}/opt-gather.awk (100%) rename support/{cpp2 => cpp}/optc-gen.awk (100%) rename support/{cpp2 => cpp}/opth-gen.awk (100%) rename support/{cpp2 => cpp}/opts-common.c (100%) rename support/{cpp2 => cpp}/opts.c (100%) rename support/{cpp2 => cpp}/opts.h (100%) rename support/{cpp2 => cpp}/output.h (100%) rename support/{cpp2 => cpp}/prefix.c (100%) rename support/{cpp2 => cpp}/prefix.h (100%) rename support/{cpp2 => cpp}/sdcpp-opts.c (100%) rename support/{cpp2 => cpp}/sdcpp.c (100%) rename support/{cpp2 => cpp}/sdcpp.dsp (100%) rename support/{cpp2 => cpp}/sdcpp.h (100%) rename support/{cpp2 => cpp}/sdcpp.opt (100%) rename support/{cpp2 => cpp}/sdcppa.dsp (100%) rename support/{cpp2 => cpp}/symcat.h (100%) rename support/{cpp2 => cpp}/system.h (100%) rename support/{cpp2 => cpp}/version.c (100%) rename support/{cpp2 => cpp}/version.h (100%) rename support/{cpp2 => cpp}/win32/dirent.c (100%) rename support/{cpp2 => cpp}/win32/dirent.h (100%) diff --git a/ChangeLog b/ChangeLog index 5ae30138..c8ad5095 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-03-31 Borut Razem + + * support/cpp2 renamed to support/cpp + * support/cpp2/libiberty/filenames.h, support/cpp2/libiberty/hex.c, + support/cpp2/libiberty/splay-tree.c, + support/cpp2/libiberty/splay-tree.h, support/cpp2/libcpp/macro.c, + support/cpp2/libcpp/directives.c, + support/cpp2/libcpp/include/cpplib.h, + support/cpp2/libcpp/include/symtab.h, + support/cpp2/libcpp/include/line-map.h, + support/cpp2/libcpp/line-map.c, support/cpp2/libcpp/files.c, + support/cpp2/libcpp/init.c, support/cpp2/libcpp/traditional.c, + support/cpp2/libcpp/expr.c, support/cpp2/libcpp/internal.h, + support/cpp2/libcpp/lex.c, support/cpp2/libcpp/system.h, + support/cpp2/libcpp/charset.c: SDCPP synchronized with GCC CPP + release version 4.3.0 + 2008-03-31 Frieder Ferlemann * device/include/hc08/mc68hc908jkjl.h: committed fix for bug #1929739, diff --git a/support/cpp2/Makefile.bcc b/support/cpp/Makefile.bcc similarity index 100% rename from support/cpp2/Makefile.bcc rename to support/cpp/Makefile.bcc diff --git a/support/cpp2/Makefile.in b/support/cpp/Makefile.in similarity index 100% rename from support/cpp2/Makefile.in rename to support/cpp/Makefile.in diff --git a/support/cpp2/acconfig.h b/support/cpp/acconfig.h similarity index 100% rename from support/cpp2/acconfig.h rename to support/cpp/acconfig.h diff --git a/support/cpp2/aclocal.m4 b/support/cpp/aclocal.m4 similarity index 100% rename from support/cpp2/aclocal.m4 rename to support/cpp/aclocal.m4 diff --git a/support/cpp2/ansidecl.h b/support/cpp/ansidecl.h similarity index 100% rename from support/cpp2/ansidecl.h rename to support/cpp/ansidecl.h diff --git a/support/cpp2/auto-host_vc_in.h b/support/cpp/auto-host_vc_in.h similarity index 100% rename from support/cpp2/auto-host_vc_in.h rename to support/cpp/auto-host_vc_in.h diff --git a/support/cpp2/c-incpath.c b/support/cpp/c-incpath.c similarity index 100% rename from support/cpp2/c-incpath.c rename to support/cpp/c-incpath.c diff --git a/support/cpp2/c-incpath.h b/support/cpp/c-incpath.h similarity index 100% rename from support/cpp2/c-incpath.h rename to support/cpp/c-incpath.h diff --git a/support/cpp2/c-ppoutput.c b/support/cpp/c-ppoutput.c similarity index 100% rename from support/cpp2/c-ppoutput.c rename to support/cpp/c-ppoutput.c diff --git a/support/cpp2/config.h b/support/cpp/config.h similarity index 100% rename from support/cpp2/config.h rename to support/cpp/config.h diff --git a/support/cpp2/config.in b/support/cpp/config.in similarity index 100% rename from support/cpp2/config.in rename to support/cpp/config.in diff --git a/support/cpp2/configure b/support/cpp/configure similarity index 100% rename from support/cpp2/configure rename to support/cpp/configure diff --git a/support/cpp2/configure.in b/support/cpp/configure.in similarity index 100% rename from support/cpp2/configure.in rename to support/cpp/configure.in diff --git a/support/cpp2/cppdefault.c b/support/cpp/cppdefault.c similarity index 100% rename from support/cpp2/cppdefault.c rename to support/cpp/cppdefault.c diff --git a/support/cpp2/cppdefault.h b/support/cpp/cppdefault.h similarity index 100% rename from support/cpp2/cppdefault.h rename to support/cpp/cppdefault.h diff --git a/support/cpp2/except.h b/support/cpp/except.h similarity index 100% rename from support/cpp2/except.h rename to support/cpp/except.h diff --git a/support/cpp2/hwint.h b/support/cpp/hwint.h similarity index 100% rename from support/cpp2/hwint.h rename to support/cpp/hwint.h diff --git a/support/cpp2/intl.h b/support/cpp/intl.h similarity index 100% rename from support/cpp2/intl.h rename to support/cpp/intl.h diff --git a/support/cpp2/libcpp/charset.c b/support/cpp/libcpp/charset.c similarity index 81% rename from support/cpp2/libcpp/charset.c rename to support/cpp/libcpp/charset.c index 78c89816..847c8b1b 100644 --- a/support/cpp2/libcpp/charset.c +++ b/support/cpp/libcpp/charset.c @@ -1,5 +1,5 @@ /* CPP Library - charsets - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. Broken out of c-lex.c Apr 2003, adding valid C99 UCN ranges. @@ -142,7 +142,7 @@ struct _cpp_strbuf UTF-8 encoding looks like this: - value range encoded as + value range encoded as 00000000-0000007F 0xxxxxxx 00000080-000007FF 110xxxxx 10xxxxxx 00000800-0000FFFF 1110xxxx 10xxxxxx 10xxxxxx @@ -167,7 +167,7 @@ struct _cpp_strbuf operation in several places below. */ static inline int one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp, - cppchar_t *cp) + cppchar_t *cp) { static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 }; static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; @@ -205,7 +205,7 @@ one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp, { cppchar_t n = *inbuf++; if ((n & 0xC0) != 0x80) - return EILSEQ; + return EILSEQ; c = ((c << 6) + (n & 0x3F)); } @@ -240,11 +240,11 @@ one_cppchar_to_utf8 (cppchar_t c, uchar **outbufp, size_t *outbytesleftp) else { do - { - *--p = ((c & 0x3F) | 0x80); - c >>= 6; - nbytes++; - } + { + *--p = ((c & 0x3F) | 0x80); + c >>= 6; + nbytes++; + } while (c >= 0x3F || (c & limits[nbytes-1])); *--p = (c | masks[nbytes-1]); } @@ -278,7 +278,7 @@ one_cppchar_to_utf8 (cppchar_t c, uchar **outbufp, size_t *outbytesleftp) static inline int one_utf8_to_utf32 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, - uchar **outbufp, size_t *outbytesleftp) + uchar **outbufp, size_t *outbytesleftp) { uchar *outbuf; cppchar_t s = 0; @@ -305,7 +305,7 @@ one_utf8_to_utf32 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, static inline int one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, - uchar **outbufp, size_t *outbytesleftp) + uchar **outbufp, size_t *outbytesleftp) { cppchar_t s; int rval; @@ -335,7 +335,7 @@ one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, static inline int one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, - uchar **outbufp, size_t *outbytesleftp) + uchar **outbufp, size_t *outbytesleftp) { int rval; cppchar_t s = 0; @@ -357,11 +357,11 @@ one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, if (s < 0xFFFF) { if (*outbytesleftp < 2) - { - *inbufp = save_inbuf; - *inbytesleftp = save_inbytesleft; - return E2BIG; - } + { + *inbufp = save_inbuf; + *inbytesleftp = save_inbytesleft; + return E2BIG; + } outbuf[bigend ? 1 : 0] = (s & 0x00FF); outbuf[bigend ? 0 : 1] = (s & 0xFF00) >> 8; @@ -374,17 +374,17 @@ one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, cppchar_t hi, lo; if (*outbytesleftp < 4) - { - *inbufp = save_inbuf; - *inbytesleftp = save_inbytesleft; - return E2BIG; - } + { + *inbufp = save_inbuf; + *inbytesleftp = save_inbytesleft; + return E2BIG; + } hi = (s - 0x10000) / 0x400 + 0xD800; lo = (s - 0x10000) % 0x400 + 0xDC00; /* Even if we are little-endian, put the high surrogate first. - ??? Matches practice? */ + ??? Matches practice? */ outbuf[bigend ? 1 : 0] = (hi & 0x00FF); outbuf[bigend ? 0 : 1] = (hi & 0xFF00) >> 8; outbuf[bigend ? 3 : 2] = (lo & 0x00FF); @@ -398,7 +398,7 @@ one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, static inline int one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, - uchar **outbufp, size_t *outbytesleftp) + uchar **outbufp, size_t *outbytesleftp) { cppchar_t s; const uchar *inbuf = *inbufp; @@ -417,13 +417,13 @@ one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, { cppchar_t hi = s, lo; if (*inbytesleftp < 4) - return EINVAL; + return EINVAL; lo = inbuf[bigend ? 2 : 3] << 8; lo += inbuf[bigend ? 3 : 2]; if (lo < 0xDC00 || lo > 0xDFFF) - return EILSEQ; + return EILSEQ; s = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000; } @@ -453,8 +453,8 @@ one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, static inline bool conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *, - uchar **, size_t *), - iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to) + uchar **, size_t *), + iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to) { const uchar *inbuf; uchar *outbuf; @@ -469,20 +469,20 @@ conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *, for (;;) { do - rval = one_conversion (cd, &inbuf, &inbytesleft, - &outbuf, &outbytesleft); + rval = one_conversion (cd, &inbuf, &inbytesleft, + &outbuf, &outbytesleft); while (inbytesleft && !rval); if (__builtin_expect (inbytesleft == 0, 1)) - { - to->len = to->asize - outbytesleft; - return true; - } + { + to->len = to->asize - outbytesleft; + return true; + } if (rval != E2BIG) - { - errno = rval; - return false; - } + { + errno = rval; + return false; + } outbytesleft += OUTBUF_BLOCK_SIZE; to->asize += OUTBUF_BLOCK_SIZE; @@ -504,28 +504,28 @@ conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *, /* These four use the custom conversion code above. */ static bool convert_utf8_utf16 (iconv_t cd, const uchar *from, size_t flen, - struct _cpp_strbuf *to) + struct _cpp_strbuf *to) { return conversion_loop (one_utf8_to_utf16, cd, from, flen, to); } static bool convert_utf8_utf32 (iconv_t cd, const uchar *from, size_t flen, - struct _cpp_strbuf *to) + struct _cpp_strbuf *to) { return conversion_loop (one_utf8_to_utf32, cd, from, flen, to); } static bool convert_utf16_utf8 (iconv_t cd, const uchar *from, size_t flen, - struct _cpp_strbuf *to) + struct _cpp_strbuf *to) { return conversion_loop (one_utf16_to_utf8, cd, from, flen, to); } static bool convert_utf32_utf8 (iconv_t cd, const uchar *from, size_t flen, - struct _cpp_strbuf *to) + struct _cpp_strbuf *to) { return conversion_loop (one_utf32_to_utf8, cd, from, flen, to); } @@ -533,7 +533,7 @@ convert_utf32_utf8 (iconv_t cd, const uchar *from, size_t flen, /* Identity conversion, used when we have no alternative. */ static bool convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, - const uchar *from, size_t flen, struct _cpp_strbuf *to) + const uchar *from, size_t flen, struct _cpp_strbuf *to) { if (to->len + flen > to->asize) { @@ -548,9 +548,18 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, /* And this one uses the system iconv primitive. It's a little different, since iconv's interface is a little different. */ #if HAVE_ICONV + +#define CONVERT_ICONV_GROW_BUFFER \ + do { \ + outbytesleft += OUTBUF_BLOCK_SIZE; \ + to->asize += OUTBUF_BLOCK_SIZE; \ + to->text = XRESIZEVEC (uchar, to->text, to->asize); \ + outbuf = (char *)to->text + to->asize - outbytesleft; \ + } while (0) + static bool convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, - struct _cpp_strbuf *to) + struct _cpp_strbuf *to) { ICONV_CONST char *inbuf; char *outbuf; @@ -569,17 +578,25 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, { iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (__builtin_expect (inbytesleft == 0, 1)) - { - to->len = to->asize - outbytesleft; - return true; - } + { + /* Close out any shift states, returning to the initial state. */ + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + { + if (errno != E2BIG) + return false; + + CONVERT_ICONV_GROW_BUFFER; + if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1) + return false; + } + + to->len = to->asize - outbytesleft; + return true; + } if (errno != E2BIG) - return false; + return false; - outbytesleft += OUTBUF_BLOCK_SIZE; - to->asize += OUTBUF_BLOCK_SIZE; - to->text = XRESIZEVEC (uchar, to->text, to->asize); - outbuf = (char *)to->text + to->asize - outbytesleft; + CONVERT_ICONV_GROW_BUFFER; } } #else @@ -636,9 +653,9 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) for (i = 0; i < ARRAY_SIZE (conversion_tab); i++) if (!strcasecmp (pair, conversion_tab[i].pair)) { - ret.func = conversion_tab[i].func; - ret.cd = conversion_tab[i].fake_cd; - return ret; + ret.func = conversion_tab[i].func; + ret.cd = conversion_tab[i].fake_cd; + return ret; } /* No custom converter - try iconv. */ @@ -648,22 +665,22 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) ret.cd = iconv_open (to, from); if (ret.cd == (iconv_t) -1) - { - if (errno == EINVAL) - cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */ - "conversion from %s to %s not supported by iconv", - from, to); - else - cpp_errno (pfile, CPP_DL_ERROR, "iconv_open"); - - ret.func = convert_no_conversion; - } + { + if (errno == EINVAL) + cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */ + "conversion from %s to %s not supported by iconv", + from, to); + else + cpp_errno (pfile, CPP_DL_ERROR, "iconv_open"); + + ret.func = convert_no_conversion; + } } else { cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */ - "no iconv implementation, cannot convert from %s to %s", - from, to); + "no iconv implementation, cannot convert from %s to %s", + from, to); ret.func = convert_no_conversion; ret.cd = (iconv_t) -1; } @@ -709,9 +726,9 @@ _cpp_destroy_iconv (cpp_reader *pfile) if (HAVE_ICONV) { if (pfile->narrow_cset_desc.func == convert_using_iconv) - iconv_close (pfile->narrow_cset_desc.cd); + iconv_close (pfile->narrow_cset_desc.cd); if (pfile->wide_cset_desc.func == convert_using_iconv) - iconv_close (pfile->wide_cset_desc.cd); + iconv_close (pfile->wide_cset_desc.cd); } } @@ -739,8 +756,8 @@ cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c) if (c > LAST_POSSIBLY_BASIC_SOURCE_CHAR) { cpp_error (pfile, CPP_DL_ICE, - "character 0x%lx is not in the basic source character set\n", - (unsigned long)c); + "character 0x%lx is not in the basic source character set\n", + (unsigned long)c); return 0; } @@ -762,8 +779,8 @@ cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c) if (tbuf.len != 1) { cpp_error (pfile, CPP_DL_ICE, - "character 0x%lx is not unibyte in execution character set", - (unsigned long)c); + "character 0x%lx is not unibyte in execution character set", + (unsigned long)c); return 0; } c = tbuf.text[0]; @@ -823,7 +840,7 @@ static const struct { static int ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, - struct normalize_state *nst) + struct normalize_state *nst) { int mn, mx, md; @@ -836,9 +853,9 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, { md = (mn + mx) / 2; if (c <= ucnranges[md].end) - mx = md; + mx = md; else - mn = md + 1; + mn = md + 1; } /* When -pedantic, we require the character to have been listed by @@ -849,8 +866,8 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, if (CPP_PEDANTIC (pfile) && ((CPP_OPTION (pfile, c99) && !(ucnranges[mn].flags & C99)) - || (CPP_OPTION (pfile, cplusplus) - && !(ucnranges[mn].flags & CXX)))) + || (CPP_OPTION (pfile, cplusplus) + && !(ucnranges[mn].flags & CXX)))) return 0; /* Update NST. */ @@ -863,36 +880,36 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, /* Easy cases from Bengali, Oriya, Tamil, Jannada, and Malayalam. */ if (c == 0x09BE) - safe = p != 0x09C7; /* Use 09CB instead of 09C7 09BE. */ + safe = p != 0x09C7; /* Use 09CB instead of 09C7 09BE. */ else if (c == 0x0B3E) - safe = p != 0x0B47; /* Use 0B4B instead of 0B47 0B3E. */ + safe = p != 0x0B47; /* Use 0B4B instead of 0B47 0B3E. */ else if (c == 0x0BBE) - safe = p != 0x0BC6 && p != 0x0BC7; /* Use 0BCA/0BCB instead. */ + safe = p != 0x0BC6 && p != 0x0BC7; /* Use 0BCA/0BCB instead. */ else if (c == 0x0CC2) - safe = p != 0x0CC6; /* Use 0CCA instead of 0CC6 0CC2. */ + safe = p != 0x0CC6; /* Use 0CCA instead of 0CC6 0CC2. */ else if (c == 0x0D3E) - safe = p != 0x0D46 && p != 0x0D47; /* Use 0D4A/0D4B instead. */ + safe = p != 0x0D46 && p != 0x0D47; /* Use 0D4A/0D4B instead. */ /* For Hangul, characters in the range AC00-D7A3 are NFC/NFKC, - and are combined algorithmically from a sequence of the form - 1100-1112 1161-1175 11A8-11C2 - (if the third is not present, it is treated as 11A7, which is not - really a valid character). - Unfortunately, C99 allows (only) the NFC form, but C++ allows - only the combining characters. */ + and are combined algorithmically from a sequence of the form + 1100-1112 1161-1175 11A8-11C2 + (if the third is not present, it is treated as 11A7, which is not + really a valid character). + Unfortunately, C99 allows (only) the NFC form, but C++ allows + only the combining characters. */ else if (c >= 0x1161 && c <= 0x1175) - safe = p < 0x1100 || p > 0x1112; + safe = p < 0x1100 || p > 0x1112; else if (c >= 0x11A8 && c <= 0x11C2) - safe = (p < 0xAC00 || p > 0xD7A3 || (p - 0xAC00) % 28 != 0); + safe = (p < 0xAC00 || p > 0xD7A3 || (p - 0xAC00) % 28 != 0); else - { - /* Uh-oh, someone updated ucnid.h without updating this code. */ - cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c); - safe = true; - } + { + /* Uh-oh, someone updated ucnid.h without updating this code. */ + cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c); + safe = true; + } if (!safe && c < 0x1161) - nst->level = normalized_none; + nst->level = normalized_none; else if (!safe) - nst->level = MAX (nst->level, normalized_identifier_C); + nst->level = MAX (nst->level, normalized_identifier_C); } else if (ucnranges[mn].flags & NKC) ; @@ -936,8 +953,8 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, cppchar_t _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, - const uchar *limit, int identifier_pos, - struct normalize_state *nst) + const uchar *limit, int identifier_pos, + struct normalize_state *nst) { cppchar_t result, c; unsigned int length; @@ -946,11 +963,11 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, if (!CPP_OPTION (pfile, cplusplus) && !CPP_OPTION (pfile, c99)) cpp_error (pfile, CPP_DL_WARNING, - "universal character names are only valid in C++ and C99"); + "universal character names are only valid in C++ and C99"); else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0) cpp_error (pfile, CPP_DL_WARNING, - "the meaning of '\\%c' is different in traditional C", - (int) str[-1]); + "the meaning of '\\%c' is different in traditional C", + (int) str[-1]); if (str[-1] == 'u') length = 4; @@ -967,7 +984,7 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, { c = *str; if (!ISXDIGIT (c)) - break; + break; str++; result = (result << 4) + hex_value (c); } @@ -978,35 +995,35 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, error message in that case. */ if (length && identifier_pos) return 0; - + *pstr = str; if (length) { cpp_error (pfile, CPP_DL_ERROR, - "incomplete universal character name %.*s", - (int) (str - base), base); + "incomplete universal character name %.*s", + (int) (str - base), base); result = 1; } /* The standard permits $, @ and ` to be specified as UCNs. We use hex escapes so that this also works with EBCDIC hosts. */ else if ((result < 0xa0 - && (result != 0x24 && result != 0x40 && result != 0x60)) - || (result & 0x80000000) - || (result >= 0xD800 && result <= 0xDFFF)) + && (result != 0x24 && result != 0x40 && result != 0x60)) + || (result & 0x80000000) + || (result >= 0xD800 && result <= 0xDFFF)) { cpp_error (pfile, CPP_DL_ERROR, - "%.*s is not a valid universal character", - (int) (str - base), base); + "%.*s is not a valid universal character", + (int) (str - base), base); result = 1; } - else if (identifier_pos && result == 0x24 - && CPP_OPTION (pfile, dollars_in_ident)) + else if (identifier_pos && result == 0x24 + && CPP_OPTION (pfile, dollars_in_ident)) { if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) - { - CPP_OPTION (pfile, warn_dollars) = 0; - cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); - } + { + CPP_OPTION (pfile, warn_dollars) = 0; + cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); + } NORMALIZE_STATE_UPDATE_IDNUM (nst); } else if (identifier_pos) @@ -1014,13 +1031,13 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, int validity = ucn_valid_in_identifier (pfile, result, nst); if (validity == 0) - cpp_error (pfile, CPP_DL_ERROR, - "universal character %.*s is not valid in an identifier", - (int) (str - base), base); + cpp_error (pfile, CPP_DL_ERROR, + "universal character %.*s is not valid in an identifier", + (int) (str - base), base); else if (validity == 2 && identifier_pos == 1) - cpp_error (pfile, CPP_DL_ERROR, + cpp_error (pfile, CPP_DL_ERROR, "universal character %.*s is not valid at the start of an identifier", - (int) (str - base), base); + (int) (str - base), base); } if (result == 0) @@ -1034,7 +1051,7 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, An advanced pointer is returned. Issues all relevant diagnostics. */ static const uchar * convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, bool wide) + struct _cpp_strbuf *tbuf, bool wide) { cppchar_t ucn; uchar buf[6]; @@ -1053,11 +1070,11 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, { errno = rval; cpp_errno (pfile, CPP_DL_ERROR, - "converting UCN to source character set"); + "converting UCN to source character set"); } else if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf)) cpp_errno (pfile, CPP_DL_ERROR, - "converting UCN to execution character set"); + "converting UCN to execution character set"); return from; } @@ -1069,12 +1086,12 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, function issues no diagnostics and never fails. */ static void emit_numeric_escape (cpp_reader *pfile, cppchar_t n, - struct _cpp_strbuf *tbuf, bool wide) + struct _cpp_strbuf *tbuf, bool wide) { if (wide) { /* We have to render this into the target byte order, which may not - be our byte order. */ + be our byte order. */ bool bigend = CPP_OPTION (pfile, bytes_big_endian); size_t width = CPP_OPTION (pfile, wchar_precision); size_t cwidth = CPP_OPTION (pfile, char_precision); @@ -1085,28 +1102,28 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n, cppchar_t c; if (tbuf->len + nbwc > tbuf->asize) - { - tbuf->asize += OUTBUF_BLOCK_SIZE; - tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); - } + { + tbuf->asize += OUTBUF_BLOCK_SIZE; + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); + } for (i = 0; i < nbwc; i++) - { - c = n & cmask; - n >>= cwidth; - tbuf->text[off + (bigend ? nbwc - i - 1 : i)] = c; - } + { + c = n & cmask; + n >>= cwidth; + tbuf->text[off + (bigend ? nbwc - i - 1 : i)] = c; + } tbuf->len += nbwc; } else { /* Note: this code does not handle the case where the target - and host have a different number of bits in a byte. */ + and host have a different number of bits in a byte. */ if (tbuf->len + 1 > tbuf->asize) - { - tbuf->asize += OUTBUF_BLOCK_SIZE; - tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); - } + { + tbuf->asize += OUTBUF_BLOCK_SIZE; + tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize); + } tbuf->text[tbuf->len++] = n; } } @@ -1119,24 +1136,24 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n, number. You can, e.g. generate surrogate pairs this way. */ static const uchar * convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, bool wide) + struct _cpp_strbuf *tbuf, bool wide) { cppchar_t c, n = 0, overflow = 0; int digits_found = 0; size_t width = (wide ? CPP_OPTION (pfile, wchar_precision) - : CPP_OPTION (pfile, char_precision)); + : CPP_OPTION (pfile, char_precision)); size_t mask = width_to_mask (width); if (CPP_WTRADITIONAL (pfile)) cpp_error (pfile, CPP_DL_WARNING, - "the meaning of '\\x' is different in traditional C"); + "the meaning of '\\x' is different in traditional C"); from++; /* Skip 'x'. */ while (from < limit) { c = *from; if (! hex_p (c)) - break; + break; from++; overflow |= n ^ (n << 4 >> 4); n = (n << 4) + hex_value (c); @@ -1146,14 +1163,14 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, if (!digits_found) { cpp_error (pfile, CPP_DL_ERROR, - "\\x used with no following hex digits"); + "\\x used with no following hex digits"); return from; } if (overflow | (n != (n & mask))) { cpp_error (pfile, CPP_DL_PEDWARN, - "hex escape sequence out of range"); + "hex escape sequence out of range"); n &= mask; } @@ -1170,12 +1187,12 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, number. */ static const uchar * convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, bool wide) + struct _cpp_strbuf *tbuf, bool wide) { size_t count = 0; cppchar_t c, n = 0; size_t width = (wide ? CPP_OPTION (pfile, wchar_precision) - : CPP_OPTION (pfile, char_precision)); + : CPP_OPTION (pfile, char_precision)); size_t mask = width_to_mask (width); bool overflow = false; @@ -1183,7 +1200,7 @@ convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, { c = *from; if (c < '0' || c > '7') - break; + break; from++; overflow |= n ^ (n << 3 >> 3); n = (n << 3) + c - '0'; @@ -1192,7 +1209,7 @@ convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, if (n != (n & mask)) { cpp_error (pfile, CPP_DL_PEDWARN, - "octal escape sequence out of range"); + "octal escape sequence out of range"); n &= mask; } @@ -1207,7 +1224,7 @@ convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, pointer. Handles all relevant diagnostics. */ static const uchar * convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, bool wide) + struct _cpp_strbuf *tbuf, bool wide) { /* Values of \a \b \e \f \n \r \t \v respectively. */ #if HOST_CHARSET == HOST_CHARSET_ASCII @@ -1238,16 +1255,16 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, return convert_oct (pfile, from, limit, tbuf, wide); /* Various letter escapes. Get the appropriate host-charset - value into C. */ + value into C. */ case '\\': case '\'': case '"': case '?': break; case '(': case '{': case '[': case '%': /* '\(', etc, can be used at the beginning of a line in a long - string split onto multiple lines with \-newline, to prevent - Emacs or other text editors from getting confused. '\%' can - be used to prevent SCCS from mangling printf format strings. */ + string split onto multiple lines with \-newline, to prevent + Emacs or other text editors from getting confused. '\%' can + be used to prevent SCCS from mangling printf format strings. */ if (CPP_PEDANTIC (pfile)) - goto unknown; + goto unknown; break; case 'b': c = charconsts[1]; break; @@ -1259,38 +1276,38 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, case 'a': if (CPP_WTRADITIONAL (pfile)) - cpp_error (pfile, CPP_DL_WARNING, - "the meaning of '\\a' is different in traditional C"); + cpp_error (pfile, CPP_DL_WARNING, + "the meaning of '\\a' is different in traditional C"); c = charconsts[0]; break; case 'e': case 'E': if (CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "non-ISO-standard escape sequence, '\\%c'", (int) c); + cpp_error (pfile, CPP_DL_PEDWARN, + "non-ISO-standard escape sequence, '\\%c'", (int) c); c = charconsts[2]; break; default: unknown: if (ISGRAPH (c)) - cpp_error (pfile, CPP_DL_PEDWARN, - "unknown escape sequence '\\%c'", (int) c); + cpp_error (pfile, CPP_DL_PEDWARN, + "unknown escape sequence '\\%c'", (int) c); else - { - /* diagnostic.c does not support "%03o". When it does, this - code can use %03o directly in the diagnostic again. */ - char buf[32]; - sprintf(buf, "%03o", (int) c); - cpp_error (pfile, CPP_DL_PEDWARN, - "unknown escape sequence: '\\%s'", buf); - } + { + /* diagnostic.c does not support "%03o". When it does, this + code can use %03o directly in the diagnostic again. */ + char buf[32]; + sprintf(buf, "%03o", (int) c); + cpp_error (pfile, CPP_DL_PEDWARN, + "unknown escape sequence: '\\%s'", buf); + } } /* Now convert what we have to the execution character set. */ if (!APPLY_CONVERSION (cvt, &c, 1, tbuf)) cpp_errno (pfile, CPP_DL_ERROR, - "converting escape sequence to execution character set"); + "converting escape sequence to execution character set"); return from + 1; } @@ -1303,7 +1320,7 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, false for failure. */ bool cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, - cpp_string *to, bool wide) + cpp_string *to, bool wide) { struct _cpp_strbuf tbuf; const uchar *p, *base, *limit; @@ -1323,22 +1340,22 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */ for (;;) - { - base = p; - while (p < limit && *p != '\\') - p++; - if (p > base) - { - /* We have a run of normal characters; these can be fed - directly to convert_cset. */ - if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf)) - goto fail; - } - if (p == limit) - break; - - p = convert_escape (pfile, p + 1, limit, &tbuf, wide); - } + { + base = p; + while (p < limit && *p != '\\') + p++; + if (p > base) + { + /* We have a run of normal characters; these can be fed + directly to convert_cset. */ + if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf)) + goto fail; + } + if (p == limit) + break; + + p = convert_escape (pfile, p + 1, limit, &tbuf, wide); + } } /* NUL-terminate the 'to' buffer and translate it to a cpp_string structure. */ @@ -1358,7 +1375,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, in a string, but do not perform character set conversion. */ bool cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, - size_t count, cpp_string *to, bool wide) + size_t count, cpp_string *to, bool wide) { struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc; bool retval; @@ -1379,7 +1396,7 @@ cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, cpp_interpret_charconst. */ static cppchar_t narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, - unsigned int *pchars_seen, int *unsignedp) + unsigned int *pchars_seen, int *unsignedp) { size_t width = CPP_OPTION (pfile, char_precision); size_t max_chars = CPP_OPTION (pfile, int_precision) / width; @@ -1403,16 +1420,16 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, { c = str.text[i] & mask; if (width < BITS_PER_CPPCHAR_T) - result = (result << width) | c; + result = (result << width) | c; else - result = c; + result = c; } if (i > max_chars) { i = max_chars; cpp_error (pfile, CPP_DL_WARNING, - "character constant too long for its type"); + "character constant too long for its type"); } else if (i > 1 && CPP_OPTION (pfile, warn_multichar)) cpp_error (pfile, CPP_DL_WARNING, "multi-character character constant"); @@ -1433,9 +1450,9 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, { mask = ((cppchar_t) 1 << width) - 1; if (unsigned_p || !(result & (1 << (width - 1)))) - result &= mask; + result &= mask; else - result |= ~mask; + result |= ~mask; } *pchars_seen = i; *unsignedp = unsigned_p; @@ -1448,7 +1465,7 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, cpp_interpret_charconst. */ static cppchar_t wide_str_to_charconst (cpp_reader *pfile, cpp_string str, - unsigned int *pchars_seen, int *unsignedp) + unsigned int *pchars_seen, int *unsignedp) { bool bigend = CPP_OPTION (pfile, bytes_big_endian); size_t width = CPP_OPTION (pfile, wchar_precision); @@ -1475,16 +1492,16 @@ wide_str_to_charconst (cpp_reader *pfile, cpp_string str, character constant is guaranteed to overflow. */ if (off > 0) cpp_error (pfile, CPP_DL_WARNING, - "character constant too long for its type"); + "character constant too long for its type"); /* Truncate the constant to its natural width, and simultaneously sign- or zero-extend to the full width of cppchar_t. */ if (width < BITS_PER_CPPCHAR_T) { if (CPP_OPTION (pfile, unsigned_wchar) || !(result & (1 << (width - 1)))) - result &= mask; + result &= mask; else - result |= ~mask; + result |= ~mask; } *unsignedp = CPP_OPTION (pfile, unsigned_wchar); @@ -1498,7 +1515,7 @@ wide_str_to_charconst (cpp_reader *pfile, cpp_string str, whether the result has signed type. */ cppchar_t cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token, - unsigned int *pchars_seen, int *unsignedp) + unsigned int *pchars_seen, int *unsignedp) { cpp_string str = { 0, 0 }; bool wide = (token->type == CPP_WCHAR); @@ -1535,46 +1552,46 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len) uchar * buf = (uchar *) alloca (len + 1); uchar * bufp = buf; size_t idp; - + for (idp = 0; idp < len; idp++) if (id[idp] != '\\') *bufp++ = id[idp]; else { - unsigned length = id[idp+1] == 'u' ? 4 : 8; - cppchar_t value = 0; - size_t bufleft = len - (bufp - buf); - int rval; - - idp += 2; - while (length && idp < len && ISXDIGIT (id[idp])) - { - value = (value << 4) + hex_value (id[idp]); - idp++; - length--; - } - idp--; - - /* Special case for EBCDIC: if the identifier contains - a '$' specified using a UCN, translate it to EBCDIC. */ - if (value == 0x24) - { - *bufp++ = '$'; - continue; - } - - rval = one_cppchar_to_utf8 (value, &bufp, &bufleft); - if (rval) - { - errno = rval; - cpp_errno (pfile, CPP_DL_ERROR, - "converting UCN to source character set"); - break; - } + unsigned length = id[idp+1] == 'u' ? 4 : 8; + cppchar_t value = 0; + size_t bufleft = len - (bufp - buf); + int rval; + + idp += 2; + while (length && idp < len && ISXDIGIT (id[idp])) + { + value = (value << 4) + hex_value (id[idp]); + idp++; + length--; + } + idp--; + + /* Special case for EBCDIC: if the identifier contains + a '$' specified using a UCN, translate it to EBCDIC. */ + if (value == 0x24) + { + *bufp++ = '$'; + continue; + } + + rval = one_cppchar_to_utf8 (value, &bufp, &bufleft); + if (rval) + { + errno = rval; + cpp_errno (pfile, CPP_DL_ERROR, + "converting UCN to source character set"); + break; + } } - return CPP_HASHNODE (ht_lookup (pfile->hash_table, - buf, bufp - buf, HT_ALLOC)); + return CPP_HASHNODE (ht_lookup (pfile->hash_table, + buf, bufp - buf, HT_ALLOC)); } /* Convert an input buffer (containing the complete contents of one @@ -1587,9 +1604,9 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len) INPUT is expected to have been allocated with xmalloc. This function will either return INPUT, or free it and return a pointer to another xmalloc-allocated block of memory. */ -uchar * +uchar * _cpp_convert_input (cpp_reader *pfile, const char *input_charset, - uchar *input, size_t size, size_t len, off_t *st_size) + uchar *input, size_t size, size_t len, off_t *st_size) { struct cset_converter input_cset; struct _cpp_strbuf to; @@ -1608,9 +1625,9 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, to.len = 0; if (!APPLY_CONVERSION (input_cset, input, len, &to)) - cpp_error (pfile, CPP_DL_ERROR, - "failure to convert %s to %s", - CPP_OPTION (pfile, input_charset), SOURCE_CHARSET); + cpp_error (pfile, CPP_DL_ERROR, + "failure to convert %s to %s", + CPP_OPTION (pfile, input_charset), SOURCE_CHARSET); free (input); } @@ -1628,7 +1645,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 && to.text[to.len - 1] == '\r') to.text[to.len] = '\r'; else to.text[to.len] = '\n'; diff --git a/support/cpp2/libcpp/directives.c b/support/cpp/libcpp/directives.c similarity index 71% rename from support/cpp2/libcpp/directives.c rename to support/cpp/libcpp/directives.c index 7fb142e4..89bf6104 100644 --- a/support/cpp2/libcpp/directives.c +++ b/support/cpp/libcpp/directives.c @@ -1,6 +1,7 @@ /* CPP Library. (Directive handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -31,11 +32,11 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ struct if_stack { struct if_stack *next; - unsigned int line; /* Line where condition started. */ + unsigned int line; /* Line where condition started. */ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ - bool skip_elses; /* Can future #else / #elif be skipped? */ - bool was_skipping; /* If were skipping on entry. */ - int type; /* Most recent conditional for diagnostics. */ + bool skip_elses; /* Can future #else / #elif be skipped? */ + bool was_skipping; /* If were skipping on entry. */ + int type; /* Most recent conditional for diagnostics. */ }; /* Contains a registered pragma or pragma namespace. */ @@ -43,7 +44,7 @@ typedef void (*pragma_cb) (cpp_reader *); struct pragma_entry { struct pragma_entry *next; - const cpp_hashnode *pragma; /* Name and length. */ + const cpp_hashnode *pragma; /* Name and length. */ bool is_nspace; bool is_internal; bool is_deferred; @@ -58,9 +59,9 @@ struct pragma_entry /* Values for the origin field of struct directive. KANDR directives come from traditional (K&R) C. STDC89 directives come from the 1989 C standard. EXTENSION directives are extensions. */ -#define KANDR 0 -#define STDC89 1 -#define EXTENSION 2 +#define KANDR 0 +#define STDC89 1 +#define EXTENSION 2 /* Values for the flags field of struct directive. COND indicates a conditional; IF_COND an opening conditional. INCL means to treat @@ -69,22 +70,22 @@ struct pragma_entry effect (these are the directives with callback hooks). EXPAND is set on directives that are always macro-expanded. */ -#define COND (1 << 0) -#define IF_COND (1 << 1) -#define INCL (1 << 2) -#define IN_I (1 << 3) -#define EXPAND (1 << 4) +#define COND (1 << 0) +#define IF_COND (1 << 1) +#define INCL (1 << 2) +#define IN_I (1 << 3) +#define EXPAND (1 << 4) /* Defines one #-directive, including how to handle it. */ typedef void (*directive_handler) (cpp_reader *); typedef struct directive directive; struct directive { - directive_handler handler; /* Function to handle directive. */ - const uchar *name; /* Name of directive. */ - unsigned short length; /* Length of name. */ - unsigned char origin; /* Origin of directive. */ - unsigned char flags; /* Flags describing this directive. */ + directive_handler handler; /* Function to handle directive. */ + const uchar *name; /* Name of directive. */ + unsigned short length; /* Length of name. */ + unsigned char origin; /* Origin of directive. */ + unsigned char flags; /* Flags describing this directive. */ }; /* Forward declarations. */ @@ -102,7 +103,7 @@ static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static int strtoul_for_line (const uchar *, unsigned int, unsigned long *); static void do_diagnostic (cpp_reader *, int, int); -static cpp_hashnode *lex_macro_node (cpp_reader *); +static cpp_hashnode *lex_macro_node (cpp_reader *, bool); static int undefine_macros (cpp_reader *, cpp_hashnode *, void *); static void do_include_common (cpp_reader *, enum include_type); static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *, @@ -133,26 +134,26 @@ static void handle_assertion (cpp_reader *, const char *, int); are deprecated. The name is where the extension appears to have come from. */ -#define DIRECTIVE_TABLE \ -D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \ -D(include, T_INCLUDE, KANDR, INCL | EXPAND) /* 52262 */ \ -D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \ -D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \ -D(if, T_IF, KANDR, COND | IF_COND | EXPAND) /* 18162 */ \ -D(else, T_ELSE, KANDR, COND) /* 9863 */ \ -D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \ -D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \ -D(line, T_LINE, KANDR, EXPAND) /* 2465 */ \ -D(elif, T_ELIF, STDC89, COND | EXPAND) /* 610 */ \ -D(error, T_ERROR, STDC89, 0) /* 475 */ \ -D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \ -D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \ -D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \ -D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ -D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ -D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \ -D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \ -D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */ +#define DIRECTIVE_TABLE \ +D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \ +D(include, T_INCLUDE, KANDR, INCL | EXPAND) /* 52262 */ \ +D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \ +D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \ +D(if, T_IF, KANDR, COND | IF_COND | EXPAND) /* 18162 */ \ +D(else, T_ELSE, KANDR, COND) /* 9863 */ \ +D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \ +D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \ +D(line, T_LINE, KANDR, EXPAND) /* 2465 */ \ +D(elif, T_ELIF, STDC89, COND | EXPAND) /* 610 */ \ +D(error, T_ERROR, STDC89, 0) /* 475 */ \ +D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \ +D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \ +D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \ +D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ +D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ +D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \ +D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \ +D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */ /* #sccs is synonymous with #ident. */ #define do_sccs do_ident @@ -212,7 +213,7 @@ check_eol (cpp_reader *pfile) { if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF) cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive", - pfile->directive->name); + pfile->directive->name); } /* Ensure there are no stray tokens other than comments at the end of @@ -229,27 +230,27 @@ check_eol_return_comments (cpp_reader *pfile) if (! SEEN_EOL ()) { while (1) - { - const cpp_token *tok; - - tok = _cpp_lex_token (pfile); - if (tok->type == CPP_EOF) - break; - if (tok->type != CPP_COMMENT) - cpp_error (pfile, CPP_DL_PEDWARN, - "extra tokens at end of #%s directive", - pfile->directive->name); - else - { - if (c + 1 >= capacity) - { - capacity *= 2; - buf = XRESIZEVEC (const cpp_token *, buf, capacity); - } - buf[c] = tok; - ++c; - } - } + { + const cpp_token *tok; + + tok = _cpp_lex_token (pfile); + if (tok->type == CPP_EOF) + break; + if (tok->type != CPP_COMMENT) + cpp_error (pfile, CPP_DL_PEDWARN, + "extra tokens at end of #%s directive", + pfile->directive->name); + else + { + if (c + 1 >= capacity) + { + capacity *= 2; + buf = XRESIZEVEC (const cpp_token *, buf, capacity); + } + buf[c] = tok; + ++c; + } + } } buf[c] = NULL; return buf; @@ -280,17 +281,17 @@ end_directive (cpp_reader *pfile, int skip_line) pfile->state.prevent_expansion--; if (pfile->directive != &dtable[T_DEFINE]) - _cpp_remove_overlay (pfile); + _cpp_remove_overlay (pfile); } /* We don't skip for an assembler #. */ else if (skip_line) { skip_rest_of_line (pfile); if (!pfile->keep_tokens) - { - pfile->cur_run = &pfile->base_run; - pfile->cur_token = pfile->base_run.base; - } + { + pfile->cur_run = &pfile->base_run; + pfile->cur_token = pfile->base_run.base; + } } /* Restore state. */ @@ -308,23 +309,23 @@ prepare_directive_trad (cpp_reader *pfile) if (pfile->directive != &dtable[T_DEFINE]) { bool no_expand = (pfile->directive - && ! (pfile->directive->flags & EXPAND)); + && ! (pfile->directive->flags & EXPAND)); bool was_skipping = pfile->state.skipping; pfile->state.in_expression = (pfile->directive == &dtable[T_IF] - || pfile->directive == &dtable[T_ELIF]); + || pfile->directive == &dtable[T_ELIF]); if (pfile->state.in_expression) - pfile->state.skipping = false; + pfile->state.skipping = false; if (no_expand) - pfile->state.prevent_expansion++; + pfile->state.prevent_expansion++; _cpp_scan_out_logical_line (pfile, NULL); if (no_expand) - pfile->state.prevent_expansion--; + pfile->state.prevent_expansion--; pfile->state.skipping = was_skipping; _cpp_overlay_buffer (pfile, pfile->out.base, - pfile->out.cur - pfile->out.base); + pfile->out.cur - pfile->out.base); } /* Stop ISO C from expanding anything. */ @@ -351,16 +352,16 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) if (CPP_WTRADITIONAL (pfile)) { if (dir == &dtable[T_ELIF]) - cpp_error (pfile, CPP_DL_WARNING, - "suggest not using #elif in traditional C"); + cpp_error (pfile, CPP_DL_WARNING, + "suggest not using #elif in traditional C"); else if (indented && dir->origin == KANDR) - cpp_error (pfile, CPP_DL_WARNING, - "traditional C ignores #%s with the # indented", - dir->name); + cpp_error (pfile, CPP_DL_WARNING, + "traditional C ignores #%s with the # indented", + dir->name); else if (!indented && dir->origin != KANDR) - cpp_error (pfile, CPP_DL_WARNING, - "suggest hiding #%s from traditional C with an indented #", - dir->name); + cpp_error (pfile, CPP_DL_WARNING, + "suggest hiding #%s from traditional C with an indented #", + dir->name); } } @@ -384,8 +385,8 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) if (was_parsing_args) { if (CPP_OPTION (pfile, pedantic)) - cpp_error (pfile, CPP_DL_PEDWARN, - "embedding a directive within macro arguments is not portable"); + cpp_error (pfile, CPP_DL_PEDWARN, + "embedding a directive within macro arguments is not portable"); pfile->state.parsing_args = 0; pfile->state.prevent_expansion = 0; } @@ -395,7 +396,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) if (dname->type == CPP_NAME) { if (dname->val.node->is_directive) - dir = &dtable[dname->val.node->directive_index]; + dir = &dtable[dname->val.node->directive_index]; } /* We do not recognize the # followed by a number extension in assembler code. */ @@ -403,60 +404,65 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) { dir = &linemarker_dir; if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed) - && ! pfile->state.skipping) - cpp_error (pfile, CPP_DL_PEDWARN, - "style of line directive is a GCC extension"); + && ! pfile->state.skipping) + cpp_error (pfile, CPP_DL_PEDWARN, + "style of line directive is a GCC extension"); } if (dir) { /* If we have a directive that is not an opening conditional, - invalidate any control macro. */ + invalidate any control macro. */ if (! (dir->flags & IF_COND)) - pfile->mi_valid = false; + pfile->mi_valid = false; /* Kluge alert. In order to be sure that code like this - #define HASH # - HASH define foo bar + #define HASH # + HASH define foo bar + + 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. - 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. */ + 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) - && (indented || !(dir->flags & IN_I))) - { - skip = 0; - dir = 0; - } + && !CPP_OPTION (pfile, directives_only) + && (indented || !(dir->flags & IN_I))) + { + skip = 0; + dir = 0; + } else - { - /* In failed conditional groups, all non-conditional - directives are ignored. Before doing that, whether - skipping or not, we should lex angle-bracketed headers - correctly, and maybe output some diagnostics. */ - pfile->state.angled_headers = dir->flags & INCL; - pfile->state.directive_wants_padding = dir->flags & INCL; - if (! CPP_OPTION (pfile, preprocessed)) - directive_diagnostics (pfile, dir, indented); - if (pfile->state.skipping && !(dir->flags & COND)) - dir = 0; - } + { + /* In failed conditional groups, all non-conditional + directives are ignored. Before doing that, whether + skipping or not, we should lex angle-bracketed headers + correctly, and maybe output some diagnostics. */ + pfile->state.angled_headers = dir->flags & INCL; + pfile->state.directive_wants_padding = dir->flags & INCL; + if (! CPP_OPTION (pfile, preprocessed)) + directive_diagnostics (pfile, dir, indented); + if (pfile->state.skipping && !(dir->flags & COND)) + dir = 0; + } } else if (dname->type == CPP_EOF) - ; /* CPP_EOF is the "null directive". */ + ; /* CPP_EOF is the "null directive". */ else { /* An unknown directive. Don't complain about it in assembly - source: we don't know where the comments are, and # may - introduce assembler pseudo-ops. Don't complain about invalid - directives in skipped conditional groups (6.10 p4). */ + source: we don't know where the comments are, and # may + introduce assembler pseudo-ops. Don't complain about invalid + directives in skipped conditional groups (6.10 p4). */ if (CPP_OPTION (pfile, lang) == CLK_ASM) - skip = 0; + skip = 0; else if (!pfile->state.skipping) - cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s", - cpp_token_as_text (pfile, dname)); + cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s", + cpp_token_as_text (pfile, dname)); } pfile->directive = dir; @@ -469,7 +475,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) _cpp_backup_tokens (pfile, 1); end_directive (pfile, skip); - if (was_parsing_args) + if (was_parsing_args && !pfile->state.in_deferred_pragma) { /* Restore state when within macro args. */ pfile->state.parsing_args = 2; @@ -486,7 +492,7 @@ static void run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) { cpp_push_buffer (pfile, (const uchar *) buf, count, - /* from_stage3 */ true); + /* from_stage3 */ true); start_directive (pfile); /* This is a short-term fix to prevent a leading '#' being @@ -502,9 +508,11 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count) } /* Checks for validity the macro name in #define, #undef, #ifdef and - #ifndef directives. */ + #ifndef directives. IS_DEF_OR_UNDEF is true if this call is + processing a #define or #undefine directive, and false + otherwise. */ static cpp_hashnode * -lex_macro_node (cpp_reader *pfile) +lex_macro_node (cpp_reader *pfile, bool is_def_or_undef) { const cpp_token *token = _cpp_lex_token (pfile); @@ -519,19 +527,19 @@ lex_macro_node (cpp_reader *pfile) { cpp_hashnode *node = token->val.node; - if (node == pfile->spec_nodes.n_defined) - cpp_error (pfile, CPP_DL_ERROR, - "\"defined\" cannot be used as a macro name"); + if (is_def_or_undef && node == pfile->spec_nodes.n_defined) + cpp_error (pfile, CPP_DL_ERROR, + "\"defined\" cannot be used as a macro name"); else if (! (node->flags & NODE_POISONED)) - return node; + return node; } else if (token->flags & NAMED_OP) cpp_error (pfile, CPP_DL_ERROR, "\"%s\" cannot be used as a macro name as it is an operator in C++", - NODE_NAME (token->val.node)); + NODE_NAME (token->val.node)); else if (token->type == CPP_EOF) cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive", - pfile->directive->name); + pfile->directive->name); else cpp_error (pfile, CPP_DL_ERROR, "macro names must be identifiers"); @@ -542,18 +550,18 @@ lex_macro_node (cpp_reader *pfile) static void do_define (cpp_reader *pfile) { - cpp_hashnode *node = lex_macro_node (pfile); + cpp_hashnode *node = lex_macro_node (pfile, true); if (node) { /* If we have been requested to expand comments into macros, - then re-enable saving of comments. */ + then re-enable saving of comments. */ pfile->state.save_comments = - ! CPP_OPTION (pfile, discard_comments_in_macro_exp); + ! CPP_OPTION (pfile, discard_comments_in_macro_exp); if (_cpp_create_definition (pfile, node)) - if (pfile->cb.define) - pfile->cb.define (pfile, pfile->directive_line, node); + if (pfile->cb.define) + pfile->cb.define (pfile, pfile->directive_line, node); } } @@ -561,26 +569,26 @@ do_define (cpp_reader *pfile) static void do_undef (cpp_reader *pfile) { - cpp_hashnode *node = lex_macro_node (pfile); + cpp_hashnode *node = lex_macro_node (pfile, true); if (node) { if (pfile->cb.undef) - pfile->cb.undef (pfile, pfile->directive_line, node); + pfile->cb.undef (pfile, pfile->directive_line, node); /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified - identifier is not currently defined as a macro name. */ + identifier is not currently defined as a macro name. */ if (node->type == NT_MACRO) - { - if (node->flags & NODE_WARN) - cpp_error (pfile, CPP_DL_WARNING, - "undefining \"%s\"", NODE_NAME (node)); + { + if (node->flags & NODE_WARN) + cpp_error (pfile, CPP_DL_WARNING, + "undefining \"%s\"", NODE_NAME (node)); - if (CPP_OPTION (pfile, warn_unused_macros)) - _cpp_warn_if_unused_macro (pfile, node, NULL); + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); - _cpp_free_definition (node); - } + _cpp_free_definition (node); + } } check_eol (pfile); @@ -590,7 +598,7 @@ do_undef (cpp_reader *pfile) static int undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, - void *data_p ATTRIBUTE_UNUSED) + void *data_p ATTRIBUTE_UNUSED) { /* Body of _cpp_free_definition inlined here for speed. Macros and assertions no longer have anything to free. */ @@ -626,26 +634,26 @@ glue_header_name (cpp_reader *pfile) token = get_token_no_padding (pfile); if (token->type == CPP_GREATER) - break; + break; if (token->type == CPP_EOF) - { - cpp_error (pfile, CPP_DL_ERROR, "missing terminating > character"); - break; - } + { + cpp_error (pfile, CPP_DL_ERROR, "missing terminating > character"); + break; + } len = cpp_token_len (token) + 2; /* Leading space, terminating \0. */ if (total_len + len > capacity) - { - capacity = (capacity + len) * 2; - buffer = XRESIZEVEC (char, buffer, capacity); - } + { + capacity = (capacity + len) * 2; + buffer = XRESIZEVEC (char, buffer, capacity); + } if (token->flags & PREV_WHITE) - buffer[total_len++] = ' '; + buffer[total_len++] = ' '; total_len = (cpp_spell_token (pfile, token, (uchar *) &buffer[total_len], - true) - - (uchar *) buffer); + true) + - (uchar *) buffer); } buffer[total_len] = '\0'; @@ -657,7 +665,7 @@ glue_header_name (cpp_reader *pfile) free it. Returns NULL on error. */ static const char * parse_include (cpp_reader *pfile, int *pangle_brackets, - const cpp_token ***buf) + const cpp_token ***buf) { char *fname; const cpp_token *header; @@ -681,21 +689,25 @@ parse_include (cpp_reader *pfile, int *pangle_brackets, const unsigned char *dir; if (pfile->directive == &dtable[T_PRAGMA]) - dir = U"pragma dependency"; + dir = U"pragma dependency"; else - dir = pfile->directive->name; + dir = pfile->directive->name; cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or ", - dir); + dir); return NULL; } - if (buf == NULL || CPP_OPTION (pfile, discard_comments)) + if (pfile->directive == &dtable[T_PRAGMA]) + { + /* This pragma allows extra tokens after the file name. */ + } + else if (buf == NULL || CPP_OPTION (pfile, discard_comments)) check_eol (pfile); else { /* If we are not discarding comments, then gather them while - doing the eol check. */ + doing the eol check. */ *buf = check_eol_return_comments (pfile); } @@ -718,7 +730,7 @@ do_include_common (cpp_reader *pfile, enum include_type type) if (!fname) { if (buf) - XDELETEVEC (buf); + XDELETEVEC (buf); return; } @@ -741,9 +753,9 @@ do_include_common (cpp_reader *pfile, enum include_type type) skip_rest_of_line (pfile); if (pfile->cb.include) - pfile->cb.include (pfile, pfile->directive_line, - pfile->directive->name, fname, angle_brackets, - buf); + pfile->cb.include (pfile, pfile->directive_line, + pfile->directive->name, fname, angle_brackets, + buf); _cpp_stack_include (pfile, fname, angle_brackets, type); } @@ -772,10 +784,10 @@ do_include_next (cpp_reader *pfile) /* If this is the primary source file, warn and use the normal search logic. */ - if (! pfile->buffer->prev) + if (cpp_in_primary_file (pfile)) { cpp_error (pfile, CPP_DL_WARNING, - "#include_next in primary source file"); + "#include_next in primary source file"); type = IT_INCLUDE; } do_include_common (pfile, type); @@ -795,14 +807,14 @@ read_flag (cpp_reader *pfile, unsigned int last) unsigned int flag = token->val.str.text[0] - '0'; if (flag > last && flag <= 4 - && (flag != 4 || last == 3) - && (flag != 2 || last == 0)) - return flag; + && (flag != 4 || last == 3) + && (flag != 2 || last == 0)) + return flag; } if (token->type != CPP_EOF) cpp_error (pfile, CPP_DL_ERROR, "invalid flag \"%s\" in line directive", - cpp_token_as_text (pfile, token)); + cpp_token_as_text (pfile, token)); return 0; } @@ -818,7 +830,7 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump) { c = *str++; if (!ISDIGIT (c)) - return 1; + return 1; reg *= 10; reg += c - '0'; } @@ -850,11 +862,14 @@ do_line (cpp_reader *pfile) token = cpp_get_token (pfile); if (token->type != CPP_NUMBER || strtoul_for_line (token->val.str.text, token->val.str.len, - &new_lineno)) + &new_lineno)) { - cpp_error (pfile, CPP_DL_ERROR, - "\"%s\" after #line is not a positive integer", - cpp_token_as_text (pfile, token)); + if (token->type == CPP_EOF) + cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line"); + else + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" after #line is not a positive integer", + cpp_token_as_text (pfile, token)); return; } @@ -866,20 +881,20 @@ do_line (cpp_reader *pfile) { cpp_string s = { 0, 0 }; if (cpp_interpret_string_notranslate (pfile, &token->val.str, 1, - &s, false)) - new_file = (const char *)s.text; + &s, false)) + new_file = (const char *)s.text; check_eol (pfile); } else if (token->type != CPP_EOF) { cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename", - cpp_token_as_text (pfile, token)); + cpp_token_as_text (pfile, token)); return; } skip_rest_of_line (pfile); _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno, - map_sysp); + map_sysp); } /* Interpret the # 44 "file" [flags] notation, which has slightly @@ -906,11 +921,13 @@ do_linemarker (cpp_reader *pfile) token = cpp_get_token (pfile); if (token->type != CPP_NUMBER || strtoul_for_line (token->val.str.text, token->val.str.len, - &new_lineno)) + &new_lineno)) { + /* Unlike #line, there does not seem to be a way to get an EOF + here. So, it should be safe to always spell the token. */ cpp_error (pfile, CPP_DL_ERROR, - "\"%s\" after # is not a positive integer", - cpp_token_as_text (pfile, token)); + "\"%s\" after # is not a positive integer", + cpp_token_as_text (pfile, token)); return; } @@ -919,30 +936,30 @@ do_linemarker (cpp_reader *pfile) { cpp_string s = { 0, 0 }; if (cpp_interpret_string_notranslate (pfile, &token->val.str, - 1, &s, false)) - new_file = (const char *)s.text; + 1, &s, false)) + new_file = (const char *)s.text; new_sysp = 0; flag = read_flag (pfile, 0); if (flag == 1) - { - reason = LC_ENTER; - /* Fake an include for cpp_included (). */ - _cpp_fake_include (pfile, new_file); - flag = read_flag (pfile, flag); - } + { + reason = LC_ENTER; + /* Fake an include for cpp_included (). */ + _cpp_fake_include (pfile, new_file); + flag = read_flag (pfile, flag); + } else if (flag == 2) - { - reason = LC_LEAVE; - flag = read_flag (pfile, flag); - } + { + reason = LC_LEAVE; + flag = read_flag (pfile, flag); + } if (flag == 3) - { - new_sysp = 1; - flag = read_flag (pfile, flag); - if (flag == 4) - new_sysp = 2; - } + { + new_sysp = 1; + flag = read_flag (pfile, flag); + if (flag == 4) + new_sysp = 2; + } pfile->buffer->sysp = new_sysp; check_eol (pfile); @@ -950,7 +967,7 @@ do_linemarker (cpp_reader *pfile) else if (token->type != CPP_EOF) { cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename", - cpp_token_as_text (pfile, token)); + cpp_token_as_text (pfile, token)); return; } @@ -964,11 +981,11 @@ do_linemarker (cpp_reader *pfile) and zero otherwise. */ void _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, - const char *to_file, unsigned int file_line, - unsigned int sysp) + const char *to_file, unsigned int file_line, + unsigned int sysp) { const struct line_map *map = linemap_add (pfile->line_table, reason, sysp, - to_file, file_line); + to_file, file_line); if (map != NULL) linemap_line_start (pfile->line_table, map->to_line, 127); @@ -984,7 +1001,7 @@ do_diagnostic (cpp_reader *pfile, int code, int print_dir) if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0)) { if (print_dir) - fprintf (stderr, "#%s ", pfile->directive->name); + fprintf (stderr, "#%s ", pfile->directive->name); pfile->state.prevent_expansion++; cpp_output_line (pfile, stderr); pfile->state.prevent_expansion--; @@ -1012,7 +1029,7 @@ do_ident (cpp_reader *pfile) if (str->type != CPP_STRING) cpp_error (pfile, CPP_DL_ERROR, "invalid #%s directive", - pfile->directive->name); + pfile->directive->name); else if (pfile->cb.ident) pfile->cb.ident (pfile, pfile->directive_line, &str->val.str); @@ -1052,7 +1069,7 @@ new_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain) goes in the global namespace. */ static struct pragma_entry * register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, - bool allow_name_expansion) + bool allow_name_expansion) { struct pragma_entry **chain = &pfile->pragmas; struct pragma_entry *entry; @@ -1063,28 +1080,28 @@ register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, node = cpp_lookup (pfile, U space, strlen (space)); entry = lookup_pragma_entry (*chain, node); if (!entry) - { - entry = new_pragma_entry (pfile, chain); - entry->pragma = node; - entry->is_nspace = true; - entry->allow_expansion = allow_name_expansion; - } + { + entry = new_pragma_entry (pfile, chain); + entry->pragma = node; + entry->is_nspace = true; + entry->allow_expansion = allow_name_expansion; + } else if (!entry->is_nspace) - goto clash; + goto clash; else if (entry->allow_expansion != allow_name_expansion) - { - cpp_error (pfile, CPP_DL_ICE, - "registering pragmas in namespace \"%s\" with mismatched " - "name expansion", space); - return NULL; - } + { + cpp_error (pfile, CPP_DL_ICE, + "registering pragmas in namespace \"%s\" with mismatched " + "name expansion", space); + return NULL; + } chain = &entry->u.space; } else if (allow_name_expansion) { cpp_error (pfile, CPP_DL_ICE, - "registering pragma \"%s\" with name expansion " - "and no namespace", name); + "registering pragma \"%s\" with name expansion " + "and no namespace", name); return NULL; } @@ -1101,11 +1118,11 @@ register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, if (entry->is_nspace) clash: cpp_error (pfile, CPP_DL_ICE, - "registering \"%s\" as both a pragma and a pragma namespace", - NODE_NAME (node)); + "registering \"%s\" as both a pragma and a pragma namespace", + NODE_NAME (node)); else if (space) cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered", - space, name); + space, name); else cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name); @@ -1115,7 +1132,7 @@ register_pragma_1 (cpp_reader *pfile, const char *space, const char *name, /* Register a cpplib internal pragma SPACE NAME with HANDLER. */ static void register_pragma_internal (cpp_reader *pfile, const char *space, - const char *name, pragma_cb handler) + const char *name, pragma_cb handler) { struct pragma_entry *entry; @@ -1131,7 +1148,7 @@ register_pragma_internal (cpp_reader *pfile, const char *space, from libcpp. */ void cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, - pragma_cb handler, bool allow_expansion) + pragma_cb handler, bool allow_expansion) { struct pragma_entry *entry; @@ -1154,8 +1171,8 @@ cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name, with IDENT in the token->u.pragma slot. */ void cpp_register_deferred_pragma (cpp_reader *pfile, const char *space, - const char *name, unsigned int ident, - bool allow_expansion, bool allow_name_expansion) + const char *name, unsigned int ident, + bool allow_expansion, bool allow_name_expansion) { struct pragma_entry *entry; @@ -1166,7 +1183,7 @@ cpp_register_deferred_pragma (cpp_reader *pfile, const char *space, entry->allow_expansion = allow_expansion; entry->u.ident = ident; } -} +} /* Register the pragmas the preprocessor itself handles. */ void @@ -1178,7 +1195,7 @@ _cpp_init_internal_pragmas (cpp_reader *pfile) /* New GCC-specific pragmas should be put in the GCC namespace. */ register_pragma_internal (pfile, "GCC", "poison", do_pragma_poison); register_pragma_internal (pfile, "GCC", "system_header", - do_pragma_system_header); + do_pragma_system_header); register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency); } @@ -1191,7 +1208,7 @@ count_registered_pragmas (struct pragma_entry *pe) for (; pe != NULL; pe = pe->next) { if (pe->is_nspace) - ct += count_registered_pragmas (pe->u.space); + ct += count_registered_pragmas (pe->u.space); ct++; } return ct; @@ -1206,7 +1223,7 @@ save_registered_pragmas (struct pragma_entry *pe, char **sd) for (; pe != NULL; pe = pe->next) { if (pe->is_nspace) - sd = save_registered_pragmas (pe->u.space, sd); + sd = save_registered_pragmas (pe->u.space, sd); *sd++ = (char *) xmemdup (HT_STR (&pe->pragma->ident), HT_LEN (&pe->pragma->ident), HT_LEN (&pe->pragma->ident) + 1); @@ -1231,12 +1248,12 @@ _cpp_save_pragma_names (cpp_reader *pfile) static char ** restore_registered_pragmas (cpp_reader *pfile, struct pragma_entry *pe, - char **sd) + char **sd) { for (; pe != NULL; pe = pe->next) { if (pe->is_nspace) - sd = restore_registered_pragmas (pfile, pe->u.space, sd); + sd = restore_registered_pragmas (pfile, pe->u.space, sd); pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd)); free (*sd); sd++; @@ -1276,66 +1293,66 @@ do_pragma (cpp_reader *pfile) { p = lookup_pragma_entry (pfile->pragmas, token->val.node); if (p && p->is_nspace) - { - bool allow_name_expansion = p->allow_expansion; - if (allow_name_expansion) - pfile->state.prevent_expansion--; - token = cpp_get_token (pfile); - if (token->type == CPP_NAME) - p = lookup_pragma_entry (p->u.space, token->val.node); - else - p = NULL; - if (allow_name_expansion) - pfile->state.prevent_expansion++; - count = 2; - } + { + bool allow_name_expansion = p->allow_expansion; + if (allow_name_expansion) + pfile->state.prevent_expansion--; + token = cpp_get_token (pfile); + if (token->type == CPP_NAME) + p = lookup_pragma_entry (p->u.space, token->val.node); + else + p = NULL; + if (allow_name_expansion) + pfile->state.prevent_expansion++; + count = 2; + } } if (p) { if (p->is_deferred) - { - pfile->directive_result.src_loc = pragma_token->src_loc; - pfile->directive_result.type = CPP_PRAGMA; - pfile->directive_result.flags = pragma_token->flags; - pfile->directive_result.val.pragma = p->u.ident; - pfile->state.in_deferred_pragma = true; - pfile->state.pragma_allow_expansion = p->allow_expansion; - if (!p->allow_expansion) - pfile->state.prevent_expansion++; - } + { + pfile->directive_result.src_loc = pragma_token->src_loc; + pfile->directive_result.type = CPP_PRAGMA; + pfile->directive_result.flags = pragma_token->flags; + pfile->directive_result.val.pragma = p->u.ident; + pfile->state.in_deferred_pragma = true; + pfile->state.pragma_allow_expansion = p->allow_expansion; + if (!p->allow_expansion) + pfile->state.prevent_expansion++; + } else - { - /* Since the handler below doesn't get the line number, that - it might need for diagnostics, make sure it has the right - numbers in place. */ - if (pfile->cb.line_change) - (*pfile->cb.line_change) (pfile, pragma_token, false); - if (p->allow_expansion) - pfile->state.prevent_expansion--; - (*p->u.handler) (pfile); - if (p->allow_expansion) - pfile->state.prevent_expansion++; - } + { + /* Since the handler below doesn't get the line number, that + it might need for diagnostics, make sure it has the right + numbers in place. */ + if (pfile->cb.line_change) + (*pfile->cb.line_change) (pfile, pragma_token, false); + if (p->allow_expansion) + pfile->state.prevent_expansion--; + (*p->u.handler) (pfile); + if (p->allow_expansion) + pfile->state.prevent_expansion++; + } } else if (pfile->cb.def_pragma) { if (count == 1 || pfile->context->prev == NULL) - _cpp_backup_tokens (pfile, count); + _cpp_backup_tokens (pfile, count); else - { - /* Invalid name comes from macro expansion, _cpp_backup_tokens - won't allow backing 2 tokens. */ - /* ??? The token buffer is leaked. Perhaps if def_pragma hook - reads both tokens, we could perhaps free it, but if it doesn't, - we don't know the exact lifespan. */ - cpp_token *toks = XNEWVEC (cpp_token, 2); - toks[0] = ns_token; - toks[0].flags |= NO_EXPAND; - toks[1] = *token; - toks[1].flags |= NO_EXPAND; - _cpp_push_token_context (pfile, NULL, toks, 2); - } + { + /* Invalid name comes from macro expansion, _cpp_backup_tokens + won't allow backing 2 tokens. */ + /* ??? The token buffer is leaked. Perhaps if def_pragma hook + reads both tokens, we could perhaps free it, but if it doesn't, + we don't know the exact lifespan. */ + cpp_token *toks = XNEWVEC (cpp_token, 2); + toks[0] = ns_token; + toks[0].flags |= NO_EXPAND; + toks[1] = *token; + toks[1].flags |= NO_EXPAND; + _cpp_push_token_context (pfile, NULL, toks, 2); + } pfile->cb.def_pragma (pfile, pfile->directive_line); } @@ -1346,7 +1363,7 @@ do_pragma (cpp_reader *pfile) static void do_pragma_once (cpp_reader *pfile) { - if (pfile->buffer->prev == NULL) + if (cpp_in_primary_file (pfile)) cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file"); check_eol (pfile); @@ -1366,21 +1383,21 @@ do_pragma_poison (cpp_reader *pfile) { tok = _cpp_lex_token (pfile); if (tok->type == CPP_EOF) - break; + break; if (tok->type != CPP_NAME) - { - cpp_error (pfile, CPP_DL_ERROR, - "invalid #pragma GCC poison directive"); - break; - } + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid #pragma GCC poison directive"); + break; + } hp = tok->val.node; if (hp->flags & NODE_POISONED) - continue; + continue; if (hp->type == NT_MACRO) - cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", - NODE_NAME (hp)); + cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", + NODE_NAME (hp)); _cpp_free_definition (hp); hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC; } @@ -1396,11 +1413,9 @@ do_pragma_poison (cpp_reader *pfile) static void do_pragma_system_header (cpp_reader *pfile) { - cpp_buffer *buffer = pfile->buffer; - - if (buffer->prev == 0) + if (cpp_in_primary_file (pfile)) cpp_error (pfile, CPP_DL_WARNING, - "#pragma system_header ignored outside include file"); + "#pragma system_header ignored outside include file"); else { check_eol (pfile); @@ -1428,12 +1443,12 @@ do_pragma_dependency (cpp_reader *pfile) else if (ordering > 0) { cpp_error (pfile, CPP_DL_WARNING, - "current file is older than %s", fname); + "current file is older than %s", fname); if (cpp_get_token (pfile)->type != CPP_EOF) - { - _cpp_backup_tokens (pfile, 1); - do_diagnostic (pfile, CPP_DL_WARNING, 0); - } + { + _cpp_backup_tokens (pfile, 1); + do_diagnostic (pfile, CPP_DL_WARNING, 0); + } } free ((void *) fname); @@ -1447,7 +1462,7 @@ get_token_no_padding (cpp_reader *pfile) { const cpp_token *result = cpp_get_token (pfile); if (result->type != CPP_PADDING) - return result; + return result; } } @@ -1457,15 +1472,24 @@ static const cpp_token * get__Pragma_string (cpp_reader *pfile) { const cpp_token *string; + const cpp_token *paren; - if (get_token_no_padding (pfile)->type != CPP_OPEN_PAREN) + paren = get_token_no_padding (pfile); + if (paren->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + if (paren->type != CPP_OPEN_PAREN) return NULL; string = get_token_no_padding (pfile); + if (string->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); if (string->type != CPP_STRING && string->type != CPP_WSTRING) return NULL; - if (get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN) + paren = get_token_no_padding (pfile); + if (paren->type == CPP_EOF) + _cpp_backup_tokens (pfile, 1); + if (paren->type != CPP_CLOSE_PAREN) return NULL; return string; @@ -1491,7 +1515,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) { /* We know there is a character following the backslash. */ if (*src == '\\' && (src[1] == '\\' || src[1] == '"')) - src++; + src++; *dest++ = *src++; } *dest = '\n'; @@ -1516,7 +1540,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) /* Inline run_directive, since we need to delay the _cpp_pop_buffer until we've read all of the tokens that we want. */ cpp_push_buffer (pfile, (const uchar *) result, dest - result, - /* from_stage3 */ true); + /* from_stage3 */ true); /* ??? Antique Disgusting Hack. What does this do? */ if (pfile->buffer->prev) pfile->buffer->file = pfile->buffer->prev->file; @@ -1527,7 +1551,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) end_directive (pfile, 1); /* We always insert at least one token, the directive result. It'll - either be a CPP_PADDING or a CPP_PRAGMA. In the later case, we + either be a CPP_PADDING or a CPP_PRAGMA. In the later case, we need to insert *all* of the tokens, including the CPP_PRAGMA_EOL. */ /* If we're not handling the pragma internally, read all of the tokens from @@ -1546,17 +1570,17 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) toks[0] = pfile->directive_result; do - { - if (count == maxcount) - { - maxcount = maxcount * 3 / 2; - toks = XRESIZEVEC (cpp_token, toks, maxcount); - } - toks[count] = *cpp_get_token (pfile); - /* Macros have been already expanded by cpp_get_token - if the pragma allowed expansion. */ - toks[count++].flags |= NO_EXPAND; - } + { + if (count == maxcount) + { + maxcount = maxcount * 3 / 2; + toks = XRESIZEVEC (cpp_token, toks, maxcount); + } + toks[count] = *cpp_get_token (pfile); + /* Macros have been already expanded by cpp_get_token + if the pragma allowed expansion. */ + toks[count++].flags |= NO_EXPAND; + } while (toks[count-1].type != CPP_PRAGMA_EOL); } else @@ -1566,9 +1590,9 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) toks[0] = pfile->directive_result; /* If we handled the entire pragma internally, make sure we get the - line number correct for the next token. */ + line number correct for the next token. */ if (pfile->cb.line_change) - pfile->cb.line_change (pfile, pfile->cur_token, false); + pfile->cb.line_change (pfile, pfile->cur_token, false); } /* Finish inlining run_directive. */ @@ -1585,18 +1609,21 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) _cpp_push_token_context (pfile, NULL, toks, count); } -/* Handle the _Pragma operator. */ -void +/* Handle the _Pragma operator. Return 0 on error, 1 if ok. */ +int _cpp_do__Pragma (cpp_reader *pfile) { const cpp_token *string = get__Pragma_string (pfile); pfile->directive_result.type = CPP_PADDING; if (string) - destringize_and_run (pfile, &string->val.str); - else - cpp_error (pfile, CPP_DL_ERROR, - "_Pragma takes a parenthesized string literal"); + { + destringize_and_run (pfile, &string->val.str); + return 1; + } + cpp_error (pfile, CPP_DL_ERROR, + "_Pragma takes a parenthesized string literal"); + return 0; } /* Handle #ifdef. */ @@ -1607,14 +1634,14 @@ do_ifdef (cpp_reader *pfile) if (! pfile->state.skipping) { - const cpp_hashnode *node = lex_macro_node (pfile); + const cpp_hashnode *node = lex_macro_node (pfile, false); if (node) - { - skip = node->type != NT_MACRO; - _cpp_mark_macro_used (node); - check_eol (pfile); - } + { + skip = node->type != NT_MACRO; + _cpp_mark_macro_used (node); + check_eol (pfile); + } } push_conditional (pfile, skip, T_IFDEF, 0); @@ -1629,14 +1656,14 @@ do_ifndef (cpp_reader *pfile) if (! pfile->state.skipping) { - node = lex_macro_node (pfile); + node = lex_macro_node (pfile, false); if (node) - { - skip = node->type == NT_MACRO; - _cpp_mark_macro_used (node); - check_eol (pfile); - } + { + skip = node->type == NT_MACRO; + _cpp_mark_macro_used (node); + check_eol (pfile); + } } push_conditional (pfile, skip, T_IFNDEF, node); @@ -1672,11 +1699,11 @@ do_else (cpp_reader *pfile) else { if (ifs->type == T_ELSE) - { - cpp_error (pfile, CPP_DL_ERROR, "#else after #else"); - cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, - "the conditional began here"); - } + { + cpp_error (pfile, CPP_DL_ERROR, "#else after #else"); + cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, + "the conditional began here"); + } ifs->type = T_ELSE; /* Skip any future (erroneous) #elses or #elifs. */ @@ -1688,7 +1715,7 @@ do_else (cpp_reader *pfile) /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile); + check_eol (pfile); } } @@ -1705,23 +1732,23 @@ do_elif (cpp_reader *pfile) else { if (ifs->type == T_ELSE) - { - cpp_error (pfile, CPP_DL_ERROR, "#elif after #else"); - cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, - "the conditional began here"); - } + { + cpp_error (pfile, CPP_DL_ERROR, "#elif after #else"); + cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, + "the conditional began here"); + } ifs->type = T_ELIF; /* Only evaluate this if we aren't skipping elses. During - evaluation, set skipping to false to get lexer warnings. */ + evaluation, set skipping to false to get lexer warnings. */ if (ifs->skip_elses) - pfile->state.skipping = 1; + pfile->state.skipping = 1; else - { - pfile->state.skipping = 0; - pfile->state.skipping = ! _cpp_parse_expr (pfile); - ifs->skip_elses = ! pfile->state.skipping; - } + { + pfile->state.skipping = 0; + pfile->state.skipping = ! _cpp_parse_expr (pfile); + ifs->skip_elses = ! pfile->state.skipping; + } /* Invalidate any controlling macro. */ ifs->mi_cmacro = 0; @@ -1741,14 +1768,14 @@ do_endif (cpp_reader *pfile) { /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile); + check_eol (pfile); /* If potential control macro, we go back outside again. */ if (ifs->next == 0 && ifs->mi_cmacro) - { - pfile->mi_valid = true; - pfile->mi_cmacro = ifs->mi_cmacro; - } + { + pfile->mi_valid = true; + pfile->mi_cmacro = ifs->mi_cmacro; + } buffer->if_stack = ifs->next; pfile->state.skipping = ifs->was_skipping; @@ -1762,7 +1789,7 @@ do_endif (cpp_reader *pfile) we need to check here that we are at the top of the file. */ static void push_conditional (cpp_reader *pfile, int skip, int type, - const cpp_hashnode *cmacro) + const cpp_hashnode *cmacro) { struct if_stack *ifs; cpp_buffer *buffer = pfile->buffer; @@ -1804,14 +1831,14 @@ parse_answer (cpp_reader *pfile, struct answer **answerp, int type) /* In a conditional no answer is a test for any answer. It could be followed by any token. */ if (type == T_IF) - { - _cpp_backup_tokens (pfile, 1); - return 0; - } + { + _cpp_backup_tokens (pfile, 1); + return 0; + } /* #unassert with no answer is valid - it removes all answers. */ if (type == T_UNASSERT && paren->type == CPP_EOF) - return 0; + return 0; cpp_error (pfile, CPP_DL_ERROR, "missing '(' after predicate"); return 1; @@ -1824,26 +1851,26 @@ parse_answer (cpp_reader *pfile, struct answer **answerp, int type) cpp_token *dest; if (token->type == CPP_CLOSE_PAREN) - break; + break; if (token->type == CPP_EOF) - { - cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer"); - return 1; - } + { + cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer"); + return 1; + } /* struct answer includes the space for one token. */ room_needed = (sizeof (struct answer) + acount * sizeof (cpp_token)); if (BUFF_ROOM (pfile->a_buff) < room_needed) - _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer)); + _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer)); dest = &((struct answer *) BUFF_FRONT (pfile->a_buff))->first[acount]; *dest = *token; /* Drop whitespace at start, for answer equivalence purposes. */ if (acount == 0) - dest->flags &= ~PREV_WHITE; + dest->flags &= ~PREV_WHITE; } if (acount == 0) @@ -1906,14 +1933,14 @@ find_answer (cpp_hashnode *node, const struct answer *candidate) struct answer *answer = *result; if (answer->count == candidate->count) - { - for (i = 0; i < answer->count; i++) - if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i])) - break; + { + for (i = 0; i < answer->count; i++) + if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i])) + break; - if (i == answer->count) - break; - } + if (i == answer->count) + break; + } } return result; @@ -1936,7 +1963,7 @@ _cpp_test_assertion (cpp_reader *pfile, unsigned int *value) if (node) *value = (node->type == NT_ASSERTION && - (answer == 0 || *find_answer (node, answer) != 0)); + (answer == 0 || *find_answer (node, answer) != 0)); else if (pfile->cur_token[-1].type == CPP_EOF) _cpp_backup_tokens (pfile, 1); @@ -1960,28 +1987,28 @@ do_assert (cpp_reader *pfile) is not a duplicate. */ new_answer->next = 0; if (node->type == NT_ASSERTION) - { - if (*find_answer (node, new_answer)) - { - cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", - NODE_NAME (node) + 1); - return; - } - new_answer->next = node->value.answers; - } + { + if (*find_answer (node, new_answer)) + { + cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", + NODE_NAME (node) + 1); + return; + } + new_answer->next = node->value.answers; + } answer_size = sizeof (struct answer) + ((new_answer->count - 1) - * sizeof (cpp_token)); + * sizeof (cpp_token)); /* Commit or allocate storage for the object. */ if (pfile->hash_table->alloc_subobject) - { - struct answer *temp_answer = new_answer; - new_answer = (struct answer *) pfile->hash_table->alloc_subobject + { + struct answer *temp_answer = new_answer; + new_answer = (struct answer *) pfile->hash_table->alloc_subobject (answer_size); - memcpy (new_answer, temp_answer, answer_size); - } + memcpy (new_answer, temp_answer, answer_size); + } else - BUFF_FRONT (pfile->a_buff) += answer_size; + BUFF_FRONT (pfile->a_buff) += answer_size; node->type = NT_ASSERTION; node->value.answers = new_answer; @@ -2001,22 +2028,22 @@ do_unassert (cpp_reader *pfile) if (node && node->type == NT_ASSERTION) { if (answer) - { - struct answer **p = find_answer (node, answer), *temp; + { + struct answer **p = find_answer (node, answer), *temp; - /* Remove the answer from the list. */ - temp = *p; - if (temp) - *p = temp->next; + /* Remove the answer from the list. */ + temp = *p; + if (temp) + *p = temp->next; - /* Did we free the last answer? */ - if (node->value.answers == 0) - node->type = NT_VOID; + /* Did we free the last answer? */ + if (node->value.answers == 0) + node->type = NT_VOID; - check_eol (pfile); - } + check_eol (pfile); + } else - _cpp_free_definition (node); + _cpp_free_definition (node); } /* We don't commit the memory for the answer - it's temporary only. */ @@ -2077,6 +2104,65 @@ cpp_undef (cpp_reader *pfile, const char *macro) run_directive (pfile, T_UNDEF, buf, len); } +/* Like lex_macro_node, but read the input from STR. */ +static cpp_hashnode * +lex_macro_node_from_str (cpp_reader *pfile, const char *str) +{ + size_t len = strlen (str); + uchar *buf = (uchar *) alloca (len + 1); + cpp_hashnode *node; + + memcpy (buf, str, len); + buf[len] = '\n'; + cpp_push_buffer (pfile, buf, len, true); + node = lex_macro_node (pfile, true); + _cpp_pop_buffer (pfile); + + return node; +} + +/* If STR is a defined macro, return its definition node, else return NULL. */ +cpp_macro * +cpp_push_definition (cpp_reader *pfile, const char *str) +{ + cpp_hashnode *node = lex_macro_node_from_str (pfile, str); + if (node && node->type == NT_MACRO) + return node->value.macro; + else + return NULL; +} + +/* Replace a previous definition DFN of the macro STR. If DFN is NULL, + then the macro should be undefined. */ +void +cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn) +{ + cpp_hashnode *node = lex_macro_node_from_str (pfile, str); + if (node == NULL) + return; + + if (node->type == NT_MACRO) + { + if (pfile->cb.undef) + pfile->cb.undef (pfile, pfile->directive_line, node); + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + } + if (node->type != NT_VOID) + _cpp_free_definition (node); + + if (dfn) + { + node->type = NT_MACRO; + node->value.macro = dfn; + if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))) + node->flags |= NODE_WARN; + + if (pfile->cb.define) + pfile->cb.define (pfile, pfile->directive_line, node); + } +} + /* Process the string STR as if it appeared as the body of a #assert. */ void cpp_assert (cpp_reader *pfile, const char *str) @@ -2156,7 +2242,7 @@ cpp_get_deps (cpp_reader *pfile) is the responsibility of the caller. */ cpp_buffer * cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len, - int from_stage3) + int from_stage3) { cpp_buffer *new_buffer = XOBNEW (&pfile->buffer_ob, cpp_buffer); @@ -2187,7 +2273,7 @@ _cpp_pop_buffer (cpp_reader *pfile) entry to this file, issuing error messages. */ for (ifs = buffer->if_stack; ifs; ifs = ifs->next) cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, - "unterminated #%s", dtable[ifs->type].name); + "unterminated #%s", dtable[ifs->type].name); /* In case of a missing #endif. */ pfile->state.skipping = 0; diff --git a/support/cpp2/libcpp/errors.c b/support/cpp/libcpp/errors.c similarity index 100% rename from support/cpp2/libcpp/errors.c rename to support/cpp/libcpp/errors.c diff --git a/support/cpp2/libcpp/expr.c b/support/cpp/libcpp/expr.c similarity index 55% rename from support/cpp2/libcpp/expr.c rename to support/cpp/libcpp/expr.c index 574b85ff..8ac90108 100644 --- a/support/cpp2/libcpp/expr.c +++ b/support/cpp/libcpp/expr.c @@ -30,8 +30,8 @@ Boston, MA 02110-1301, USA. */ struct op { - const cpp_token *token; /* The token forming op (for diagnostics). */ - cpp_num value; /* The value logically "right" of op. */ + const cpp_token *token; /* The token forming op (for diagnostics). */ + cpp_num value; /* The value logically "right" of op. */ enum cpp_ttype op; }; @@ -48,9 +48,9 @@ static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); static cpp_num num_negate (cpp_num, size_t); static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num, - enum cpp_ttype); + enum cpp_ttype); static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num, - enum cpp_ttype); + enum cpp_ttype); static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num); static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); static cpp_num num_lshift (cpp_num, size_t, size_t); @@ -82,26 +82,77 @@ static void check_promotion (cpp_reader *, const struct op *); static unsigned int interpret_float_suffix (const uchar *s, size_t len) { - size_t f = 0, l = 0, i = 0, d = 0; + size_t f, l, w, q, i, d; + size_t r, k, u, h; + + f = l = w = q = i = d = 0; + r = k = u = h = 0; while (len--) switch (s[len]) { - case 'f': case 'F': f++; break; - case 'l': case 'L': l++; break; + case 'r': case 'R': r++; break; + case 'k': case 'K': k++; break; + case 'u': case 'U': u++; break; + case 'h': case 'H': h++; break; + case 'f': case 'F': + if (d > 0) + return 0; + f++; + break; + case 'l': case 'L': + if (d > 0) + return 0; + l++; + /* If there are two Ls, they must be adjacent and the same case. */ + if (l == 2 && s[len] != s[len + 1]) + return 0; + break; + case 'w': case 'W': + if (d > 0) + return 0; + w++; + break; + case 'q': case 'Q': + if (d > 0) + return 0; + q++; + break; case 'i': case 'I': case 'j': case 'J': i++; break; - case 'd': case 'D': - /* Disallow fd, ld suffixes. */ - if (d && (f || l)) - return 0; - d++; - break; + case 'd': case 'D': d++; break; default: - return 0; + return 0; } - if (f + l > 1 || i > 1) + if (r + k > 1 || h > 1 || l > 2 || u > 1) + return 0; + + if (r == 1) + { + if (f || i || d || w || q) + return 0; + + return (CPP_N_FRACT + | (u ? CPP_N_UNSIGNED : 0) + | (h ? CPP_N_SMALL : + l == 2 ? CPP_N_LARGE : + l == 1 ? CPP_N_MEDIUM : 0)); + } + + if (k == 1) + { + if (f || i || d || w || q) + return 0; + + return (CPP_N_ACCUM + | (u ? CPP_N_UNSIGNED : 0) + | (h ? CPP_N_SMALL : + l == 2 ? CPP_N_LARGE : + l == 1 ? CPP_N_MEDIUM : 0)); + } + + if (f + l + w + q > 1 || i > 1 || h + u > 0) return 0; /* Allow dd, df, dl suffixes for decimal float constants. */ @@ -109,9 +160,11 @@ interpret_float_suffix (const uchar *s, size_t len) return 0; return ((i ? CPP_N_IMAGINARY : 0) - | (f ? CPP_N_SMALL : - l ? CPP_N_LARGE : CPP_N_MEDIUM) - | (d ? CPP_N_DFLOAT : 0)); + | (f ? CPP_N_SMALL : + l ? CPP_N_LARGE : + w ? CPP_N_MD_W : + q ? CPP_N_MD_Q : CPP_N_MEDIUM) + | (d ? CPP_N_DFLOAT : 0)); } /* Subroutine of cpp_classify_number. S points to an integer suffix @@ -127,25 +180,25 @@ interpret_int_suffix (const uchar *s, size_t len) while (len--) switch (s[len]) { - case 'u': case 'U': u++; break; + case 'u': case 'U': u++; break; case 'i': case 'I': - case 'j': case 'J': i++; break; - case 'l': case 'L': l++; - /* If there are two Ls, they must be adjacent and the same case. */ - if (l == 2 && s[len] != s[len + 1]) - return 0; - break; + case 'j': case 'J': i++; break; + case 'l': case 'L': l++; + /* If there are two Ls, they must be adjacent and the same case. */ + if (l == 2 && s[len] != s[len + 1]) + return 0; + break; default: - return 0; + return 0; } if (l > 2 || u > 1 || i > 1) return 0; return ((i ? CPP_N_IMAGINARY : 0) - | (u ? CPP_N_UNSIGNED : 0) - | ((l == 0) ? CPP_N_SMALL - : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)); + | (u ? CPP_N_UNSIGNED : 0) + | ((l == 0) ? CPP_N_SMALL + : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)); } /* Categorize numeric constants according to their field (integer, @@ -177,11 +230,16 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) /* Require at least one hex digit to classify it as hex. */ if ((*str == 'x' || *str == 'X') - && (str[1] == '.' || ISXDIGIT (str[1]))) - { - radix = 16; - str++; - } + && (str[1] == '.' || ISXDIGIT (str[1]))) + { + radix = 16; + str++; + } + else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) + { + radix = 2; + str++; + } } /* Now scan for a well-formed integer or float. */ @@ -190,76 +248,108 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) unsigned int c = *str++; if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16)) - { - c = hex_value (c); - if (c > max_digit) - max_digit = c; - } + { + c = hex_value (c); + if (c > max_digit) + max_digit = c; + } else if (c == '.') - { - if (float_flag == NOT_FLOAT) - float_flag = AFTER_POINT; - else - SYNTAX_ERROR ("too many decimal points in number"); - } + { + if (float_flag == NOT_FLOAT) + float_flag = AFTER_POINT; + else + SYNTAX_ERROR ("too many decimal points in number"); + } else if ((radix <= 10 && (c == 'e' || c == 'E')) - || (radix == 16 && (c == 'p' || c == 'P'))) - { - float_flag = AFTER_EXPON; - break; - } + || (radix == 16 && (c == 'p' || c == 'P'))) + { + float_flag = AFTER_EXPON; + break; + } else - { - /* Start of suffix. */ - str--; - break; - } + { + /* Start of suffix. */ + str--; + break; + } + } + + /* The suffix may be for decimal fixed-point constants without exponent. */ + if (radix != 16 && float_flag == NOT_FLOAT) + { + result = interpret_float_suffix (str, limit - str); + if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM)) + { + result |= CPP_N_FLOATING; + /* We need to restore the radix to 10, if the radix is 8. */ + if (radix == 8) + radix = 10; + + if (CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "fixed-point constants are a GCC extension"); + goto syntax_ok; + } + else + result = 0; } if (float_flag != NOT_FLOAT && radix == 8) radix = 10; if (max_digit >= radix) - SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit); + { + if (radix == 2) + SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit); + else + SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit); + } if (float_flag != NOT_FLOAT) { + if (radix == 2) + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid prefix \"0b\" for floating constant"); + return CPP_N_INVALID; + } + if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99)) - cpp_error (pfile, CPP_DL_PEDWARN, - "use of C99 hexadecimal floating constant"); + cpp_error (pfile, CPP_DL_PEDWARN, + "use of C99 hexadecimal floating constant"); if (float_flag == AFTER_EXPON) - { - if (*str == '+' || *str == '-') - str++; - - /* Exponent is decimal, even if string is a hex float. */ - if (!ISDIGIT (*str)) - SYNTAX_ERROR ("exponent has no digits"); - - do - str++; - while (ISDIGIT (*str)); - } + { + if (*str == '+' || *str == '-') + str++; + + /* Exponent is decimal, even if string is a hex float. */ + if (!ISDIGIT (*str)) + SYNTAX_ERROR ("exponent has no digits"); + + do + str++; + while (ISDIGIT (*str)); + } else if (radix == 16) - SYNTAX_ERROR ("hexadecimal floating constants require an exponent"); + SYNTAX_ERROR ("hexadecimal floating constants require an exponent"); result = interpret_float_suffix (str, limit - str); if (result == 0) - { - cpp_error (pfile, CPP_DL_ERROR, - "invalid suffix \"%.*s\" on floating constant", - (int) (limit - str), str); - return CPP_N_INVALID; - } + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" on floating constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } /* Traditional C didn't accept any floating suffixes. */ if (limit != str - && CPP_WTRADITIONAL (pfile) - && ! cpp_sys_macro_p (pfile)) - cpp_error (pfile, CPP_DL_WARNING, - "traditional C rejects the \"%.*s\" suffix", - (int) (limit - str), str); + && CPP_WTRADITIONAL (pfile) + && ! cpp_sys_macro_p (pfile)) + cpp_error (pfile, CPP_DL_WARNING, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); /* Radix must be 10 for decimal floats. */ if ((result & CPP_N_DFLOAT) && radix != 10) @@ -270,49 +360,63 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) return CPP_N_INVALID; } + if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "fixed-point constants are a GCC extension"); + + if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "decimal float constants are a GCC extension"); + result |= CPP_N_FLOATING; } else { result = interpret_int_suffix (str, limit - str); if (result == 0) - { - cpp_error (pfile, CPP_DL_ERROR, - "invalid suffix \"%.*s\" on integer constant", - (int) (limit - str), str); - return CPP_N_INVALID; - } + { + cpp_error (pfile, CPP_DL_ERROR, + "invalid suffix \"%.*s\" on integer constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } /* Traditional C only accepted the 'L' suffix. Suppress warning about 'LL' with -Wno-long-long. */ if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile)) - { - int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY)); - int large = (result & CPP_N_WIDTH) == CPP_N_LARGE; + { + int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY)); + int large = (result & CPP_N_WIDTH) == CPP_N_LARGE; - if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long))) - cpp_error (pfile, CPP_DL_WARNING, - "traditional C rejects the \"%.*s\" suffix", - (int) (limit - str), str); - } + if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long))) + cpp_error (pfile, CPP_DL_WARNING, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); + } if ((result & CPP_N_WIDTH) == CPP_N_LARGE - && ! CPP_OPTION (pfile, c99) - && CPP_OPTION (pfile, warn_long_long)) - cpp_error (pfile, CPP_DL_PEDWARN, - "use of C99 long long integer constant"); + && ! CPP_OPTION (pfile, c99) + && CPP_OPTION (pfile, warn_long_long)) + cpp_error (pfile, CPP_DL_PEDWARN, + "use of C99 long long integer constant"); result |= CPP_N_INTEGER; } + syntax_ok: if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile)) cpp_error (pfile, CPP_DL_PEDWARN, - "imaginary constants are a GCC extension"); + "imaginary constants are a GCC extension"); + if (radix == 2 && CPP_PEDANTIC (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "binary constants are a GCC extension"); if (radix == 10) result |= CPP_N_DECIMAL; else if (radix == 16) result |= CPP_N_HEX; + else if (radix == 2) + result |= CPP_N_BINARY; else result |= CPP_N_OCTAL; @@ -330,7 +434,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) drag in GCC's floating point emulator. */ cpp_num cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, - unsigned int type) + unsigned int type) { const uchar *p, *end; cpp_num result; @@ -354,60 +458,65 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, bool overflow = false; if ((type & CPP_N_RADIX) == CPP_N_OCTAL) - { - base = 8; - p++; - } + { + base = 8; + p++; + } else if ((type & CPP_N_RADIX) == CPP_N_HEX) - { - base = 16; - p += 2; - } + { + base = 16; + p += 2; + } + else if ((type & CPP_N_RADIX) == CPP_N_BINARY) + { + base = 2; + p += 2; + } /* We can add a digit to numbers strictly less than this without - needing the precision and slowness of double integers. */ + needing the precision and slowness of double integers. */ max = ~(cpp_num_part) 0; if (precision < PART_PRECISION) - max >>= PART_PRECISION - precision; + max >>= PART_PRECISION - precision; max = (max - base + 1) / base + 1; for (; p < end; p++) - { - c = *p; - - if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c))) - c = hex_value (c); - else - break; - - /* Strict inequality for when max is set to zero. */ - if (result.low < max) - result.low = result.low * base + c; - else - { - result = append_digit (result, c, base, precision); - overflow |= result.overflow; - max = 0; - } - } + { + c = *p; + + if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c))) + c = hex_value (c); + else + break; + + /* Strict inequality for when max is set to zero. */ + if (result.low < max) + result.low = result.low * base + c; + else + { + result = append_digit (result, c, base, precision); + overflow |= result.overflow; + max = 0; + } + } if (overflow) - cpp_error (pfile, CPP_DL_PEDWARN, - "integer constant is too large for its type"); + cpp_error (pfile, CPP_DL_PEDWARN, + "integer constant is too large for its type"); /* If too big to be signed, consider it unsigned. Only warn for - decimal numbers. Traditional numbers were always signed (but - we still honor an explicit U suffix); but we only have - traditional semantics in directives. */ + decimal numbers. Traditional numbers were always signed (but + we still honor an explicit U suffix); but we only have + traditional semantics in directives. */ else if (!result.unsignedp - && !(CPP_OPTION (pfile, traditional) - && pfile->state.in_directive) - && !num_positive (result, precision)) - { - if (base == 10) - cpp_error (pfile, CPP_DL_WARNING, - "integer constant is so large that it is unsigned"); - result.unsignedp = true; - } + && !(CPP_OPTION (pfile, traditional) + && pfile->state.in_directive) + && !num_positive (result, precision)) + { + if (base == 10) + cpp_error (pfile, CPP_DL_WARNING, + "integer constant is so large that it is unsigned"); + result.unsignedp = true; + } } return result; @@ -418,12 +527,25 @@ static cpp_num append_digit (cpp_num num, int digit, int base, size_t precision) { cpp_num result; - unsigned int shift = 3 + (base == 16); + unsigned int shift; bool overflow; cpp_num_part add_high, add_low; - /* Multiply by 8 or 16. Catching this overflow here means we don't + /* Multiply by 2, 8 or 16. Catching this overflow here means we don't need to worry about add_high overflowing. */ + switch (base) + { + case 2: + shift = 1; + break; + + case 16: + shift = 4; + break; + + default: + shift = 3; + } overflow = !!(num.high >> (PART_PRECISION - shift)); result.high = num.high << shift; result.low = num.low << shift; @@ -441,7 +563,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) @@ -486,38 +608,38 @@ parse_defined (cpp_reader *pfile) { node = token->val.node; if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN) - { - cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\""); - node = 0; - } + { + cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\""); + node = 0; + } } else { cpp_error (pfile, CPP_DL_ERROR, - "operator \"defined\" requires an identifier"); + "operator \"defined\" requires an identifier"); if (token->flags & NAMED_OP) - { - cpp_token op; - - op.flags = 0; - op.type = token->type; - cpp_error (pfile, CPP_DL_ERROR, - "(\"%s\" is an alternative token for \"%s\" in C++)", - cpp_token_as_text (pfile, token), - cpp_token_as_text (pfile, &op)); - } + { + cpp_token op; + + op.flags = 0; + op.type = token->type; + cpp_error (pfile, CPP_DL_ERROR, + "(\"%s\" is an alternative token for \"%s\" in C++)", + cpp_token_as_text (pfile, token), + cpp_token_as_text (pfile, &op)); + } } if (node) { if (pfile->context != initial_context && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_WARNING, - "this use of \"defined\" may not be portable"); + cpp_error (pfile, CPP_DL_WARNING, + "this use of \"defined\" may not be portable"); _cpp_mark_macro_used (node); /* A possible controlling macro of the form #if !defined (). - _cpp_parse_expr checks there was no other junk on the line. */ + _cpp_parse_expr checks there was no other junk on the line. */ pfile->mi_ind_cmacro = node; } @@ -548,63 +670,63 @@ eval_token (cpp_reader *pfile, const cpp_token *token) case CPP_NUMBER: temp = cpp_classify_number (pfile, token); switch (temp & CPP_N_CATEGORY) - { - case CPP_N_FLOATING: - cpp_error (pfile, CPP_DL_ERROR, - "floating constant in preprocessor expression"); - break; - case CPP_N_INTEGER: - if (!(temp & CPP_N_IMAGINARY)) - return cpp_interpret_integer (pfile, token, temp); - cpp_error (pfile, CPP_DL_ERROR, - "imaginary number in preprocessor expression"); - break; - - case CPP_N_INVALID: - /* Error already issued. */ - break; - } + { + case CPP_N_FLOATING: + cpp_error (pfile, CPP_DL_ERROR, + "floating constant in preprocessor expression"); + break; + case CPP_N_INTEGER: + if (!(temp & CPP_N_IMAGINARY)) + return cpp_interpret_integer (pfile, token, temp); + cpp_error (pfile, CPP_DL_ERROR, + "imaginary number in preprocessor expression"); + break; + + case CPP_N_INVALID: + /* Error already issued. */ + break; + } result.high = result.low = 0; break; case CPP_WCHAR: case CPP_CHAR: { - cppchar_t cc = cpp_interpret_charconst (pfile, token, - &temp, &unsignedp); - - result.high = 0; - result.low = cc; - /* Sign-extend the result if necessary. */ - if (!unsignedp && (cppchar_signed_t) cc < 0) - { - if (PART_PRECISION > BITS_PER_CPPCHAR_T) - result.low |= ~(~(cpp_num_part) 0 - >> (PART_PRECISION - BITS_PER_CPPCHAR_T)); - result.high = ~(cpp_num_part) 0; - result = num_trim (result, CPP_OPTION (pfile, precision)); - } + cppchar_t cc = cpp_interpret_charconst (pfile, token, + &temp, &unsignedp); + + result.high = 0; + result.low = cc; + /* Sign-extend the result if necessary. */ + if (!unsignedp && (cppchar_signed_t) cc < 0) + { + if (PART_PRECISION > BITS_PER_CPPCHAR_T) + result.low |= ~(~(cpp_num_part) 0 + >> (PART_PRECISION - BITS_PER_CPPCHAR_T)); + result.high = ~(cpp_num_part) 0; + result = num_trim (result, CPP_OPTION (pfile, precision)); + } } break; case CPP_NAME: if (token->val.node == pfile->spec_nodes.n_defined) - return parse_defined (pfile); + return parse_defined (pfile); else if (CPP_OPTION (pfile, cplusplus) - && (token->val.node == pfile->spec_nodes.n_true - || token->val.node == pfile->spec_nodes.n_false)) - { - result.high = 0; - result.low = (token->val.node == pfile->spec_nodes.n_true); - } + && (token->val.node == pfile->spec_nodes.n_true + || token->val.node == pfile->spec_nodes.n_false)) + { + result.high = 0; + result.low = (token->val.node == pfile->spec_nodes.n_true); + } else - { - result.high = 0; - result.low = 0; - if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval) - cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined", - NODE_NAME (token->val.node)); - } + { + result.high = 0; + result.low = 0; + if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval) + cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined", + NODE_NAME (token->val.node)); + } break; default: /* CPP_HASH */ @@ -641,9 +763,9 @@ extra semantics need to be handled with operator-specific code. */ /* Flags. If CHECK_PROMOTION, we warn if the effective sign of an operand changes because of integer promotions. */ -#define NO_L_OPERAND (1 << 0) -#define LEFT_ASSOC (1 << 1) -#define CHECK_PROMOTION (1 << 2) +#define NO_L_OPERAND (1 << 0) +#define LEFT_ASSOC (1 << 1) +#define CHECK_PROMOTION (1 << 2) /* Operator to priority map. Must be in the same order as the first N entries of enum cpp_ttype. */ @@ -653,36 +775,36 @@ static const struct cpp_operator uchar flags; } optab[] = { - /* EQ */ {0, 0}, /* Shouldn't happen. */ - /* NOT */ {16, NO_L_OPERAND}, - /* GREATER */ {12, LEFT_ASSOC | CHECK_PROMOTION}, - /* LESS */ {12, LEFT_ASSOC | CHECK_PROMOTION}, - /* PLUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, - /* MINUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, - /* MULT */ {15, LEFT_ASSOC | CHECK_PROMOTION}, - /* DIV */ {15, LEFT_ASSOC | CHECK_PROMOTION}, - /* MOD */ {15, LEFT_ASSOC | CHECK_PROMOTION}, - /* AND */ {9, LEFT_ASSOC | CHECK_PROMOTION}, - /* OR */ {7, LEFT_ASSOC | CHECK_PROMOTION}, - /* XOR */ {8, LEFT_ASSOC | CHECK_PROMOTION}, - /* RSHIFT */ {13, LEFT_ASSOC}, - /* LSHIFT */ {13, LEFT_ASSOC}, - - /* COMPL */ {16, NO_L_OPERAND}, - /* AND_AND */ {6, LEFT_ASSOC}, - /* OR_OR */ {5, LEFT_ASSOC}, - /* QUERY */ {3, 0}, - /* COLON */ {4, LEFT_ASSOC | CHECK_PROMOTION}, - /* COMMA */ {2, LEFT_ASSOC}, - /* OPEN_PAREN */ {1, NO_L_OPERAND}, - /* CLOSE_PAREN */ {0, 0}, - /* EOF */ {0, 0}, - /* EQ_EQ */ {11, LEFT_ASSOC}, - /* NOT_EQ */ {11, LEFT_ASSOC}, - /* GREATER_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, - /* LESS_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, - /* UPLUS */ {16, NO_L_OPERAND}, - /* UMINUS */ {16, NO_L_OPERAND} + /* EQ */ {0, 0}, /* Shouldn't happen. */ + /* NOT */ {16, NO_L_OPERAND}, + /* GREATER */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* LESS */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* PLUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, + /* MINUS */ {14, LEFT_ASSOC | CHECK_PROMOTION}, + /* MULT */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* DIV */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* MOD */ {15, LEFT_ASSOC | CHECK_PROMOTION}, + /* AND */ {9, LEFT_ASSOC | CHECK_PROMOTION}, + /* OR */ {7, LEFT_ASSOC | CHECK_PROMOTION}, + /* XOR */ {8, LEFT_ASSOC | CHECK_PROMOTION}, + /* RSHIFT */ {13, LEFT_ASSOC}, + /* LSHIFT */ {13, LEFT_ASSOC}, + + /* COMPL */ {16, NO_L_OPERAND}, + /* AND_AND */ {6, LEFT_ASSOC}, + /* OR_OR */ {5, LEFT_ASSOC}, + /* QUERY */ {3, 0}, + /* COLON */ {4, LEFT_ASSOC | CHECK_PROMOTION}, + /* COMMA */ {2, LEFT_ASSOC}, + /* OPEN_PAREN */ {1, NO_L_OPERAND}, + /* CLOSE_PAREN */ {0, 0}, + /* EOF */ {0, 0}, + /* EQ_EQ */ {11, LEFT_ASSOC}, + /* NOT_EQ */ {11, LEFT_ASSOC}, + /* GREATER_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* LESS_EQ */ {12, LEFT_ASSOC | CHECK_PROMOTION}, + /* UPLUS */ {16, NO_L_OPERAND}, + /* UMINUS */ {16, NO_L_OPERAND} }; /* Parse and evaluate a C expression, reading from PFILE. @@ -722,102 +844,102 @@ _cpp_parse_expr (cpp_reader *pfile) op.op = op.token->type; switch (op.op) - { - /* These tokens convert into values. */ - case CPP_NUMBER: - case CPP_CHAR: - case CPP_WCHAR: - case CPP_NAME: - case CPP_HASH: - if (!want_value) - SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", - cpp_token_as_text (pfile, op.token)); - want_value = false; - top->value = eval_token (pfile, op.token); - continue; - - case CPP_NOT: - saw_leading_not = lex_count == 1; - break; - case CPP_PLUS: - if (want_value) - op.op = CPP_UPLUS; - break; - case CPP_MINUS: - if (want_value) - op.op = CPP_UMINUS; - break; - - default: - if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ) - SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions", - cpp_token_as_text (pfile, op.token)); - break; - } + { + /* These tokens convert into values. */ + case CPP_NUMBER: + case CPP_CHAR: + case CPP_WCHAR: + case CPP_NAME: + case CPP_HASH: + if (!want_value) + SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); + want_value = false; + top->value = eval_token (pfile, op.token); + continue; + + case CPP_NOT: + saw_leading_not = lex_count == 1; + break; + case CPP_PLUS: + if (want_value) + op.op = CPP_UPLUS; + break; + case CPP_MINUS: + if (want_value) + op.op = CPP_UMINUS; + break; + + default: + if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ) + SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions", + cpp_token_as_text (pfile, op.token)); + break; + } /* Check we have a value or operator as appropriate. */ if (optab[op.op].flags & NO_L_OPERAND) - { - if (!want_value) - SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", - cpp_token_as_text (pfile, op.token)); - } + { + if (!want_value) + SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); + } else if (want_value) - { - /* We want a number (or expression) and haven't got one. - Try to emit a specific diagnostic. */ - if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN) - SYNTAX_ERROR ("missing expression between '(' and ')'"); - - if (op.op == CPP_EOF && top->op == CPP_EOF) - SYNTAX_ERROR ("#if with no expression"); - - if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN) - SYNTAX_ERROR2 ("operator '%s' has no right operand", - cpp_token_as_text (pfile, top->token)); - else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF) - /* Complain about missing paren during reduction. */; - else - SYNTAX_ERROR2 ("operator '%s' has no left operand", - cpp_token_as_text (pfile, op.token)); - } + { + /* We want a number (or expression) and haven't got one. + Try to emit a specific diagnostic. */ + if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN) + SYNTAX_ERROR ("missing expression between '(' and ')'"); + + if (op.op == CPP_EOF && top->op == CPP_EOF) + SYNTAX_ERROR ("#if with no expression"); + + if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN) + SYNTAX_ERROR2 ("operator '%s' has no right operand", + cpp_token_as_text (pfile, top->token)); + else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF) + /* Complain about missing paren during reduction. */; + else + SYNTAX_ERROR2 ("operator '%s' has no left operand", + cpp_token_as_text (pfile, op.token)); + } top = reduce (pfile, top, op.op); if (!top) - goto syntax_error; + goto syntax_error; if (op.op == CPP_EOF) - break; + break; switch (op.op) - { - case CPP_CLOSE_PAREN: - continue; - case CPP_OR_OR: - if (!num_zerop (top->value)) - pfile->state.skip_eval++; - break; - case CPP_AND_AND: - case CPP_QUERY: - if (num_zerop (top->value)) - pfile->state.skip_eval++; - break; - case CPP_COLON: - if (top->op != CPP_QUERY) - SYNTAX_ERROR (" ':' without preceding '?'"); - if (!num_zerop (top[-1].value)) /* Was '?' condition true? */ - pfile->state.skip_eval++; - else - pfile->state.skip_eval--; - default: - break; - } + { + case CPP_CLOSE_PAREN: + continue; + case CPP_OR_OR: + if (!num_zerop (top->value)) + pfile->state.skip_eval++; + break; + case CPP_AND_AND: + case CPP_QUERY: + if (num_zerop (top->value)) + pfile->state.skip_eval++; + break; + case CPP_COLON: + if (top->op != CPP_QUERY) + SYNTAX_ERROR (" ':' without preceding '?'"); + if (!num_zerop (top[-1].value)) /* Was '?' condition true? */ + pfile->state.skip_eval++; + else + pfile->state.skip_eval--; + default: + break; + } want_value = true; /* Check for and handle stack overflow. */ if (++top == pfile->op_limit) - top = _cpp_expand_op_stack (pfile); + top = _cpp_expand_op_stack (pfile); top->op = op.op; top->token = op.token; @@ -863,115 +985,115 @@ reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op) while (prio < optab[top->op].prio) { if (CPP_OPTION (pfile, warn_num_sign_change) - && optab[top->op].flags & CHECK_PROMOTION) - check_promotion (pfile, top); + && optab[top->op].flags & CHECK_PROMOTION) + check_promotion (pfile, top); switch (top->op) - { - case CPP_UPLUS: - case CPP_UMINUS: - case CPP_NOT: - case CPP_COMPL: - top[-1].value = num_unary_op (pfile, top->value, top->op); - break; - - case CPP_PLUS: - case CPP_MINUS: - case CPP_RSHIFT: - case CPP_LSHIFT: - case CPP_COMMA: - top[-1].value = num_binary_op (pfile, top[-1].value, - top->value, top->op); - break; - - case CPP_GREATER: - case CPP_LESS: - case CPP_GREATER_EQ: - case CPP_LESS_EQ: - top[-1].value - = num_inequality_op (pfile, top[-1].value, top->value, top->op); - break; - - case CPP_EQ_EQ: - case CPP_NOT_EQ: - top[-1].value - = num_equality_op (pfile, top[-1].value, top->value, top->op); - break; - - case CPP_AND: - case CPP_OR: - case CPP_XOR: - top[-1].value - = num_bitwise_op (pfile, top[-1].value, top->value, top->op); - break; - - case CPP_MULT: - top[-1].value = num_mul (pfile, top[-1].value, top->value); - break; - - case CPP_DIV: - case CPP_MOD: - top[-1].value = num_div_op (pfile, top[-1].value, - top->value, top->op); - break; - - case CPP_OR_OR: - top--; - if (!num_zerop (top->value)) - pfile->state.skip_eval--; - top->value.low = (!num_zerop (top->value) - || !num_zerop (top[1].value)); - top->value.high = 0; - top->value.unsignedp = false; - top->value.overflow = false; - continue; - - case CPP_AND_AND: - top--; - if (num_zerop (top->value)) - pfile->state.skip_eval--; - top->value.low = (!num_zerop (top->value) - && !num_zerop (top[1].value)); - top->value.high = 0; - top->value.unsignedp = false; - top->value.overflow = false; - continue; - - case CPP_OPEN_PAREN: - if (op != CPP_CLOSE_PAREN) - { - cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression"); - return 0; - } - top--; - top->value = top[1].value; - return top; - - case CPP_COLON: - top -= 2; - if (!num_zerop (top->value)) - { - pfile->state.skip_eval--; - top->value = top[1].value; - } - else - top->value = top[2].value; - top->value.unsignedp = (top[1].value.unsignedp - || top[2].value.unsignedp); - continue; - - case CPP_QUERY: - cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'"); - return 0; - - default: - goto bad_op; - } + { + case CPP_UPLUS: + case CPP_UMINUS: + case CPP_NOT: + case CPP_COMPL: + top[-1].value = num_unary_op (pfile, top->value, top->op); + break; + + case CPP_PLUS: + case CPP_MINUS: + case CPP_RSHIFT: + case CPP_LSHIFT: + case CPP_COMMA: + top[-1].value = num_binary_op (pfile, top[-1].value, + top->value, top->op); + break; + + case CPP_GREATER: + case CPP_LESS: + case CPP_GREATER_EQ: + case CPP_LESS_EQ: + top[-1].value + = num_inequality_op (pfile, top[-1].value, top->value, top->op); + break; + + case CPP_EQ_EQ: + case CPP_NOT_EQ: + top[-1].value + = num_equality_op (pfile, top[-1].value, top->value, top->op); + break; + + case CPP_AND: + case CPP_OR: + case CPP_XOR: + top[-1].value + = num_bitwise_op (pfile, top[-1].value, top->value, top->op); + break; + + case CPP_MULT: + top[-1].value = num_mul (pfile, top[-1].value, top->value); + break; + + case CPP_DIV: + case CPP_MOD: + top[-1].value = num_div_op (pfile, top[-1].value, + top->value, top->op); + break; + + case CPP_OR_OR: + top--; + if (!num_zerop (top->value)) + pfile->state.skip_eval--; + top->value.low = (!num_zerop (top->value) + || !num_zerop (top[1].value)); + top->value.high = 0; + top->value.unsignedp = false; + top->value.overflow = false; + continue; + + case CPP_AND_AND: + top--; + if (num_zerop (top->value)) + pfile->state.skip_eval--; + top->value.low = (!num_zerop (top->value) + && !num_zerop (top[1].value)); + top->value.high = 0; + top->value.unsignedp = false; + top->value.overflow = false; + continue; + + case CPP_OPEN_PAREN: + if (op != CPP_CLOSE_PAREN) + { + cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression"); + return 0; + } + top--; + top->value = top[1].value; + return top; + + case CPP_COLON: + top -= 2; + if (!num_zerop (top->value)) + { + pfile->state.skip_eval--; + top->value = top[1].value; + } + else + top->value = top[2].value; + top->value.unsignedp = (top[1].value.unsignedp + || top[2].value.unsignedp); + continue; + + case CPP_QUERY: + cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'"); + return 0; + + default: + goto bad_op; + } top--; if (top->value.overflow && !pfile->state.skip_eval) - cpp_error (pfile, CPP_DL_PEDWARN, - "integer overflow in preprocessor expression"); + cpp_error (pfile, CPP_DL_PEDWARN, + "integer overflow in preprocessor expression"); } if (op == CPP_CLOSE_PAREN) @@ -1007,14 +1129,14 @@ check_promotion (cpp_reader *pfile, const struct op *op) if (op->value.unsignedp) { if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision))) - cpp_error (pfile, CPP_DL_WARNING, - "the left operand of \"%s\" changes sign when promoted", - cpp_token_as_text (pfile, op->token)); + cpp_error (pfile, CPP_DL_WARNING, + "the left operand of \"%s\" changes sign when promoted", + cpp_token_as_text (pfile, op->token)); } else if (!num_positive (op->value, CPP_OPTION (pfile, precision))) cpp_error (pfile, CPP_DL_WARNING, - "the right operand of \"%s\" changes sign when promoted", - cpp_token_as_text (pfile, op->token)); + "the right operand of \"%s\" changes sign when promoted", + cpp_token_as_text (pfile, op->token)); } /* Clears the unused high order bits of the number pointed to by PNUM. */ @@ -1025,12 +1147,12 @@ num_trim (cpp_num num, size_t precision) { precision -= PART_PRECISION; if (precision < PART_PRECISION) - num.high &= ((cpp_num_part) 1 << precision) - 1; + num.high &= ((cpp_num_part) 1 << precision) - 1; } else { if (precision < PART_PRECISION) - num.low &= ((cpp_num_part) 1 << precision) - 1; + num.low &= ((cpp_num_part) 1 << precision) - 1; num.high = 0; } @@ -1058,18 +1180,18 @@ cpp_num_sign_extend (cpp_num num, size_t precision) if (!num.unsignedp) { if (precision > PART_PRECISION) - { - precision -= PART_PRECISION; - if (precision < PART_PRECISION - && (num.high & (cpp_num_part) 1 << (precision - 1))) - num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); - } + { + precision -= PART_PRECISION; + if (precision < PART_PRECISION + && (num.high & (cpp_num_part) 1 << (precision - 1))) + num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); + } else if (num.low & (cpp_num_part) 1 << (precision - 1)) - { - if (precision < PART_PRECISION) - num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); - num.high = ~(cpp_num_part) 0; - } + { + if (precision < PART_PRECISION) + num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision)); + num.high = ~(cpp_num_part) 0; + } } return num; @@ -1107,7 +1229,7 @@ num_greater_eq (cpp_num pa, cpp_num pb, size_t precision) unsignedp = num_positive (pa, precision); if (unsignedp != num_positive (pb, precision)) - return unsignedp; + return unsignedp; /* Otherwise we can do an unsigned comparison. */ } @@ -1118,7 +1240,7 @@ num_greater_eq (cpp_num pa, cpp_num pb, size_t precision) /* Returns LHS OP RHS, where OP is a bit-wise operation. */ static cpp_num num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED, - cpp_num lhs, cpp_num rhs, enum cpp_ttype op) + cpp_num lhs, cpp_num rhs, enum cpp_ttype op) { lhs.overflow = false; lhs.unsignedp = lhs.unsignedp || rhs.unsignedp; @@ -1147,7 +1269,7 @@ num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED, /* Returns LHS OP RHS, where OP is an inequality. */ static cpp_num num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, - enum cpp_ttype op) + enum cpp_ttype op) { bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision)); @@ -1169,7 +1291,7 @@ num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, /* Returns LHS OP RHS, where OP is == or !=. */ static cpp_num num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED, - cpp_num lhs, cpp_num rhs, enum cpp_ttype op) + cpp_num lhs, cpp_num rhs, enum cpp_ttype op) { /* Work around a 3.0.4 bug; see PR 6950. */ bool eq = num_eq (lhs, rhs); @@ -1200,22 +1322,22 @@ num_rshift (cpp_num num, size_t precision, size_t n) { /* Sign-extend. */ if (precision < PART_PRECISION) - num.high = sign_mask, num.low |= sign_mask << precision; + num.high = sign_mask, num.low |= sign_mask << precision; else if (precision < 2 * PART_PRECISION) - num.high |= sign_mask << (precision - PART_PRECISION); + num.high |= sign_mask << (precision - PART_PRECISION); if (n >= PART_PRECISION) - { - n -= PART_PRECISION; - num.low = num.high; - num.high = sign_mask; - } + { + n -= PART_PRECISION; + num.low = num.high; + num.high = sign_mask; + } if (n) - { - num.low = (num.low >> n) | (num.high << (PART_PRECISION - n)); - num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n)); - } + { + num.low = (num.low >> n) | (num.high << (PART_PRECISION - n)); + num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n)); + } } num = num_trim (num, precision); @@ -1239,25 +1361,25 @@ num_lshift (cpp_num num, size_t precision, size_t n) orig = num; if (m >= PART_PRECISION) - { - m -= PART_PRECISION; - num.high = num.low; - num.low = 0; - } + { + m -= PART_PRECISION; + num.high = num.low; + num.low = 0; + } if (m) - { - num.high = (num.high << m) | (num.low >> (PART_PRECISION - m)); - num.low <<= m; - } + { + num.high = (num.high << m) | (num.low >> (PART_PRECISION - m)); + num.low <<= m; + } num = num_trim (num, precision); if (num.unsignedp) - num.overflow = false; + num.overflow = false; else - { - maybe_orig = num_rshift (num, precision, n); - num.overflow = !num_eq (orig, maybe_orig); - } + { + maybe_orig = num_rshift (num, precision, n); + num.overflow = !num_eq (orig, maybe_orig); + } } return num; @@ -1271,8 +1393,8 @@ num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op) { case CPP_UPLUS: if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval) - cpp_error (pfile, CPP_DL_WARNING, - "traditional C rejects the unary plus operator"); + cpp_error (pfile, CPP_DL_WARNING, + "traditional C rejects the unary plus operator"); num.overflow = false; break; @@ -1312,22 +1434,22 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) case CPP_LSHIFT: case CPP_RSHIFT: if (!rhs.unsignedp && !num_positive (rhs, precision)) - { - /* A negative shift is a positive shift the other way. */ - if (op == CPP_LSHIFT) - op = CPP_RSHIFT; - else - op = CPP_LSHIFT; - rhs = num_negate (rhs, precision); - } + { + /* A negative shift is a positive shift the other way. */ + if (op == CPP_LSHIFT) + op = CPP_RSHIFT; + else + op = CPP_LSHIFT; + rhs = num_negate (rhs, precision); + } if (rhs.high) - n = ~0; /* Maximal. */ + n = ~0; /* Maximal. */ else - n = rhs.low; + n = rhs.low; if (op == CPP_LSHIFT) - lhs = num_lshift (lhs, precision, n); + lhs = num_lshift (lhs, precision, n); else - lhs = num_rshift (lhs, precision, n); + lhs = num_rshift (lhs, precision, n); break; /* Arithmetic. */ @@ -1337,25 +1459,25 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) result.low = lhs.low + rhs.low; result.high = lhs.high + rhs.high; if (result.low < lhs.low) - result.high++; + result.high++; result.unsignedp = lhs.unsignedp || rhs.unsignedp; result.overflow = false; result = num_trim (result, precision); if (!result.unsignedp) - { - bool lhsp = num_positive (lhs, precision); - result.overflow = (lhsp == num_positive (rhs, precision) - && lhsp != num_positive (result, precision)); - } + { + bool lhsp = num_positive (lhs, precision); + result.overflow = (lhsp == num_positive (rhs, precision) + && lhsp != num_positive (result, precision)); + } return result; /* Comma. */ default: /* case CPP_COMMA: */ if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99) - || !pfile->state.skip_eval)) - cpp_error (pfile, CPP_DL_PEDWARN, - "comma operator in operand of #if"); + || !pfile->state.skip_eval)) + cpp_error (pfile, CPP_DL_PEDWARN, + "comma operator in operand of #if"); lhs = rhs; break; } @@ -1408,9 +1530,9 @@ num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs) if (!unsignedp) { if (!num_positive (lhs, precision)) - negate = !negate, lhs = num_negate (lhs, precision); + negate = !negate, lhs = num_negate (lhs, precision); if (!num_positive (rhs, precision)) - negate = !negate, rhs = num_negate (rhs, precision); + negate = !negate, rhs = num_negate (rhs, precision); } overflow = lhs.high && rhs.high; @@ -1438,7 +1560,7 @@ num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs) result.overflow = false; else result.overflow = overflow || (num_positive (result, precision) ^ !negate - && !num_zerop (result)); + && !num_zerop (result)); result.unsignedp = unsignedp; return result; @@ -1459,9 +1581,9 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) if (!unsignedp) { if (!num_positive (lhs, precision)) - negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision); + negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision); if (!num_positive (rhs, precision)) - negate = !negate, rhs = num_negate (rhs, precision); + negate = !negate, rhs = num_negate (rhs, precision); } /* Find the high bit. */ @@ -1470,24 +1592,24 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) i = precision - 1; mask = (cpp_num_part) 1 << (i - PART_PRECISION); for (; ; i--, mask >>= 1) - if (rhs.high & mask) - break; + if (rhs.high & mask) + break; } else if (rhs.low) { if (precision > PART_PRECISION) - i = precision - PART_PRECISION - 1; + i = precision - PART_PRECISION - 1; else - i = precision - 1; + i = precision - 1; mask = (cpp_num_part) 1 << i; for (; ; i--, mask >>= 1) - if (rhs.low & mask) - break; + if (rhs.low & mask) + break; } else { if (!pfile->state.skip_eval) - cpp_error (pfile, CPP_DL_ERROR, "division by zero in #if"); + cpp_error (pfile, CPP_DL_ERROR, "division by zero in #if"); return lhs; } @@ -1505,15 +1627,15 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) for (;;) { if (num_greater_eq (lhs, sub, precision)) - { - lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS); - if (i >= PART_PRECISION) - result.high |= (cpp_num_part) 1 << (i - PART_PRECISION); - else - result.low |= (cpp_num_part) 1 << i; - } + { + lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS); + if (i >= PART_PRECISION) + result.high |= (cpp_num_part) 1 << (i - PART_PRECISION); + else + result.low |= (cpp_num_part) 1 << i; + } if (i-- == 0) - break; + break; sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1)); sub.high >>= 1; } @@ -1524,11 +1646,12 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) result.unsignedp = unsignedp; result.overflow = false; if (!unsignedp) - { - if (negate) - result = num_negate (result, precision); - result.overflow = num_positive (result, precision) ^ !negate; - } + { + if (negate) + result = num_negate (result, precision); + result.overflow = (num_positive (result, precision) ^ !negate + && !num_zerop (result)); + } return result; } diff --git a/support/cpp2/libcpp/files.c b/support/cpp/libcpp/files.c similarity index 72% rename from support/cpp2/libcpp/files.c rename to support/cpp/libcpp/files.c index 57643822..8be675b2 100644 --- a/support/cpp2/libcpp/files.c +++ b/support/cpp/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 @@ -140,6 +142,7 @@ struct file_hash_entry { struct file_hash_entry *next; cpp_dir *start_dir; + source_location location; union { _cpp_file *file; @@ -147,20 +150,35 @@ struct file_hash_entry } u; }; +/* Number of entries to put in a file_hash_entry pool. */ +#define FILE_HASH_POOL_SIZE 127 + +/* A file hash entry pool. We allocate file_hash_entry object from + one of these. */ +struct file_hash_entry_pool +{ + /* Number of entries used from this pool. */ + unsigned int file_hash_entries_used; + /* Next pool in the chain; used when freeing. */ + struct file_hash_entry_pool *next; + /* The memory pool. */ + struct file_hash_entry pool[FILE_HASH_POOL_SIZE]; +}; + static bool open_file (_cpp_file *file); static bool pch_open_file (cpp_reader *pfile, _cpp_file *file, - bool *invalid_pch); + bool *invalid_pch); static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file, - bool *invalid_pch); + bool *invalid_pch); static bool read_file_guts (cpp_reader *pfile, _cpp_file *file); static bool read_file (cpp_reader *pfile, _cpp_file *file); static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import); static struct cpp_dir *search_path_head (cpp_reader *, const char *fname, - int angle_brackets, enum include_type); + int angle_brackets, enum include_type); static const char *dir_name_of_file (_cpp_file *file); static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int); static struct file_hash_entry *search_cache (struct file_hash_entry *head, - const cpp_dir *start_dir); + const cpp_dir *start_dir); static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname); static void destroy_cpp_file (_cpp_file *); static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp); @@ -211,21 +229,37 @@ open_file (_cpp_file *file) if (file->fd != -1) { if (fstat (file->fd, &file->st) == 0) - { - if (!S_ISDIR (file->st.st_mode)) - { - file->err_no = 0; - return true; - } - - /* Ignore a directory and continue the search. The file we're - looking for may be elsewhere in the search path. */ - errno = ENOENT; - } + { + if (!S_ISDIR (file->st.st_mode)) + { + file->err_no = 0; + return true; + } + + /* Ignore a directory and continue the search. The file we're + looking for may be elsewhere in the search path. */ + errno = ENOENT; + } close (file->fd); file->fd = -1; } +#if defined(_WIN32) && !defined(__CYGWIN__) + else if (errno == EACCES) + { + /* On most UNIX systems, open succeeds on a directory. Above, + we check if we have opened a directory and if so, set errno + to ENOENT. However, on Windows, opening a directory + fails with EACCES. We want to return ENOENT in that + case too. */ + if (stat (file->path, &file->st) == 0 + && S_ISDIR (file->st.st_mode)) + errno = ENOENT; + else + /* The call to stat may have reset errno. */ + errno = EACCES; + } +#endif else if (errno == ENOTDIR) errno = ENOENT; @@ -266,32 +300,32 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) size_t dlen, plen = len; if (!S_ISDIR (st.st_mode)) - valid = validate_pch (pfile, file, pchname); + valid = validate_pch (pfile, file, pchname); else if ((pchdir = opendir (pchname)) != NULL) - { - pchname[plen - 1] = '/'; - while ((d = readdir (pchdir)) != NULL) - { - dlen = strlen (d->d_name) + 1; - if ((strcmp (d->d_name, ".") == 0) - || (strcmp (d->d_name, "..") == 0)) - continue; - if (dlen + plen > len) - { - len += dlen + 64; - pchname = XRESIZEVEC (char, pchname, len); - } - memcpy (pchname + plen, d->d_name, dlen); - valid = validate_pch (pfile, file, pchname); - if (valid) - break; - } - closedir (pchdir); - } + { + pchname[plen - 1] = '/'; + while ((d = readdir (pchdir)) != NULL) + { + dlen = strlen (d->d_name) + 1; + if ((strcmp (d->d_name, ".") == 0) + || (strcmp (d->d_name, "..") == 0)) + continue; + if (dlen + plen > len) + { + len += dlen + 64; + pchname = XRESIZEVEC (char, pchname, len); + } + memcpy (pchname + plen, d->d_name, dlen); + valid = validate_pch (pfile, file, pchname); + if (valid) + break; + } + closedir (pchdir); + } if (valid) - file->pch = true; + file->pch = true; else - *invalid_pch = true; + *invalid_pch = true; } if (valid) @@ -322,20 +356,39 @@ 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; + return true; if (open_file (file)) - return true; + return true; if (file->err_no != ENOENT) - { - open_file_failed (pfile, file, 0); - return true; - } - + { + open_file_failed (pfile, file, 0); + 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 @@ -359,11 +412,11 @@ search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file) && file->dir == NULL) { if ((file->path = func (pfile, header, &file->dir)) != NULL) - { - if (open_file (file)) - return true; - free ((void *)file->path); - } + { + if (open_file (file)) + return true; + free ((void *)file->path); + } file->path = file->name; } @@ -396,6 +449,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) @@ -403,8 +459,8 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f hash_slot = (struct file_hash_entry **) htab_find_slot_with_hash (pfile->file_hash, fname, - htab_hash_string (fname), - INSERT); + htab_hash_string (fname), + INSERT); /* First check the cache before we resort to memory allocation. */ entry = search_cache (*hash_slot, start_dir); @@ -417,44 +473,50 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f for (; !fake ;) { if (find_file_in_dir (pfile, file, &invalid_pch)) - break; + break; file->dir = file->dir->next; if (file->dir == NULL) - { - if (search_path_exhausted (pfile, fname, file)) - { - /* Although this file must not go in the cache, because - the file found might depend on things (like the current file) - that aren't represented in the cache, it still has to go in - the list of all files so that #import works. */ - file->next_file = pfile->all_files; - pfile->all_files = file; - return file; - } - - open_file_failed (pfile, file, angle_brackets); - if (invalid_pch) - { - cpp_error (pfile, CPP_DL_ERROR, - "one or more PCH files were found, but they were invalid"); - if (!cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_ERROR, - "use -Winvalid-pch for more information"); - } - break; - } + { + if (search_path_exhausted (pfile, fname, file)) + { + /* Although this file must not go in the cache, because + the file found might depend on things (like the current file) + that aren't represented in the cache, it still has to go in + the list of all files so that #import works. */ + file->next_file = pfile->all_files; + pfile->all_files = file; + return file; + } + + open_file_failed (pfile, file, angle_brackets); + if (invalid_pch) + { + cpp_error (pfile, CPP_DL_ERROR, + "one or more PCH files were found, but they were invalid"); + if (!cpp_get_options (pfile)->warn_invalid_pch) + cpp_error (pfile, CPP_DL_ERROR, + "use -Winvalid-pch for more information"); + } + break; + } /* 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) - continue; + and the quote and bracket chain heads because there are no + other possible starting points for searches. */ + 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) @@ -475,9 +537,35 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f entry = new_file_hash_entry (pfile); entry->next = *hash_slot; entry->start_dir = start_dir; + entry->location = pfile->line_table->highest_location; 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->location = pfile->line_table->highest_location; + 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->location = pfile->line_table->highest_location; + entry->u.file = file; + *hash_slot = entry; + } + return file; } @@ -506,19 +594,19 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) if (regular) { /* off_t might have a wider range than ssize_t - in other words, - the max size of a file might be bigger than the address - space. We can't handle a file that large. (Anyone with - a single source file bigger than 2GB needs to rethink - their coding style.) Some systems (e.g. AIX 4.1) define - SSIZE_MAX to be much smaller than the actual range of the - type. Use INTTYPE_MAXIMUM unconditionally to ensure this - does not bite us. */ + the max size of a file might be bigger than the address + space. We can't handle a file that large. (Anyone with + a single source file bigger than 2GB needs to rethink + their coding style.) Some systems (e.g. AIX 4.1) define + SSIZE_MAX to be much smaller than the actual range of the + type. Use INTTYPE_MAXIMUM unconditionally to ensure this + does not bite us. */ #ifndef __BORLANDC__ if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t)) - { - cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path); - return false; - } + { + cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path); + return false; + } #endif size = file->st.st_size; @@ -536,12 +624,12 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) total += count; if (total == size) - { - if (regular) - break; - size *= 2; - buf = XRESIZEVEC (uchar, buf, size + 1); - } + { + if (regular) + break; + size *= 2; + buf = XRESIZEVEC (uchar, buf, size + 1); + } } if (count < 0) @@ -560,11 +648,11 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) */ if (regular && total != size && STAT_SIZE_RELIABLE (file->st)) cpp_error (pfile, CPP_DL_WARNING, - "%s is shorter than expected", file->path); + "%s is shorter than expected", file->path); #endif file->buffer = _cpp_convert_input (pfile, CPP_OPTION (pfile, input_charset), - buf, size, total, &file->st.st_size); + buf, size, total, &file->st.st_size); file->buffer_valid = true; return true; @@ -617,7 +705,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) /* Don't stack files that have been stacked before. */ if (file->stack_count) - return false; + return false; } /* Skip if the file had a header guard and the macro is defined. @@ -643,10 +731,10 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) if (check_file_against_entries (pfile, file, import)) { /* If this isn't a #import, but yet we can't include the file, - that means that it was #import-ed in the PCH file, - so we can never include it again. */ + that means that it was #import-ed in the PCH file, + so we can never include it again. */ if (! import) - _cpp_mark_file_once_only (pfile, file); + _cpp_mark_file_once_only (pfile, file); return false; } @@ -660,43 +748,43 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) for (f = pfile->all_files; f; f = f->next_file) { if (f == file) - continue; + continue; if ((import || f->once_only) - && f->err_no == 0 - && f->st.st_mtime == file->st.st_mtime - && f->st.st_size == file->st.st_size) - { - _cpp_file *ref_file; - bool same_file_p = false; - - if (f->buffer && !f->buffer_valid) - { - /* We already have a buffer but it is not valid, because - the file is still stacked. Make a new one. */ - ref_file = make_cpp_file (pfile, f->dir, f->name); - ref_file->path = f->path; - } - else - /* The file is not stacked anymore. We can reuse it. */ - ref_file = f; - - same_file_p = read_file (pfile, ref_file) - /* Size might have changed in read_file(). */ - && ref_file->st.st_size == file->st.st_size - && !memcmp (ref_file->buffer, - file->buffer, - file->st.st_size); - - if (f->buffer && !f->buffer_valid) - { - ref_file->path = 0; - destroy_cpp_file (ref_file); - } - - if (same_file_p) - break; - } + && f->err_no == 0 + && f->st.st_mtime == file->st.st_mtime + && f->st.st_size == file->st.st_size) + { + _cpp_file *ref_file; + bool same_file_p = false; + + if (f->buffer && !f->buffer_valid) + { + /* We already have a buffer but it is not valid, because + the file is still stacked. Make a new one. */ + ref_file = make_cpp_file (pfile, f->dir, f->name); + ref_file->path = f->path; + } + else + /* The file is not stacked anymore. We can reuse it. */ + ref_file = f; + + same_file_p = read_file (pfile, ref_file) + /* Size might have changed in read_file(). */ + && ref_file->st.st_size == file->st.st_size + && !memcmp (ref_file->buffer, + file->buffer, + file->st.st_size); + + if (f->buffer && !f->buffer_valid) + { + ref_file->path = 0; + destroy_cpp_file (ref_file); + } + + if (same_file_p) + break; + } } return f == NULL; @@ -724,7 +812,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count) { if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file)) - deps_add_dep (pfile->deps, file->path); + deps_add_dep (pfile->deps, file->path); } /* Clear buffer_valid since _cpp_clean_line messes it up. */ @@ -733,7 +821,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; @@ -760,7 +849,7 @@ _cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file) nothing left in the path, returns NULL. */ static struct cpp_dir * search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, - enum include_type type) + enum include_type type) { cpp_dir *dir; _cpp_file *file; @@ -774,7 +863,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, /* For #include_next, skip in the search path past the dir in which the current file was found, but if it was found via an absolute path use the normal search logic. */ - if (type == IT_INCLUDE_NEXT && file->dir) + if (type == IT_INCLUDE_NEXT && file->dir + && file->dir != &pfile->no_search_path) dir = file->dir->next; else if (angle_brackets) dir = pfile->bracket_include; @@ -786,11 +876,11 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, dir = pfile->quote_include; else return make_cpp_dir (pfile, dir_name_of_file (file), - pfile->buffer ? pfile->buffer->sysp : 0); + pfile->buffer ? pfile->buffer->sysp : 0); if (dir == NULL) cpp_error (pfile, CPP_DL_ERROR, - "no include path in which to search for %s", fname); + "no include path in which to search for %s", fname); return dir; } @@ -819,7 +909,7 @@ dir_name_of_file (_cpp_file *file) Returns true if a buffer was stacked. */ bool _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, - enum include_type type) + enum include_type type) { struct cpp_dir *dir; _cpp_file *file; @@ -856,11 +946,11 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) else { /* If we are outputting dependencies but not for this file then - don't error because we can still produce correct output. */ + don't error because we can still produce correct output. */ if (CPP_OPTION (pfile, deps.style) && ! print_dep) - cpp_errno (pfile, CPP_DL_WARNING, file->path); + cpp_errno (pfile, CPP_DL_WARNING, file->path); else - cpp_errno (pfile, CPP_DL_ERROR, file->path); + cpp_errno (pfile, CPP_DL_ERROR, file->path); } } @@ -900,6 +990,19 @@ destroy_cpp_file (_cpp_file *file) free (file); } +/* Release all the files allocated by this reader. */ +static void +destroy_all_cpp_files (cpp_reader *pfile) +{ + _cpp_file *iter = pfile->all_files; + while (iter) + { + _cpp_file *next = iter->next_file; + destroy_cpp_file (iter); + iter = next; + } +} + /* A hash of directory names. The directory names are the path names of files which contain a #include "", the included file name is appended to this directories. @@ -915,8 +1018,8 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) hash_slot = (struct file_hash_entry **) htab_find_slot_with_hash (pfile->dir_hash, dir_name, - htab_hash_string (dir_name), - INSERT); + htab_hash_string (dir_name), + INSERT); /* Have we already hashed this directory? */ for (entry = *hash_slot; entry; entry = entry->next) @@ -934,6 +1037,7 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) entry = new_file_hash_entry (pfile); entry->next = *hash_slot; entry->start_dir = NULL; + entry->location = pfile->line_table->highest_location; entry->u.dir = dir; *hash_slot = entry; @@ -944,20 +1048,35 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) static void allocate_file_hash_entries (cpp_reader *pfile) { - pfile->file_hash_entries_used = 0; - pfile->file_hash_entries_allocated = 127; - pfile->file_hash_entries = XNEWVEC (struct file_hash_entry, - pfile->file_hash_entries_allocated); + struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool); + pool->file_hash_entries_used = 0; + pool->next = pfile->file_hash_entries; + pfile->file_hash_entries = pool; } /* Return a new file hash entry. */ static struct file_hash_entry * new_file_hash_entry (cpp_reader *pfile) { - if (pfile->file_hash_entries_used == pfile->file_hash_entries_allocated) + unsigned int idx; + if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE) allocate_file_hash_entries (pfile); - return &pfile->file_hash_entries[pfile->file_hash_entries_used++]; + idx = pfile->file_hash_entries->file_hash_entries_used++; + return &pfile->file_hash_entries->pool[idx]; +} + +/* Free the file hash entry pools. */ +static void +free_file_hash_entries (cpp_reader *pfile) +{ + struct file_hash_entry_pool *iter = pfile->file_hash_entries; + while (iter) + { + struct file_hash_entry_pool *next = iter->next; + free (iter); + iter = next; + } } /* Returns TRUE if a file FNAME has ever been successfully opened. @@ -977,6 +1096,25 @@ cpp_included (cpp_reader *pfile, const char *fname) return entry != NULL; } +/* Returns TRUE if a file FNAME has ever been successfully opened + before LOCATION. This routine is not intended to correctly handle + filenames aliased by links or redundant . or .. traversals etc. */ +bool +cpp_included_before (cpp_reader *pfile, const char *fname, + source_location location) +{ + struct file_hash_entry *entry; + + entry = (struct file_hash_entry *) + htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname)); + + while (entry && (entry->start_dir == NULL || entry->u.file->err_no + || entry->location > location)) + entry = entry->next; + + return entry != NULL; +} + /* Calculate the hash value of a file hash entry P. */ static hashval_t @@ -1008,15 +1146,29 @@ 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) { pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, - NULL, xcalloc, free); + NULL, xcalloc, free); pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, - NULL, xcalloc, free); + 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. */ @@ -1025,6 +1177,21 @@ _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); + free_file_hash_entries (pfile); + destroy_all_cpp_files (pfile); +} + +/* Make the parser forget about files it has seen. This can be useful + for resetting the parser to start another run. */ +void +cpp_clear_file_cache (cpp_reader *pfile) +{ + _cpp_cleanup_files (pfile); + pfile->file_hash_entries = NULL; + pfile->all_files = NULL; + _cpp_init_files (pfile); } /* Enter a file name in the hash for the sake of cpp_included. */ @@ -1049,7 +1216,7 @@ cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc) flags = 1 + (externc != 0); pfile->buffer->sysp = flags; _cpp_do_file_change (pfile, LC_RENAME, map->to_file, - SOURCE_LINE (map, pfile->line_table->highest_line), flags); + SOURCE_LINE (map, pfile->line_table->highest_line), flags); } /* Allow the client to change the current file. Used by the front end @@ -1057,7 +1224,7 @@ cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc) If REASON is LC_LEAVE, then NEW_NAME must be NULL. */ void cpp_change_file (cpp_reader *pfile, enum lc_reason reason, - const char *new_name) + const char *new_name) { _cpp_do_file_change (pfile, reason, new_name, 1, 0); } @@ -1076,17 +1243,17 @@ report_missing_guard (void **slot, void *b) /* We don't want MI guard advice for the main file. */ if (file->cmacro == NULL && file->stack_count == 1 && !file->main_file) - { - if (*bannerp == 0) - { - fputs (_("Multiple include guards may be useful for:\n"), - stderr); - *bannerp = 1; - } - - fputs (entry->u.file->path, stderr); - putc ('\n', stderr); - } + { + if (*bannerp == 0) + { + fputs (_("Multiple include guards may be useful for:\n"), + stderr); + *bannerp = 1; + } + + fputs (entry->u.file->path, stderr); + putc ('\n', stderr); + } } return 0; @@ -1107,7 +1274,7 @@ _cpp_report_missing_guards (cpp_reader *pfile) newer, return 1, otherwise 0. */ int _cpp_compare_file_date (cpp_reader *pfile, const char *fname, - int angle_brackets) + int angle_brackets) { _cpp_file *file; struct cpp_dir *dir; @@ -1172,7 +1339,7 @@ _cpp_get_file_stat (_cpp_file *file) If BRACKET does not lie in the QUOTE chain, it is set to QUOTE. */ void cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket, - int quote_ignores_source_dir) + int quote_ignores_source_dir) { pfile->quote_include = quote; pfile->bracket_include = quote; @@ -1183,7 +1350,7 @@ cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket, quote->name_map = NULL; quote->len = strlen (quote->name); if (quote == bracket) - pfile->bracket_include = bracket; + pfile->bracket_include = bracket; } } @@ -1220,15 +1387,15 @@ read_filename_string (int ch, FILE *f) { *set++ = ch; while ((ch = getc (f)) != EOF && ! is_space (ch)) - { - if (set - alloc == len) - { - len *= 2; - alloc = XRESIZEVEC (char, alloc, len + 1); - set = alloc + len / 2; - } - *set++ = ch; - } + { + if (set - alloc == len) + { + len *= 2; + alloc = XRESIZEVEC (char, alloc, len + 1); + set = alloc + len / 2; + } + *set++ = ch; + } } *set = '\0'; ungetc (ch, f); @@ -1260,36 +1427,36 @@ read_name_map (cpp_dir *dir) int ch; while ((ch = getc (f)) != EOF) - { - char *to; - - if (is_space (ch)) - continue; - - if (count + 2 > room) - { - room += 8; - dir->name_map = XRESIZEVEC (const char *, dir->name_map, room); - } - - dir->name_map[count] = read_filename_string (ch, f); - while ((ch = getc (f)) != EOF && is_hspace (ch)) - ; - - to = read_filename_string (ch, f); - if (IS_ABSOLUTE_PATH (to)) - dir->name_map[count + 1] = to; - else - { - dir->name_map[count + 1] = append_file_to_dir (to, dir); - free (to); - } - - count += 2; - while ((ch = getc (f)) != '\n') - if (ch == EOF) - break; - } + { + char *to; + + if (is_space (ch)) + continue; + + if (count + 2 > room) + { + room += 8; + dir->name_map = XRESIZEVEC (const char *, dir->name_map, room); + } + + dir->name_map[count] = read_filename_string (ch, f); + while ((ch = getc (f)) != EOF && is_hspace (ch)) + ; + + to = read_filename_string (ch, f); + if (IS_ABSOLUTE_PATH (to)) + dir->name_map[count + 1] = to; + else + { + dir->name_map[count + 1] = append_file_to_dir (to, dir); + free (to); + } + + count += 2; + while ((ch = getc (f)) != '\n') + if (ch == EOF) + break; + } fclose (f); } @@ -1315,15 +1482,15 @@ remap_filename (cpp_reader *pfile, _cpp_file *file) for (;;) { if (!dir->name_map) - read_name_map (dir); + read_name_map (dir); for (index = 0; dir->name_map[index]; index += 2) - if (!strcmp (dir->name_map[index], fname)) - return xstrdup (dir->name_map[index + 1]); + if (!strcmp (dir->name_map[index], fname)) + return xstrdup (dir->name_map[index + 1]); p = strchr (fname, '/'); if (!p || p == fname) - return NULL; + return NULL; len = dir->len + (p - fname + 1); new_dir = XNEWVEC (char, len + 1); @@ -1349,19 +1516,19 @@ validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname) valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd); if (!valid) - { - close (file->fd); - file->fd = -1; - } + { + close (file->fd); + file->fd = -1; + } if (CPP_OPTION (pfile, print_include_names)) - { - unsigned int i; - for (i = 1; i < pfile->line_table->depth; i++) - putc ('.', stderr); - fprintf (stderr, "%c %s\n", - valid ? '!' : 'x', pchname); - } + { + unsigned int i; + for (i = 1; i < pfile->line_table->depth; i++) + putc ('.', stderr); + fprintf (stderr, "%c %s\n", + valid ? '!' : 'x', pchname); + } } file->path = saved_path; @@ -1465,7 +1632,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) ++count; result_size = (sizeof (struct pchf_data) - + sizeof (struct pchf_entry) * (count - 1)); + + sizeof (struct pchf_entry) * (count - 1)); result = XCNEWVAR (struct pchf_data, result_size); result->count = 0; @@ -1476,12 +1643,12 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) size_t count; /* This should probably never happen, since if a read error occurred - the PCH file shouldn't be written... */ + the PCH file shouldn't be written... */ if (f->dont_read || f->err_no) - continue; + continue; if (f->stack_count == 0) - continue; + continue; count = result->count++; @@ -1489,23 +1656,23 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) /* |= is avoided in the next line because of an HP C compiler bug */ result->have_once_only = result->have_once_only | f->once_only; if (f->buffer_valid) - md5_buffer ((const char *)f->buffer, - f->st.st_size, result->entries[count].sum); + md5_buffer ((const char *)f->buffer, + f->st.st_size, result->entries[count].sum); else - { - FILE *ff; - int oldfd = f->fd; - - if (!open_file (f)) - { - open_file_failed (pfile, f, 0); - return false; - } - ff = fdopen (f->fd, "rb"); - md5_stream (ff, result->entries[count].sum); - fclose (ff); - f->fd = oldfd; - } + { + FILE *ff; + int oldfd = f->fd; + + if (!open_file (f)) + { + open_file_failed (pfile, f, 0); + return false; + } + ff = fdopen (f->fd, "rb"); + md5_stream (ff, result->entries[count].sum); + fclose (ff); + f->fd = oldfd; + } result->entries[count].size = f->st.st_size; } @@ -1513,7 +1680,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) + sizeof (struct pchf_entry) * (result->count - 1)); qsort (result->entries, result->count, sizeof (struct pchf_entry), - pchf_save_compare); + pchf_save_compare); return fwrite (result, result_size, 1, fp) == 1; } @@ -1530,7 +1697,7 @@ _cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f) return false; pchf = XNEWVAR (struct pchf_data, sizeof (struct pchf_data) - + sizeof (struct pchf_entry) * (d.count - 1)); + + sizeof (struct pchf_entry) * (d.count - 1)); memcpy (pchf, &d, sizeof (struct pchf_data) - sizeof (struct pchf_entry)); if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f) != d.count) @@ -1595,8 +1762,8 @@ pchf_compare (const void *d_p, const void *e_p) static bool check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, - _cpp_file *f, - bool check_included) + _cpp_file *f, + bool check_included) { struct pchf_compare_data d; @@ -1609,5 +1776,5 @@ check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, d.f = f; d.check_included = check_included; return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry), - pchf_compare) != NULL; + pchf_compare) != NULL; } diff --git a/support/cpp2/libcpp/identifiers.c b/support/cpp/libcpp/identifiers.c similarity index 100% rename from support/cpp2/libcpp/identifiers.c rename to support/cpp/libcpp/identifiers.c diff --git a/support/cpp2/libcpp/include/cpp-id-data.h b/support/cpp/libcpp/include/cpp-id-data.h similarity index 100% rename from support/cpp2/libcpp/include/cpp-id-data.h rename to support/cpp/libcpp/include/cpp-id-data.h diff --git a/support/cpp2/libcpp/include/cpplib.h b/support/cpp/libcpp/include/cpplib.h similarity index 66% rename from support/cpp2/libcpp/include/cpplib.h rename to support/cpp/libcpp/include/cpplib.h index dc02b6b7..1015645f 100644 --- a/support/cpp2/libcpp/include/cpplib.h +++ b/support/cpp/libcpp/include/cpplib.h @@ -1,6 +1,6 @@ /* Definitions for CPP library. Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005 + 2004, 2005, 2007 Free Software Foundation, Inc. Written by Per Bothner, 1994-95. @@ -56,89 +56,89 @@ struct _cpp_file; See the cpp_operator table optab in expr.c if you change the order or add or remove anything in the first group. */ -#define TTYPE_TABLE \ - OP(EQ, "=") \ - OP(NOT, "!") \ - OP(GREATER, ">") /* compare */ \ - OP(LESS, "<") \ - OP(PLUS, "+") /* math */ \ - OP(MINUS, "-") \ - OP(MULT, "*") \ - OP(DIV, "/") \ - OP(MOD, "%") \ - OP(AND, "&") /* bit ops */ \ - OP(OR, "|") \ - OP(XOR, "^") \ - OP(RSHIFT, ">>") \ - OP(LSHIFT, "<<") \ - \ - OP(COMPL, "~") \ - OP(AND_AND, "&&") /* logical */ \ - OP(OR_OR, "||") \ - OP(QUERY, "?") \ - OP(COLON, ":") \ - OP(COMMA, ",") /* grouping */ \ - OP(OPEN_PAREN, "(") \ - OP(CLOSE_PAREN, ")") \ - TK(EOF, NONE) \ - OP(EQ_EQ, "==") /* compare */ \ - OP(NOT_EQ, "!=") \ - OP(GREATER_EQ, ">=") \ - OP(LESS_EQ, "<=") \ - \ - /* These two are unary + / - in preprocessor expressions. */ \ - OP(PLUS_EQ, "+=") /* math */ \ - OP(MINUS_EQ, "-=") \ - \ - OP(MULT_EQ, "*=") \ - OP(DIV_EQ, "/=") \ - OP(MOD_EQ, "%=") \ - OP(AND_EQ, "&=") /* bit ops */ \ - OP(OR_EQ, "|=") \ - OP(XOR_EQ, "^=") \ - OP(RSHIFT_EQ, ">>=") \ - OP(LSHIFT_EQ, "<<=") \ - /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ - OP(HASH, "#") /* digraphs */ \ - OP(PASTE, "##") \ - OP(OPEN_SQUARE, "[") \ - OP(CLOSE_SQUARE, "]") \ - OP(OPEN_BRACE, "{") \ - OP(CLOSE_BRACE, "}") \ - /* The remainder of the punctuation. Order is not significant. */ \ - OP(SEMICOLON, ";") /* structure */ \ - OP(ELLIPSIS, "...") \ - OP(PLUS_PLUS, "++") /* increment */ \ - OP(MINUS_MINUS, "--") \ - OP(DEREF, "->") /* accessors */ \ - OP(DOT, ".") \ - OP(SCOPE, "::") \ - OP(DEREF_STAR, "->*") \ - OP(DOT_STAR, ".*") \ - OP(ATSIGN, "@") /* used in Objective-C */ \ - \ - TK(NAME, IDENT) /* word */ \ - TK(AT_NAME, IDENT) /* @word - Objective-C */ \ - TK(NUMBER, LITERAL) /* 34_be+ta */ \ - \ - TK(CHAR, LITERAL) /* 'char' */ \ - TK(WCHAR, LITERAL) /* L'char' */ \ - TK(OTHER, LITERAL) /* stray punctuation */ \ - \ - TK(STRING, LITERAL) /* "string" */ \ - TK(WSTRING, LITERAL) /* L"string" */ \ - TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ - TK(HEADER_NAME, LITERAL) /* in #include */ \ - \ - TK(COMMENT, LITERAL) /* Only if output comments. */ \ - /* SPELL_LITERAL happens to DTRT. */ \ - TK(MACRO_ARG, NONE) /* Macro argument. */ \ - TK(PRAGMA, NONE) /* Only for deferred pragmas. */ \ - TK(PRAGMA_EOL, NONE) /* End-of-line for deferred pragmas. */ \ - TK(PADDING, NONE) /* Whitespace for -E. */ \ +#define TTYPE_TABLE \ + OP(EQ, "=") \ + OP(NOT, "!") \ + OP(GREATER, ">") /* compare */ \ + OP(LESS, "<") \ + OP(PLUS, "+") /* math */ \ + OP(MINUS, "-") \ + OP(MULT, "*") \ + OP(DIV, "/") \ + OP(MOD, "%") \ + OP(AND, "&") /* bit ops */ \ + OP(OR, "|") \ + OP(XOR, "^") \ + OP(RSHIFT, ">>") \ + OP(LSHIFT, "<<") \ + \ + OP(COMPL, "~") \ + OP(AND_AND, "&&") /* logical */ \ + OP(OR_OR, "||") \ + OP(QUERY, "?") \ + OP(COLON, ":") \ + OP(COMMA, ",") /* grouping */ \ + OP(OPEN_PAREN, "(") \ + OP(CLOSE_PAREN, ")") \ + TK(EOF, NONE) \ + OP(EQ_EQ, "==") /* compare */ \ + OP(NOT_EQ, "!=") \ + OP(GREATER_EQ, ">=") \ + OP(LESS_EQ, "<=") \ + \ + /* These two are unary + / - in preprocessor expressions. */ \ + OP(PLUS_EQ, "+=") /* math */ \ + OP(MINUS_EQ, "-=") \ + \ + OP(MULT_EQ, "*=") \ + OP(DIV_EQ, "/=") \ + OP(MOD_EQ, "%=") \ + OP(AND_EQ, "&=") /* bit ops */ \ + OP(OR_EQ, "|=") \ + OP(XOR_EQ, "^=") \ + OP(RSHIFT_EQ, ">>=") \ + OP(LSHIFT_EQ, "<<=") \ + /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ + OP(HASH, "#") /* digraphs */ \ + OP(PASTE, "##") \ + OP(OPEN_SQUARE, "[") \ + OP(CLOSE_SQUARE, "]") \ + OP(OPEN_BRACE, "{") \ + OP(CLOSE_BRACE, "}") \ + /* The remainder of the punctuation. Order is not significant. */ \ + OP(SEMICOLON, ";") /* structure */ \ + OP(ELLIPSIS, "...") \ + OP(PLUS_PLUS, "++") /* increment */ \ + OP(MINUS_MINUS, "--") \ + OP(DEREF, "->") /* accessors */ \ + OP(DOT, ".") \ + OP(SCOPE, "::") \ + OP(DEREF_STAR, "->*") \ + OP(DOT_STAR, ".*") \ + OP(ATSIGN, "@") /* used in Objective-C */ \ + \ + TK(NAME, IDENT) /* word */ \ + TK(AT_NAME, IDENT) /* @word - Objective-C */ \ + TK(NUMBER, LITERAL) /* 34_be+ta */ \ + \ + TK(CHAR, LITERAL) /* 'char' */ \ + TK(WCHAR, LITERAL) /* L'char' */ \ + TK(OTHER, LITERAL) /* stray punctuation */ \ + \ + TK(STRING, LITERAL) /* "string" */ \ + TK(WSTRING, LITERAL) /* L"string" */ \ + TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ + TK(HEADER_NAME, LITERAL) /* in #include */ \ + \ + TK(COMMENT, LITERAL) /* Only if output comments. */ \ + /* SPELL_LITERAL happens to DTRT. */ \ + TK(MACRO_ARG, NONE) /* Macro argument. */ \ + TK(PRAGMA, NONE) /* Only for deferred pragmas. */ \ + TK(PRAGMA_EOL, NONE) /* End-of-line for deferred pragmas. */ \ + TK(PADDING, NONE) /* Whitespace for -E. */ \ \ - /* SDCC _asm specific */ \ - TK(ASM, LITERAL) /* _asm ... _endasm ; */ + /* SDCC _asm specific */ \ + TK(ASM, LITERAL) /* _asm ... _endasm ; */ #define OP(e, s) CPP_ ## e, #define TK(e, s) CPP_ ## e, @@ -158,7 +158,7 @@ enum cpp_ttype /* C language kind, used when calling cpp_create_reader. */ enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99, - CLK_GNUCXX, CLK_CXX98, CLK_ASM}; + CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX0X, CLK_CXX0X, CLK_ASM}; /* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ struct cpp_string GTY(()) @@ -168,15 +168,15 @@ struct cpp_string GTY(()) }; /* Flags for the cpp_token structure. */ -#define PREV_WHITE (1 << 0) /* If whitespace before this token. */ -#define DIGRAPH (1 << 1) /* If it was a digraph. */ -#define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */ -#define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */ -#define NAMED_OP (1 << 4) /* C++ named operators. */ -#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ -#define BOL (1 << 6) /* Token at beginning of line. */ -#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, - set in c-lex.c. */ +#define PREV_WHITE (1 << 0) /* If whitespace before this token. */ +#define DIGRAPH (1 << 1) /* If it was a digraph. */ +#define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */ +#define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */ +#define NAMED_OP (1 << 4) /* C++ named operators. */ +#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ +#define BOL (1 << 6) /* Token at beginning of line. */ +#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, + set in c-lex.c. */ /* Specify which field, if any, of the cpp_token union is used. */ @@ -193,19 +193,19 @@ enum cpp_token_fld_kind { occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ struct cpp_token GTY(()) { - source_location src_loc; /* Location of first char of token. */ + source_location src_loc; /* Location of first char of token. */ ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ - unsigned char flags; /* flags - see above */ + unsigned char flags; /* flags - see above */ union cpp_token_u { /* An identifier. */ cpp_hashnode * GTY ((nested_ptr (union tree_node, - "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", - "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"), - tag ("CPP_TOKEN_FLD_NODE"))) - node; + "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", + "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"), + tag ("CPP_TOKEN_FLD_NODE"))) + node; /* Inherit padding from this token. */ cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source; @@ -460,6 +460,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 @@ -484,7 +487,7 @@ struct cpp_callbacks void (*dir_change) (cpp_reader *, const char *); void (*include) (cpp_reader *, unsigned int, const unsigned char *, - const char *, int, const cpp_token **); + const char *, int, const cpp_token **); void (*define) (cpp_reader *, unsigned int, cpp_hashnode *); void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *); void (*ident) (cpp_reader *, unsigned int, const cpp_string *); @@ -547,41 +550,42 @@ extern const char *progname; applies to __VA_ARGS__ and poisoned identifiers. */ /* Hash node flags. */ -#define NODE_OPERATOR (1 << 0) /* C++ named operator. */ -#define NODE_POISONED (1 << 1) /* Poisoned identifier. */ -#define NODE_BUILTIN (1 << 2) /* Builtin macro. */ -#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */ -#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */ -#define NODE_DISABLED (1 << 5) /* A disabled macro. */ -#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ +#define NODE_OPERATOR (1 << 0) /* C++ named operator. */ +#define NODE_POISONED (1 << 1) /* Poisoned identifier. */ +#define NODE_BUILTIN (1 << 2) /* Builtin macro. */ +#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */ +#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */ +#define NODE_DISABLED (1 << 5) /* A disabled macro. */ +#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ /* Different flavors of hash node. */ enum node_type { - NT_VOID = 0, /* No definition yet. */ - NT_MACRO, /* A macro of some form. */ - NT_ASSERTION /* Predicate for #assert. */ + NT_VOID = 0, /* No definition yet. */ + NT_MACRO, /* A macro of some form. */ + NT_ASSERTION /* Predicate for #assert. */ }; /* Different flavors of builtin macro. _Pragma is an operator, but we handle it with the builtin code for efficiency reasons. */ enum builtin_type { - BT_SPECLINE = 0, /* `__LINE__' */ - BT_DATE, /* `__DATE__' */ - BT_FILE, /* `__FILE__' */ - BT_BASE_FILE, /* `__BASE_FILE__' */ - BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ - BT_TIME, /* `__TIME__' */ - BT_STDC, /* `__STDC__' */ - BT_PRAGMA, /* `_Pragma' operator */ - BT_TIMESTAMP /* `__TIMESTAMP__' */ + BT_SPECLINE = 0, /* `__LINE__' */ + BT_DATE, /* `__DATE__' */ + BT_FILE, /* `__FILE__' */ + BT_BASE_FILE, /* `__BASE_FILE__' */ + BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ + BT_TIME, /* `__TIME__' */ + BT_STDC, /* `__STDC__' */ + BT_PRAGMA, /* `_Pragma' operator */ + BT_TIMESTAMP, /* `__TIMESTAMP__' */ + BT_COUNTER /* `__COUNTER__' */ }; -#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) -#define HT_NODE(NODE) ((ht_identifier *) (NODE)) -#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident) -#define NODE_NAME(NODE) HT_STR (&(NODE)->ident) +#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) +#define HT_NODE(NODE) ((ht_identifier *) (NODE)) +#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident) +#define NODE_NAME(NODE) HT_STR (&(NODE)->ident) /* Specify which field, if any, of the union is used. */ @@ -593,11 +597,11 @@ enum { NTV_NONE }; -#define CPP_HASHNODE_VALUE_IDX(HNODE) \ - ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ - : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ - ? NTV_BUILTIN : NTV_MACRO) \ - : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ +#define CPP_HASHNODE_VALUE_IDX(HNODE) \ + ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ + : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ + ? NTV_BUILTIN : NTV_MACRO) \ + : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ : NTV_NONE) /* The common part of an identifier node shared amongst all 3 C front @@ -620,12 +624,12 @@ struct cpp_hashnode GTY(()) { struct ht_identifier ident; unsigned int is_directive : 1; - unsigned int directive_index : 7; /* If is_directive, - then index into directive table. - Otherwise, a NODE_OPERATOR. */ - unsigned char rid_code; /* Rid code - for front ends. */ - ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */ - unsigned char flags; /* CPP flags. */ + unsigned int directive_index : 7; /* If is_directive, + then index into directive table. + Otherwise, a NODE_OPERATOR. */ + unsigned char rid_code; /* Rid code - for front ends. */ + ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */ + unsigned char flags; /* CPP flags. */ union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value; }; @@ -637,7 +641,11 @@ struct cpp_hashnode GTY(()) that cpplib will share; this technique is used by the C front ends. */ extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *, - struct line_maps *); + struct line_maps *); + +/* Reset the cpp_reader's line_map. This is only used after reading a + PCH file. */ +extern void cpp_set_line_map (cpp_reader *, struct line_maps *); /* Call this to change the selected language standard (e.g. because of command line options). */ @@ -663,6 +671,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); @@ -691,28 +703,30 @@ extern unsigned int cpp_errors (cpp_reader *); extern unsigned int cpp_token_len (const cpp_token *); extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *); extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *, - unsigned char *, bool); + unsigned char *, bool); extern void cpp_register_pragma (cpp_reader *, const char *, const char *, - void (*) (cpp_reader *), bool); + void (*) (cpp_reader *), bool); extern void cpp_register_deferred_pragma (cpp_reader *, const char *, - const char *, unsigned, bool, bool); + const char *, unsigned, bool, bool); extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, - const cpp_token *); + const cpp_token *); extern const cpp_token *cpp_get_token (cpp_reader *); +extern const cpp_token *cpp_get_token_with_location (cpp_reader *, + source_location *); extern const unsigned char *cpp_macro_definition (cpp_reader *, - const cpp_hashnode *); + const cpp_hashnode *); extern void _cpp_backup_tokens (cpp_reader *, unsigned int); /* Evaluate a CPP_CHAR or CPP_WCHAR token. */ extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *, - unsigned int *, int *); + unsigned int *, int *); /* Evaluate a vector of CPP_STRING or CPP_WSTRING tokens. */ extern bool cpp_interpret_string (cpp_reader *, - const cpp_string *, size_t, - cpp_string *, bool); + const cpp_string *, size_t, + cpp_string *, bool); extern bool cpp_interpret_string_notranslate (cpp_reader *, - const cpp_string *, size_t, - cpp_string *, bool); + const cpp_string *, size_t, + cpp_string *, bool); /* Convert a host character constant to the execution character set. */ extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); @@ -724,11 +738,14 @@ extern void cpp_assert (cpp_reader *, const char *); extern void cpp_undef (cpp_reader *, const char *); extern void cpp_unassert (cpp_reader *, const char *); +extern cpp_macro *cpp_push_definition (cpp_reader *, const char *); +extern void cpp_pop_definition (cpp_reader *, const char *, cpp_macro *); + /* Undefine all macros and assertions. */ extern void cpp_undef_all (cpp_reader *); extern cpp_buffer *cpp_push_buffer (cpp_reader *, const unsigned char *, - size_t, int); + size_t, int); extern int cpp_defined (cpp_reader *, const unsigned char *, int); /* A preprocessing number. Code assumes that any unused high bits of @@ -751,23 +768,32 @@ struct cpp_num octal, hexadecimal), and type suffixes. */ #define CPP_N_CATEGORY 0x000F -#define CPP_N_INVALID 0x0000 -#define CPP_N_INTEGER 0x0001 -#define CPP_N_FLOATING 0x0002 +#define CPP_N_INVALID 0x0000 +#define CPP_N_INTEGER 0x0001 +#define CPP_N_FLOATING 0x0002 + +#define CPP_N_WIDTH 0x00F0 +#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */ +#define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */ +#define CPP_N_LARGE 0x0040 /* long long, long double, + long long _Fract/Accum. */ + +#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */ +#define CPP_N_MD_W 0x10000 +#define CPP_N_MD_Q 0x20000 -#define CPP_N_WIDTH 0x00F0 -#define CPP_N_SMALL 0x0010 /* int, float. */ -#define CPP_N_MEDIUM 0x0020 /* long, double. */ -#define CPP_N_LARGE 0x0040 /* long long, long double. */ +#define CPP_N_RADIX 0x0F00 +#define CPP_N_DECIMAL 0x0100 +#define CPP_N_HEX 0x0200 +#define CPP_N_OCTAL 0x0400 +#define CPP_N_BINARY 0x0800 -#define CPP_N_RADIX 0x0F00 -#define CPP_N_DECIMAL 0x0100 -#define CPP_N_HEX 0x0200 -#define CPP_N_OCTAL 0x0400 +#define CPP_N_UNSIGNED 0x1000 /* Properties. */ +#define CPP_N_IMAGINARY 0x2000 +#define CPP_N_DFLOAT 0x4000 -#define CPP_N_UNSIGNED 0x1000 /* Properties. */ -#define CPP_N_IMAGINARY 0x2000 -#define CPP_N_DFLOAT 0x4000 +#define CPP_N_FRACT 0x100000 /* Fract types. */ +#define CPP_N_ACCUM 0x200000 /* Accum types. */ /* Classify a CPP_NUMBER token. The return value is a combination of the flags from the above sets. */ @@ -775,7 +801,7 @@ extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *); /* Evaluate a token classified as category CPP_N_INTEGER. */ extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, - unsigned int type); + unsigned int type); /* Sign extend a number, with PRECISION significant bits and all others assumed clear, to fill out a cpp_num structure. */ @@ -786,21 +812,21 @@ cpp_num cpp_num_sign_extend (cpp_num, size_t); with a line number of zero. */ /* Warning, an error with -Werror. */ -#define CPP_DL_WARNING 0x00 +#define CPP_DL_WARNING 0x00 /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */ -#define CPP_DL_WARNING_SYSHDR 0x01 +#define CPP_DL_WARNING_SYSHDR 0x01 /* Warning, an error with -pedantic-errors or -Werror. */ -#define CPP_DL_PEDWARN 0x02 +#define CPP_DL_PEDWARN 0x02 /* An error. */ -#define CPP_DL_ERROR 0x03 +#define CPP_DL_ERROR 0x03 /* An internal consistency check failed. Prints "internal error: ", otherwise the same as CPP_DL_ERROR. */ -#define CPP_DL_ICE 0x04 +#define CPP_DL_ICE 0x04 /* Extracts a diagnostic level from an int. */ -#define CPP_DL_EXTRACT(l) (l & 0xf) +#define CPP_DL_EXTRACT(l) (l & 0xf) /* Nonzero if a diagnostic level is one of the warnings. */ -#define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \ - && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN) +#define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \ + && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN) /* Output a diagnostic of some kind. */ extern void cpp_error (cpp_reader *, int, const char *msgid, ...) @@ -814,7 +840,7 @@ extern void cpp_errno (cpp_reader *, int, const char *msgid); (translation unit) physical line and physical column. If the line is zero, then no location is printed. */ extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned, - const char *msgid, ...) ATTRIBUTE_PRINTF_5; + const char *msgid, ...) ATTRIBUTE_PRINTF_5; /* In cpplex.c */ extern int cpp_ideq (const cpp_token *, const char *); @@ -827,14 +853,14 @@ extern const char *cpp_type2name (enum cpp_ttype); if the escape sequence is part of a wide character constant or string literal. Handles all relevant diagnostics. */ extern cppchar_t cpp_parse_escape (cpp_reader *, const unsigned char ** pstr, - const unsigned char *limit, int wide); + const unsigned char *limit, int wide); /* In cpphash.c */ /* Lookup an identifier in the hashtable. Puts the identifier in the table if it is not already there. */ extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *, - unsigned int); + unsigned int); typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *); extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *); @@ -843,10 +869,11 @@ extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *); extern void cpp_scan_nooutput (cpp_reader *); extern int cpp_sys_macro_p (cpp_reader *); extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *, - unsigned int); + unsigned int); /* In cppfiles.c */ extern bool cpp_included (cpp_reader *, const char *); +extern bool cpp_included_before (cpp_reader *, const char *, source_location); extern void cpp_make_system_header (cpp_reader *, int, int); extern bool cpp_push_include (cpp_reader *, const char *); extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *); @@ -855,6 +882,7 @@ extern cpp_dir *cpp_get_dir (struct _cpp_file *); extern cpp_buffer *cpp_get_buffer (cpp_reader *); extern struct _cpp_file *cpp_get_file (cpp_buffer *); extern cpp_buffer *cpp_get_prev (cpp_buffer *); +extern void cpp_clear_file_cache (cpp_reader *); /* In cpppch.c */ struct save_macro_data; @@ -864,7 +892,7 @@ extern int cpp_write_pch_state (cpp_reader *, FILE *); extern int cpp_valid_state (cpp_reader *, const char *, int); extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **); extern int cpp_read_state (cpp_reader *, const char *, FILE *, - struct save_macro_data *); + struct save_macro_data *); #ifdef __cplusplus } diff --git a/support/cpp2/libcpp/include/line-map.h b/support/cpp/libcpp/include/line-map.h similarity index 92% rename from support/cpp2/libcpp/include/line-map.h rename to support/cpp/libcpp/include/line-map.h index 7e9ede01..f5b5791d 100644 --- a/support/cpp2/libcpp/include/line-map.h +++ b/support/cpp/libcpp/include/line-map.h @@ -1,5 +1,5 @@ /* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003, 2004 + Copyright (C) 2001, 2003, 2004, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef LIBCPP_LINE_MAP_H #define LIBCPP_LINE_MAP_H +#ifndef GTY +#define GTY(x) /* nothing */ +#endif + /* Reason for adding a line change with add_line_map (). LC_ENTER is when including a new file, e.g. a #include directive in C. LC_LEAVE is when reaching a file's end. LC_RENAME is when a file @@ -35,6 +39,9 @@ enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME}; and effectively typedef source_location location_t. */ typedef unsigned int source_location; +/* Memory allocation function typedef. Works like xrealloc. */ +typedef void *(*line_map_realloc) (void *, size_t); + /* Physical source file TO_FILE at line TO_LINE at column 0 is represented by the logical START_LOCATION. TO_LINE+L at column C is represented by START_LOCATION+(L*(1<start_location) \ - & ~((1 << (MAP)->column_bits) - 1)) \ + & ~((1 << (MAP)->column_bits) - 1)) \ + (MAP)->start_location) /* Returns the map a given map was included from. */ @@ -171,9 +182,9 @@ extern void linemap_print_containing_files (struct line_maps *, r = r + to_column; \ if (r >= set->highest_location) \ set->highest_location = r; \ - (LOC) = r; \ + (LOC) = r; \ }} - + extern source_location linemap_position_for_column (struct line_maps *set, unsigned int to_column); diff --git a/support/cpp2/libcpp/include/mkdeps.h b/support/cpp/libcpp/include/mkdeps.h similarity index 100% rename from support/cpp2/libcpp/include/mkdeps.h rename to support/cpp/libcpp/include/mkdeps.h diff --git a/support/cpp2/libcpp/include/symtab.h b/support/cpp/libcpp/include/symtab.h similarity index 89% rename from support/cpp2/libcpp/include/symtab.h rename to support/cpp/libcpp/include/symtab.h index cbcf230d..ebe4139d 100644 --- a/support/cpp2/libcpp/include/symtab.h +++ b/support/cpp/libcpp/include/symtab.h @@ -1,5 +1,5 @@ /* Hash tables. - Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2003, 2004, 2007 Free Software Foundation, Inc. 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 @@ -23,7 +23,9 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #else #include "obstack.h" #endif +#ifndef GTY #define GTY(x) /* nothing */ +#endif /* This is what each hash table entry points to. It may be embedded deeply within another object. */ @@ -56,8 +58,8 @@ struct ht NULL means use the usual allocator. */ void * (*alloc_subobject) (size_t); - unsigned int nslots; /* Total slots in the entries array. */ - unsigned int nelements; /* Number of live elements. */ + unsigned int nslots; /* Total slots in the entries array. */ + unsigned int nelements; /* Number of live elements. */ /* Link to reader, if any. For the benefit of cpplib. */ struct cpp_reader *pfile; @@ -77,7 +79,7 @@ extern hash_table *ht_create (unsigned int order); extern void ht_destroy (hash_table *); extern hashnode ht_lookup (hash_table *, const unsigned char *, - size_t, enum ht_lookup_option); + size_t, enum ht_lookup_option); extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, size_t, unsigned int, enum ht_lookup_option); @@ -92,7 +94,7 @@ extern void ht_forall (hash_table *, ht_cb, const void *); /* Restore the hash table. */ extern void ht_load (hash_table *ht, hashnode *entries, - unsigned int nslots, unsigned int nelements, bool own); + unsigned int nslots, unsigned int nelements, bool own); /* Dump allocation statistics to stderr. */ extern void ht_dump_statistics (hash_table *); diff --git a/support/cpp2/libcpp/init.c b/support/cpp/libcpp/init.c similarity index 79% rename from support/cpp2/libcpp/init.c rename to support/cpp/libcpp/init.c index 20e4545c..40d86a28 100644 --- a/support/cpp2/libcpp/init.c +++ b/support/cpp/libcpp/init.c @@ -1,6 +1,6 @@ /* CPP Library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -58,9 +58,9 @@ __extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { #endif TRIGRAPH_MAP - s('=', '#') s(')', ']') s('!', '|') - s('(', '[') s('\'', '^') s('>', '}') - s('/', '\\') s('<', '{') s('-', '~') + s('=', '#') s(')', ']') s('!', '|') + s('(', '[') s('\'', '^') s('>', '}') + s('/', '\\') s('<', '{') s('-', '~') END #undef s @@ -82,18 +82,20 @@ struct lang_flags static const struct lang_flags lang_defaults[] = { /* c99 c++ xnum xid std // digr */ - /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 }, - /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 }, - /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 }, - /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 }, - /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 }, - /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 }, - /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 }, - /* ASM */ { 0, 0, 1, 0, 0, 1, 0 } - /* xid should be 1 for GNUC99, STDC99, GNUCXX and CXX98 when no - longer experimental (when all uses of identifiers in the compiler - have been audited for correct handling of extended - identifiers). */ + /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 }, + /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 }, + /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 }, + /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 }, + /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 }, + /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 }, + /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 }, + /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1 }, + /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1 }, + /* ASM */ { 0, 0, 1, 0, 0, 1, 0 } + /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and + CXX0X when no longer experimental (when all uses of identifiers + in the compiler have been audited for correct handling of + extended identifiers). */ }; /* Sets internal flags correctly for a given language. */ @@ -104,14 +106,14 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang) CPP_OPTION (pfile, lang) = lang; - CPP_OPTION (pfile, c99) = l->c99; - CPP_OPTION (pfile, cplusplus) = l->cplusplus; - CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; - CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers; - CPP_OPTION (pfile, std) = l->std; - CPP_OPTION (pfile, trigraphs) = l->std; - CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; - CPP_OPTION (pfile, digraphs) = l->digraphs; + CPP_OPTION (pfile, c99) = l->c99; + CPP_OPTION (pfile, cplusplus) = l->cplusplus; + CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; + CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers; + CPP_OPTION (pfile, std) = l->std; + CPP_OPTION (pfile, trigraphs) = l->std; + CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; + CPP_OPTION (pfile, digraphs) = l->digraphs; } /* Initialize library global state. */ @@ -125,8 +127,8 @@ init_library (void) initialized = 1; /* Set up the trigraph map. This doesn't need to do anything if - we were compiled with a compiler that supports C99 designated - initializers. */ + we were compiled with a compiler that supports C99 designated + initializers. */ init_trigraph_map (); #ifdef ENABLE_NLS @@ -138,7 +140,7 @@ init_library (void) /* Initialize a cpp_reader structure. */ cpp_reader * cpp_create_reader (enum c_lang lang, hash_table *table, - struct line_maps *line_table) + struct line_maps *line_table) { cpp_reader *pfile; @@ -217,8 +219,8 @@ cpp_create_reader (enum c_lang lang, hash_table *table, /* Initialize the buffer obstack. */ _obstack_begin (&pfile->buffer_ob, 0, 0, - (void *(*) (long)) xmalloc, - (void (*) (void *)) free); + (void *(*) (long)) xmalloc, + (void (*) (void *)) free); _cpp_init_files (pfile); @@ -227,6 +229,14 @@ cpp_create_reader (enum c_lang lang, hash_table *table, return pfile; } +/* Set the line_table entry in PFILE. This is called after reading a + PCH file, as the old line_table will be incorrect. */ +void +cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table) +{ + pfile->line_table = line_table; +} + /* Free resources used by PFILE. Accessing PFILE after this function returns leads to undefined behavior. Returns the error count. */ void @@ -267,7 +277,7 @@ cpp_destroy (cpp_reader *pfile) runn = run->next; free (run->base); if (run != &pfile->base_run) - free (run); + free (run); } for (context = pfile->base_context.next; context; context = contextn) @@ -303,32 +313,33 @@ struct builtin #define B(n, t) { DSC(n), t } static const struct builtin builtin_array[] = { - B("__TIMESTAMP__", BT_TIMESTAMP), - B("__TIME__", BT_TIME), - B("__DATE__", BT_DATE), - B("__FILE__", BT_FILE), - B("__BASE_FILE__", BT_BASE_FILE), - B("__LINE__", BT_SPECLINE), + B("__TIMESTAMP__", BT_TIMESTAMP), + B("__TIME__", BT_TIME), + B("__DATE__", BT_DATE), + B("__FILE__", BT_FILE), + B("__BASE_FILE__", BT_BASE_FILE), + B("__LINE__", BT_SPECLINE), B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL), + B("__COUNTER__", BT_COUNTER), /* Keep builtins not used for -traditional-cpp at the end, and update init_builtins() if any more are added. */ - B("_Pragma", BT_PRAGMA), - B("__STDC__", BT_STDC), + B("_Pragma", BT_PRAGMA), + B("__STDC__", BT_STDC), }; static const struct builtin operator_array[] = { - B("and", CPP_AND_AND), - B("and_eq", CPP_AND_EQ), - B("bitand", CPP_AND), - B("bitor", CPP_OR), - B("compl", CPP_COMPL), - B("not", CPP_NOT), - B("not_eq", CPP_NOT_EQ), - B("or", CPP_OR_OR), - B("or_eq", CPP_OR_EQ), - B("xor", CPP_XOR), - B("xor_eq", CPP_XOR_EQ) + B("and", CPP_AND_AND), + B("and_eq", CPP_AND_EQ), + B("bitand", CPP_AND), + B("bitor", CPP_OR), + B("compl", CPP_COMPL), + B("not", CPP_NOT), + B("not_eq", CPP_NOT_EQ), + B("or", CPP_OR_OR), + B("or_eq", CPP_OR_EQ), + B("xor", CPP_XOR), + B("xor_eq", CPP_XOR_EQ) }; #undef B @@ -349,11 +360,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,11 +369,8 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) if (CPP_OPTION (pfile, traditional)) n -= 2; else if (! CPP_OPTION (pfile, stdc_0_in_system_headers) - || CPP_OPTION (pfile, std)) - { - n--; - _cpp_define_builtin (pfile, "__STDC__ 1"); - } + || CPP_OPTION (pfile, std)) + n--; for (b = builtin_array; b < builtin_array + n; b++) { @@ -374,6 +379,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"); @@ -410,37 +429,37 @@ static void sanity_checks (cpp_reader *pfile) if (CPP_OPTION (pfile, precision) > max_precision) cpp_error (pfile, CPP_DL_ICE, - "preprocessor arithmetic has maximum precision of %lu bits;" - " target requires %lu bits", - (unsigned long) max_precision, - (unsigned long) CPP_OPTION (pfile, precision)); + "preprocessor arithmetic has maximum precision of %lu bits;" + " target requires %lu bits", + (unsigned long) max_precision, + (unsigned long) CPP_OPTION (pfile, precision)); if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision)) cpp_error (pfile, CPP_DL_ICE, - "CPP arithmetic must be at least as precise as a target int"); + "CPP arithmetic must be at least as precise as a target int"); if (CPP_OPTION (pfile, char_precision) < 8) cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide"); if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision)) cpp_error (pfile, CPP_DL_ICE, - "target wchar_t is narrower than target char"); + "target wchar_t is narrower than target char"); if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision)) cpp_error (pfile, CPP_DL_ICE, - "target int is narrower than target char"); + "target int is narrower than target char"); /* This is assumed in eval_token() and could be fixed if necessary. */ if (sizeof (cppchar_t) > sizeof (cpp_num_part)) cpp_error (pfile, CPP_DL_ICE, - "CPP half-integer narrower than CPP character"); + "CPP half-integer narrower than CPP character"); if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T) cpp_error (pfile, CPP_DL_ICE, - "CPP on this host cannot handle wide character constants over" - " %lu bits, but the target requires %lu bits", - (unsigned long) BITS_PER_CPPCHAR_T, - (unsigned long) CPP_OPTION (pfile, wchar_precision)); + "CPP on this host cannot handle wide character constants over" + " %lu bits, but the target requires %lu bits", + (unsigned long) BITS_PER_CPPCHAR_T, + (unsigned long) CPP_OPTION (pfile, wchar_precision)); } #else # define sanity_checks(PFILE) @@ -469,7 +488,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname) if (CPP_OPTION (pfile, deps.style) != DEPS_NONE) { if (!pfile->deps) - pfile->deps = deps_init (); + pfile->deps = deps_init (); /* Set the default target (if there is none already). */ deps_add_default_target (pfile, fname); @@ -513,11 +532,11 @@ read_original_filename (cpp_reader *pfile) /* If it's a #line directive, handle it. */ if (token1->type == CPP_NUMBER) - { - _cpp_handle_directive (pfile, token->flags & PREV_WHITE); - read_original_directory (pfile); - return; - } + { + _cpp_handle_directive (pfile, token->flags & PREV_WHITE); + read_original_directory (pfile); + return; + } } /* Backup as if nothing happened. */ @@ -553,8 +572,8 @@ read_original_directory (cpp_reader *pfile) if (token->type != CPP_STRING || ! (token->val.str.len >= 5 - && token->val.str.text[token->val.str.len-2] == '/' - && token->val.str.text[token->val.str.len-3] == '/')) + && token->val.str.text[token->val.str.len-2] == '/' + && token->val.str.text[token->val.str.len-3] == '/')) { _cpp_backup_tokens (pfile, 3); return; @@ -565,7 +584,7 @@ read_original_directory (cpp_reader *pfile) char *debugdir = (char *) alloca (token->val.str.len - 3); memcpy (debugdir, (const char *) token->val.str.text + 1, - token->val.str.len - 4); + token->val.str.len - 4); debugdir[token->val.str.len - 4] = '\0'; pfile->cb.dir_change (pfile, debugdir); @@ -600,7 +619,7 @@ cpp_finish (cpp_reader *pfile, FILE *deps_stream) deps_write (pfile->deps, deps_stream, 72); if (CPP_OPTION (pfile, deps.phony_targets)) - deps_phony_targets (pfile->deps, deps_stream); + deps_phony_targets (pfile->deps, deps_stream); } /* Report on headers that could use multiple include guards. */ @@ -621,7 +640,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/support/cpp2/libcpp/internal.h b/support/cpp/libcpp/internal.h similarity index 85% rename from support/cpp2/libcpp/internal.h rename to support/cpp/libcpp/internal.h index d8e07e38..ac08c420 100644 --- a/support/cpp2/libcpp/internal.h +++ b/support/cpp/libcpp/internal.h @@ -1,5 +1,5 @@ /* Part of CPP library. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -37,13 +37,13 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ typedef int iconv_t; /* dummy */ #endif -struct directive; /* Deliberately incomplete. */ +struct directive; /* Deliberately incomplete. */ struct pending_option; struct op; struct _cpp_strbuf; typedef bool (*convert_f) (iconv_t, const unsigned char *, size_t, - struct _cpp_strbuf *); + struct _cpp_strbuf *); struct cset_converter { convert_f func; @@ -90,8 +90,8 @@ struct dummy #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) -#define _cpp_mark_macro_used(NODE) do { \ - if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ +#define _cpp_mark_macro_used(NODE) do { \ + if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ (NODE)->value.macro->used = 1; } while (0) /* A generic memory buffer, and operations on it. */ @@ -225,12 +225,12 @@ struct lexer_state /* Special nodes - identifiers with predefined significance. */ struct spec_nodes { - cpp_hashnode *n_defined; /* defined operator */ - cpp_hashnode *n_true; /* C++ keyword true */ - cpp_hashnode *n_false; /* C++ keyword false */ - cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ + cpp_hashnode *n_defined; /* defined operator */ + cpp_hashnode *n_true; /* C++ keyword true */ + cpp_hashnode *n_false; /* C++ keyword false */ + cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ /* SDCC _asm specific */ - cpp_hashnode *n__asm; /* _asm ... _endasm ; */ + cpp_hashnode *n__asm; /* _asm ... _endasm ; */ }; typedef struct _cpp_line_note _cpp_line_note; @@ -327,9 +327,9 @@ struct cpp_reader source_location directive_line; /* Memory buffers. */ - _cpp_buff *a_buff; /* Aligned permanent storage. */ - _cpp_buff *u_buff; /* Unaligned permanent storage. */ - _cpp_buff *free_buffs; /* Free buffer chain. */ + _cpp_buff *a_buff; /* Aligned permanent storage. */ + _cpp_buff *u_buff; /* Unaligned permanent storage. */ + _cpp_buff *free_buffs; /* Free buffer chain. */ /* Context stack. */ struct cpp_context base_context; @@ -341,10 +341,18 @@ struct cpp_reader /* Token generated while handling a directive, if any. */ cpp_token directive_result; + /* When expanding a macro at top-level, this is the location of the + macro invocation. */ + source_location invocation_location; + + /* True if this call to cpp_get_token should consider setting + invocation_location. */ + bool set_invocation_location; + /* Search paths for include files. */ - struct cpp_dir *quote_include; /* "" */ - struct cpp_dir *bracket_include; /* <> */ - struct cpp_dir no_search_path; /* No path. */ + struct cpp_dir *quote_include; /* "" */ + struct cpp_dir *bracket_include; /* <> */ + struct cpp_dir no_search_path; /* No path. */ /* Chain of all hashed _cpp_file instances. */ struct _cpp_file *all_files; @@ -354,8 +362,11 @@ struct cpp_reader /* File and directory hash table. */ struct htab *file_hash; struct htab *dir_hash; - struct file_hash_entry *file_hash_entries; - unsigned int file_hash_entries_allocated, file_hash_entries_used; + struct file_hash_entry_pool *file_hash_entries; + + /* 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. */ @@ -450,6 +461,9 @@ struct cpp_reader /* A saved list of the defined macros, for dependency checking of precompiled headers. */ struct cpp_savedstate *savedstate; + + /* Next value of __COUNTER__ macro. */ + unsigned int counter; }; /* Character classes. Based on the more primitive macros in safe-ctype.h. @@ -459,16 +473,16 @@ struct cpp_reader In the unlikely event that characters other than \r and \n enter the set is_vspace, the macro handle_newline() in lex.c must be updated. */ -#define _dollar_ok(x) ((x) == '$' && CPP_OPTION (pfile, dollars_in_ident)) +#define _dollar_ok(x) ((x) == '$' && CPP_OPTION (pfile, dollars_in_ident)) -#define is_idchar(x) (ISIDNUM(x) || _dollar_ok(x)) -#define is_numchar(x) ISIDNUM(x) -#define is_idstart(x) (ISIDST(x) || _dollar_ok(x)) -#define is_numstart(x) ISDIGIT(x) -#define is_hspace(x) ISBLANK(x) -#define is_vspace(x) IS_VSPACE(x) -#define is_nvspace(x) IS_NVSPACE(x) -#define is_space(x) IS_SPACE_OR_NUL(x) +#define is_idchar(x) (ISIDNUM(x) || _dollar_ok(x)) +#define is_numchar(x) ISIDNUM(x) +#define is_idstart(x) (ISIDST(x) || _dollar_ok(x)) +#define is_numstart(x) ISDIGIT(x) +#define is_hspace(x) ISBLANK(x) +#define is_vspace(x) IS_VSPACE(x) +#define is_nvspace(x) IS_NVSPACE(x) +#define is_space(x) IS_SPACE_OR_NUL(x) /* This table is constant if it can be initialized at compile time, which is the case if cpp was compiled with GCC >=2.7, or another @@ -490,24 +504,31 @@ cpp_in_system_header (cpp_reader *pfile) #define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic) #define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional) +static inline int cpp_in_primary_file (cpp_reader *); +static inline int +cpp_in_primary_file (cpp_reader *pfile) +{ + return pfile->line_table->depth == 1; +} + /* In errors.c */ extern int _cpp_begin_message (cpp_reader *, int, - source_location, unsigned int); + source_location, unsigned int); /* In macro.c */ extern void _cpp_free_definition (cpp_hashnode *); extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); extern void _cpp_pop_context (cpp_reader *); extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *, - const unsigned char *, size_t); + const unsigned char *, size_t); extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *); extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, - unsigned int); + unsigned int); extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, - cpp_hashnode *); + cpp_hashnode *); extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, - const cpp_token *, unsigned int); + const cpp_token *, unsigned int); /* In identifiers.c */ extern void _cpp_init_hashtable (cpp_reader *, hash_table *); @@ -516,13 +537,13 @@ extern void _cpp_destroy_hashtable (cpp_reader *); /* In files.c */ typedef struct _cpp_file _cpp_file; extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *, - bool, int); + bool, int); extern bool _cpp_find_failed (_cpp_file *); extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *); extern void _cpp_fake_include (cpp_reader *, const char *); extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool); extern bool _cpp_stack_include (cpp_reader *, const char *, int, - enum include_type); + enum include_type); extern int _cpp_compare_file_date (cpp_reader *, const char *, int); extern void _cpp_report_missing_guards (cpp_reader *); extern void _cpp_init_files (cpp_reader *); @@ -556,24 +577,35 @@ extern int _cpp_handle_directive (cpp_reader *, int); extern void _cpp_define_builtin (cpp_reader *, const char *); extern char ** _cpp_save_pragma_names (cpp_reader *); extern void _cpp_restore_pragma_names (cpp_reader *, char **); -extern void _cpp_do__Pragma (cpp_reader *); +extern int _cpp_do__Pragma (cpp_reader *); extern void _cpp_init_directives (cpp_reader *); extern void _cpp_init_internal_pragmas (cpp_reader *); extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *, - unsigned int, unsigned int); + 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 *); extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *, - size_t); + size_t); extern void _cpp_remove_overlay (cpp_reader *); extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *); extern bool _cpp_expansions_different_trad (const cpp_macro *, - const cpp_macro *); + const cpp_macro *); extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *, - unsigned char *); + unsigned char *); extern size_t _cpp_replacement_text_len (const cpp_macro *); /* In charset.c. */ @@ -600,16 +632,16 @@ struct normalize_state ((st)->previous = 0, (st)->prev_class = 0) extern cppchar_t _cpp_valid_ucn (cpp_reader *, const unsigned char **, - const unsigned char *, int, - struct normalize_state *state); + const unsigned char *, int, + struct normalize_state *state); extern void _cpp_destroy_iconv (cpp_reader *); extern unsigned char *_cpp_convert_input (cpp_reader *, const char *, - unsigned char *, size_t, size_t, - off_t *); + unsigned char *, size_t, size_t, + off_t *); extern const char *_cpp_default_encoding (void); extern cpp_hashnode * _cpp_interpret_identifier (cpp_reader *pfile, - const unsigned char *id, - size_t len); + const unsigned char *id, + size_t len); /* Utility routines and macros. */ #define DSC(str) (const unsigned char *)str, sizeof str - 1 @@ -618,7 +650,7 @@ extern cpp_hashnode * _cpp_interpret_identifier (cpp_reader *pfile, checking. */ static inline int ustrcmp (const unsigned char *, const unsigned char *); static inline int ustrncmp (const unsigned char *, const unsigned char *, - size_t); + size_t); static inline size_t ustrlen (const unsigned char *); static inline unsigned char *uxstrdup (const unsigned char *); static inline unsigned char *ustrchr (const unsigned char *, int); diff --git a/support/cpp2/libcpp/lex.c b/support/cpp/libcpp/lex.c similarity index 67% rename from support/cpp2/libcpp/lex.c rename to support/cpp/libcpp/lex.c index 22dc7e7e..78df1dff 100644 --- a/support/cpp2/libcpp/lex.c +++ b/support/cpp/libcpp/lex.c @@ -57,7 +57,7 @@ static void skip_whitespace (cpp_reader *, cppchar_t); static void lex_string (cpp_reader *, cpp_token *, const uchar *); static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t); static void create_literal (cpp_reader *, cpp_token *, const uchar *, - unsigned int, enum cpp_ttype); + unsigned int, enum cpp_ttype); static bool warn_in_comment (cpp_reader *, _cpp_line_note *); static int name_p (cpp_reader *, const cpp_string *); static tokenrun *next_tokenrun (tokenrun *); @@ -112,104 +112,116 @@ _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. */ + 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') - { - d = (uchar *) s; - - if (s == buffer->rlimit) - goto done; - - /* DOS line ending? */ - if (c == '\r' && s[1] == '\n') - s++; - - if (s == buffer->rlimit) - goto done; - - /* check for escaped newline */ - p = d; - while (p != buffer->next_line && is_nvspace (p[-1])) - p--; - if (p == buffer->next_line || p[-1] != '\\') - goto done; - - /* Have an escaped newline; process it and proceed to - the slow path. */ - add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); - d = p - 2; - buffer->next_line = p - 1; - break; - } - if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) - { - /* Have a trigraph. We may or may not have to convert - it. Add a line note regardless, for -Wtrigraphs. */ - add_line_note (buffer, s, s[2]); - if (CPP_OPTION (pfile, trigraphs)) - { - /* We do, and that means we have to switch to the - slow path. */ - d = (uchar *) s; - *d = _cpp_trigraph_map[s[2]]; - s += 2; - break; - } - } - } + { + c = *++s; + if (__builtin_expect (c == '\n', false) + || __builtin_expect (c == '\r', false)) + { + d = (uchar *) s; + + if (__builtin_expect (s == buffer->rlimit, false)) + goto done; + + /* DOS line ending? */ + if (__builtin_expect (c == '\r', false) + && s[1] == '\n') + { + s++; + if (s == buffer->rlimit) + goto done; + } + + if (__builtin_expect (pbackslash == NULL, true)) + goto done; + + /* Check for escaped newline. */ + p = d; + while (is_nvspace (p[-1])) + p--; + if (p - 1 != pbackslash) + goto done; + + /* Have an escaped newline; process it and proceed to + the slow path. */ + add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); + d = p - 2; + buffer->next_line = p - 1; + break; + } + 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. */ + add_line_note (buffer, s, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + /* We do, and that means we have to switch to the + slow path. */ + d = (uchar *) s; + *d = _cpp_trigraph_map[s[2]]; + s += 2; + break; + } + } + } for (;;) - { - c = *++s; - *++d = c; - - if (c == '\n' || c == '\r') - { - /* Handle DOS line endings. */ - if (c == '\r' && s != buffer->rlimit && s[1] == '\n') - s++; - if (s == buffer->rlimit) - break; - - /* Escaped? */ - p = d; - while (p != buffer->next_line && is_nvspace (p[-1])) - p--; - if (p == buffer->next_line || p[-1] != '\\') - break; - - add_line_note (buffer, p - 1, p != d ? ' ': '\\'); - d = p - 2; - buffer->next_line = p - 1; - } - else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) - { - /* Add a note regardless, for the benefit of -Wtrigraphs. */ - add_line_note (buffer, d, s[2]); - if (CPP_OPTION (pfile, trigraphs)) - { - *d = _cpp_trigraph_map[s[2]]; - s += 2; - } - } - } + { + c = *++s; + *++d = c; + + if (c == '\n' || c == '\r') + { + /* Handle DOS line endings. */ + if (c == '\r' && s != buffer->rlimit && s[1] == '\n') + s++; + if (s == buffer->rlimit) + break; + + /* Escaped? */ + p = d; + while (p != buffer->next_line && is_nvspace (p[-1])) + p--; + if (p == buffer->next_line || p[-1] != '\\') + break; + + add_line_note (buffer, p - 1, p != d ? ' ': '\\'); + d = p - 2; + buffer->next_line = p - 1; + } + else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) + { + /* Add a note regardless, for the benefit of -Wtrigraphs. */ + add_line_note (buffer, d, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + *d = _cpp_trigraph_map[s[2]]; + s += 2; + } + } + } } else { do - s++; + s++; while (*s != '\n' && *s != '\r'); d = (uchar *) s; /* Handle DOS line endings. */ if (*s == '\r' && s != buffer->rlimit && s[1] == '\n') - s++; + s++; } done: @@ -260,49 +272,49 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment) unsigned int col; if (note->pos > buffer->cur) - break; + break; buffer->cur_note++; col = CPP_BUF_COLUMN (buffer, note->pos + 1); if (note->type == '\\' || note->type == ' ') - { - if (note->type == ' ' && !in_comment) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, - "backslash and newline separated by space"); - - if (buffer->next_line > buffer->rlimit) - { - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, - "backslash-newline at end of file"); - /* Prevent "no newline at end of file" warning. */ - buffer->next_line = buffer->rlimit; - } - - buffer->line_base = note->pos; - CPP_INCREMENT_LINE (pfile, 0); - } + { + if (note->type == ' ' && !in_comment) + cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, + "backslash and newline separated by space"); + + if (buffer->next_line > buffer->rlimit) + { + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, + "backslash-newline at end of file"); + /* Prevent "no newline at end of file" warning. */ + buffer->next_line = buffer->rlimit; + } + + buffer->line_base = note->pos; + CPP_INCREMENT_LINE (pfile, 0); + } else if (_cpp_trigraph_map[note->type]) - { - if (CPP_OPTION (pfile, warn_trigraphs) - && (!in_comment || warn_in_comment (pfile, note))) - { - if (CPP_OPTION (pfile, trigraphs)) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, - "trigraph ??%c converted to %c", - note->type, - (int) _cpp_trigraph_map[note->type]); - else - { - cpp_error_with_line - (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, - "trigraph ??%c ignored, use -trigraphs to enable", - note->type); - } - } - } + { + if (CPP_OPTION (pfile, warn_trigraphs) + && (!in_comment || warn_in_comment (pfile, note))) + { + if (CPP_OPTION (pfile, trigraphs)) + cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, + "trigraph ??%c converted to %c", + note->type, + (int) _cpp_trigraph_map[note->type]); + else + { + cpp_error_with_line + (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, + "trigraph ??%c ignored, use -trigraphs to enable", + note->type); + } + } + } else - abort (); + abort (); } } @@ -373,40 +385,40 @@ _cpp_skip_block_comment (cpp_reader *pfile) for (;;) { /* People like decorating comments with '*', so check for '/' - instead for efficiency. */ + instead for efficiency. */ c = *cur++; if (c == '/') - { - if (cur[-2] == '*') - break; - - /* Warn about potential nested comments, but not if the '/' - comes immediately before the true comment delimiter. - Don't bother to get it right across escaped newlines. */ - if (CPP_OPTION (pfile, warn_comments) - && cur[0] == '*' && cur[1] != '/') - { - buffer->cur = cur; - cpp_error_with_line (pfile, CPP_DL_WARNING, - pfile->line_table->highest_line, CPP_BUF_COL (buffer), - "\"/*\" within comment"); - } - } + { + if (cur[-2] == '*') + break; + + /* Warn about potential nested comments, but not if the '/' + comes immediately before the true comment delimiter. + Don't bother to get it right across escaped newlines. */ + if (CPP_OPTION (pfile, warn_comments) + && cur[0] == '*' && cur[1] != '/') + { + buffer->cur = cur; + cpp_error_with_line (pfile, CPP_DL_WARNING, + pfile->line_table->highest_line, CPP_BUF_COL (buffer), + "\"/*\" within comment"); + } + } else if (c == '\n') - { - unsigned int cols; - buffer->cur = cur - 1; - _cpp_process_line_notes (pfile, true); - if (buffer->next_line >= buffer->rlimit) - return true; - _cpp_clean_line (pfile); - - cols = buffer->next_line - buffer->line_base; - CPP_INCREMENT_LINE (pfile, cols); - - cur = buffer->cur; - } + { + unsigned int cols; + buffer->cur = cur - 1; + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; + _cpp_clean_line (pfile); + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + + cur = buffer->cur; + } } buffer->cur = cur; @@ -441,15 +453,15 @@ skip_whitespace (cpp_reader *pfile, cppchar_t c) { /* Horizontal space always OK. */ if (c == ' ' || c == '\t') - ; + ; /* Just \f \v or \0 left. */ else if (c == '\0') - saw_NUL = true; + saw_NUL = true; else if (pfile->state.in_directive && CPP_PEDANTIC (pfile)) - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, - CPP_BUF_COL (buffer), - "%s in preprocessing directive", - c == '\f' ? "form feed" : "vertical tab"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, + CPP_BUF_COL (buffer), + "%s in preprocessing directive", + c == '\f' ? "form feed" : "vertical tab"); c = *buffer->cur++; } @@ -480,24 +492,24 @@ name_p (cpp_reader *pfile, const cpp_string *string) sequences not in NFC/NFKC. */ static void warn_about_normalization (cpp_reader *pfile, - const cpp_token *token, - const struct normalize_state *s) + const cpp_token *token, + const struct normalize_state *s) { if (CPP_OPTION (pfile, warn_normalize) < NORMALIZE_STATE_RESULT (s) && !pfile->state.skipping) { /* Make sure that the token is printed using UCNs, even - if we'd otherwise happily print UTF-8. */ + if we'd otherwise happily print UTF-8. */ unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token)); size_t sz; sz = cpp_spell_token (pfile, token, buf, false) - buf; if (NORMALIZE_STATE_RESULT (s) == normalized_C) - cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0, - "`%.*s' is not in NFKC", (int) sz, buf); + cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0, + "`%.*s' is not in NFKC", (int) sz, buf); else - cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0, - "`%.*s' is not in NFC", (int) sz, buf); + cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0, + "`%.*s' is not in NFC", (int) sz, buf); } } @@ -505,21 +517,21 @@ warn_about_normalization (cpp_reader *pfile, an identifier. FIRST is TRUE if this starts an identifier. */ static bool forms_identifier_p (cpp_reader *pfile, int first, - struct normalize_state *state) + struct normalize_state *state) { cpp_buffer *buffer = pfile->buffer; if (*buffer->cur == '$') { if (!CPP_OPTION (pfile, dollars_in_ident)) - return false; + return false; buffer->cur++; if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) - { - CPP_OPTION (pfile, warn_dollars) = 0; - cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); - } + { + CPP_OPTION (pfile, warn_dollars) = 0; + cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); + } return true; } @@ -531,8 +543,8 @@ forms_identifier_p (cpp_reader *pfile, int first, { buffer->cur += 2; if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, - state)) - return true; + state)) + return true; buffer->cur -= 2; } @@ -542,7 +554,7 @@ forms_identifier_p (cpp_reader *pfile, int first, /* Lex an identifier starting at BUFFER->CUR - 1. */ static cpp_hashnode * lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, - struct normalize_state *nst) + struct normalize_state *nst) { cpp_hashnode *result; const uchar *cur; @@ -553,22 +565,22 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, if (! starts_ucn) while (ISIDNUM (*cur)) { - hash = HT_HASHSTEP (hash, *cur); - cur++; + hash = HT_HASHSTEP (hash, *cur); + cur++; } pfile->buffer->cur = cur; if (starts_ucn || forms_identifier_p (pfile, false, nst)) { /* Slower version for identifiers containing UCNs (or $). */ do { - while (ISIDNUM (*pfile->buffer->cur)) - { - pfile->buffer->cur++; - NORMALIZE_STATE_UPDATE_IDNUM (nst); - } + while (ISIDNUM (*pfile->buffer->cur)) + { + pfile->buffer->cur++; + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } } while (forms_identifier_p (pfile, false, nst)); result = _cpp_interpret_identifier (pfile, base, - pfile->buffer->cur - base); + pfile->buffer->cur - base); } else { @@ -576,25 +588,25 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, hash = HT_HASHFINISH (hash, len); result = (cpp_hashnode *) - ht_lookup_with_hash (pfile->hash_table, base, len, hash, HT_ALLOC); + ht_lookup_with_hash (pfile->hash_table, base, len, hash, HT_ALLOC); } /* Rarely, identifiers require diagnostics when lexed. */ if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) - && !pfile->state.skipping, 0)) + && !pfile->state.skipping, 0)) { /* It is allowed to poison the same identifier twice. */ if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) - cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", - NODE_NAME (result)); + cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", + NODE_NAME (result)); /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the - replacement list of a variadic macro. */ + replacement list of a variadic macro. */ if (result == pfile->spec_nodes.n__VA_ARGS__ - && !pfile->state.va_args_ok) - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C99 variadic macro"); + && !pfile->state.va_args_ok) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); } return result; @@ -845,7 +857,7 @@ pedantic_lex_number (cpp_reader *pfile, cpp_string *number) /* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ static void lex_number (cpp_reader *pfile, cpp_string *number, - struct normalize_state *nst) + struct normalize_state *nst) { const uchar *cur; const uchar *base; @@ -858,10 +870,10 @@ lex_number (cpp_reader *pfile, cpp_string *number, /* N.B. ISIDNUM does not include $. */ while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) - { - cur++; - NORMALIZE_STATE_UPDATE_IDNUM (nst); - } + { + cur++; + NORMALIZE_STATE_UPDATE_IDNUM (nst); + } pfile->buffer->cur = cur; } @@ -877,7 +889,7 @@ lex_number (cpp_reader *pfile, cpp_string *number, /* Create a token of type TYPE with a literal spelling. */ static void create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, - unsigned int len, enum cpp_ttype type) + unsigned int len, enum cpp_ttype type) { uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); @@ -920,26 +932,26 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) /* In #include-style directives, terminators are not escapable. */ if (c == '\\' && !pfile->state.angled_headers && *cur != '\n') - cur++; + cur++; else if (c == terminator) - break; + break; else if (c == '\n') - { - cur--; - type = CPP_OTHER; - break; - } + { + cur--; + type = CPP_OTHER; + break; + } else if (c == '\0') - saw_NUL = true; + saw_NUL = true; } if (saw_NUL && !pfile->state.skipping) cpp_error (pfile, CPP_DL_WARNING, - "null character(s) preserved in literal"); + "null character(s) preserved in literal"); if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM) cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", - (int) terminator); + (int) terminator); pfile->buffer->cur = cur; create_literal (pfile, token, base, cur - base, type); @@ -1001,7 +1013,7 @@ save_asm (cpp_reader *pfile, cpp_token *token, const unsigned char *from) /* The stored comment includes the comment start and any terminator. */ static void save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, - cppchar_t type) + cppchar_t type) { unsigned char *buffer; unsigned int len, clen; @@ -1094,54 +1106,59 @@ _cpp_lex_token (cpp_reader *pfile) for (;;) { if (pfile->cur_token == pfile->cur_run->limit) - { - pfile->cur_run = next_tokenrun (pfile->cur_run); - pfile->cur_token = pfile->cur_run->base; - } + { + 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) - { - pfile->lookaheads--; - result = pfile->cur_token++; - } + { + pfile->lookaheads--; + result = pfile->cur_token++; + } else - result = _cpp_lex_direct (pfile); + result = _cpp_lex_direct (pfile); if (result->flags & BOL) - { - /* Is this a directive. If _cpp_handle_directive returns - false, it is an assembler #. */ - if (result->type == CPP_HASH - /* 6.10.3 p 11: Directives in a list of macro arguments - gives undefined behavior. This implementation - handles the directive as normal. */ - && pfile->state.parsing_args != 1) - { - if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) - { - if (pfile->directive_result.type == CPP_PADDING) - continue; - result = &pfile->directive_result; - } - } - else if (pfile->state.in_deferred_pragma) - result = &pfile->directive_result; - - if (pfile->cb.line_change && !pfile->state.skipping) - pfile->cb.line_change (pfile, result, pfile->state.parsing_args); - } + { + /* Is this a directive. If _cpp_handle_directive returns + false, it is an assembler #. */ + if (result->type == CPP_HASH + /* 6.10.3 p 11: Directives in a list of macro arguments + gives undefined behavior. This implementation + handles the directive as normal. */ + && pfile->state.parsing_args != 1) + { + if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) + { + if (pfile->directive_result.type == CPP_PADDING) + continue; + result = &pfile->directive_result; + } + } + else if (pfile->state.in_deferred_pragma) + result = &pfile->directive_result; + + if (pfile->cb.line_change && !pfile->state.skipping) + pfile->cb.line_change (pfile, result, pfile->state.parsing_args); + } /* We don't skip tokens in directives. */ if (pfile->state.in_directive || pfile->state.in_deferred_pragma) - break; + break; /* Outside a directive, invalidate controlling macros. At file - EOF, _cpp_lex_direct takes care of popping the buffer, so we never - get here and MI optimization works. */ + EOF, _cpp_lex_direct takes care of popping the buffer, so we never + get here and MI optimization works. */ pfile->mi_valid = false; if (!pfile->state.skipping || result->type == CPP_EOF) - break; + break; } return result; @@ -1162,44 +1179,41 @@ _cpp_get_fresh_line (cpp_reader *pfile) cpp_buffer *buffer = pfile->buffer; if (!buffer->need_line) - return true; + return true; if (buffer->next_line < buffer->rlimit) - { - _cpp_clean_line (pfile); - return true; - } + { + _cpp_clean_line (pfile); + return true; + } /* First, get out of parsing arguments state. */ if (pfile->state.parsing_args) - return false; + return false; /* End of buffer. Non-empty files should end in a newline. */ if (buffer->buf != buffer->rlimit - && buffer->next_line > buffer->rlimit - && !buffer->from_stage3) - { - /* Only warn once. */ - 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"); - } + && buffer->next_line > buffer->rlimit + && !buffer->from_stage3) + { + /* Clip to buffer size. */ + buffer->next_line = buffer->rlimit; + } return_at_eof = buffer->return_at_eof; _cpp_pop_buffer (pfile); if (pfile->buffer == NULL || return_at_eof) - return false; + return false; } } -#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ - do \ - { \ - result->type = ELSE_TYPE; \ - if (*buffer->cur == CHAR) \ - buffer->cur++, result->type = THEN_TYPE; \ - } \ +#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ + do \ + { \ + result->type = ELSE_TYPE; \ + if (*buffer->cur == CHAR) \ + buffer->cur++, result->type = THEN_TYPE; \ + } \ while (0) /* Lex a token into pfile->cur_token, which is also incremented, to @@ -1227,33 +1241,33 @@ _cpp_lex_direct (cpp_reader *pfile) if (buffer->need_line) { if (pfile->state.in_deferred_pragma) - { - result->type = CPP_PRAGMA_EOL; - pfile->state.in_deferred_pragma = false; - if (!pfile->state.pragma_allow_expansion) - pfile->state.prevent_expansion--; - return result; - } + { + result->type = CPP_PRAGMA_EOL; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } if (!_cpp_get_fresh_line (pfile)) - { - result->type = CPP_EOF; - if (!pfile->state.in_directive) - { - /* Tell the compiler the line number of the EOF token. */ - result->src_loc = pfile->line_table->highest_line; - result->flags = BOL; - } - return result; - } + { + result->type = CPP_EOF; + if (!pfile->state.in_directive) + { + /* Tell the compiler the line number of the EOF token. */ + result->src_loc = pfile->line_table->highest_line; + result->flags = BOL; + } + return result; + } if (!pfile->keep_tokens) - { - pfile->cur_run = &pfile->base_run; - result = pfile->base_run.base; - pfile->cur_token = result + 1; - } + { + pfile->cur_run = &pfile->base_run; + result = pfile->base_run.base; + pfile->cur_token = result + 1; + } result->flags = BOL; if (pfile->state.parsing_args == 2) - result->flags |= PREV_WHITE; + result->flags |= PREV_WHITE; } buffer = pfile->buffer; update_tokens_line: @@ -1269,7 +1283,7 @@ _cpp_lex_direct (cpp_reader *pfile) c = *buffer->cur++; LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table, - CPP_BUF_COLUMN (buffer, buffer->cur)); + CPP_BUF_COLUMN (buffer, buffer->cur)); switch (c) { @@ -1280,30 +1294,30 @@ _cpp_lex_direct (cpp_reader *pfile) case '\n': if (buffer->cur < buffer->rlimit) - CPP_INCREMENT_LINE (pfile, 0); + CPP_INCREMENT_LINE (pfile, 0); buffer->need_line = true; goto fresh_line; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->type = CPP_NUMBER; - if (CPP_OPTION(pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str, &nst); - warn_about_normalization (pfile, result, &nst); - break; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + if (CPP_OPTION(pfile, pedantic_parse_number)) + pedantic_lex_number (pfile, &result->val.str); + else + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + break; } case 'L': /* 'L' may introduce wide characters or strings. */ if (*buffer->cur == '\'' || *buffer->cur == '"') - { - lex_string (pfile, result, buffer->cur - 1); - break; - } + { + lex_string (pfile, result, buffer->cur - 1); + break; + } /* Fall through. */ case '_': @@ -1319,10 +1333,10 @@ _cpp_lex_direct (cpp_reader *pfile) case 'Y': case 'Z': result->type = CPP_NAME; { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->val.node = lex_identifier (pfile, buffer->cur - 1, false, - &nst); - warn_about_normalization (pfile, result, &nst); + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->val.node = lex_identifier (pfile, buffer->cur - 1, false, + &nst); + warn_about_normalization (pfile, result, &nst); } /* SDCC _asm specific */ @@ -1337,10 +1351,10 @@ _cpp_lex_direct (cpp_reader *pfile) } /* Convert named operators to their proper types. */ else if (result->val.node->flags & NODE_OPERATOR) - { - result->flags |= NAMED_OP; - result->type = (enum cpp_ttype) result->val.node->directive_index; - } + { + result->flags |= NAMED_OP; + result->type = (enum cpp_ttype) result->val.node->directive_index; + } break; case '\'': @@ -1354,45 +1368,45 @@ _cpp_lex_direct (cpp_reader *pfile) c = *buffer->cur; if (c == '*') - { - if (_cpp_skip_block_comment (pfile)) - cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); - } + { + if (_cpp_skip_block_comment (pfile)) + cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); + } else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments) - || cpp_in_system_header (pfile))) - { - /* Warn about comments only if pedantically GNUC89, and not - in system headers. */ - if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile) - && ! buffer->warned_cplusplus_comments) - { - cpp_error (pfile, CPP_DL_PEDWARN, - "C++ style comments are not allowed in ISO C90"); - cpp_error (pfile, CPP_DL_PEDWARN, - "(this will be reported only once per input file)"); - buffer->warned_cplusplus_comments = 1; - } - - if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments)) - cpp_error (pfile, CPP_DL_WARNING, "multi-line comment"); - } + || cpp_in_system_header (pfile))) + { + /* Warn about comments only if pedantically GNUC89, and not + in system headers. */ + if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile) + && ! buffer->warned_cplusplus_comments) + { + cpp_error (pfile, CPP_DL_PEDWARN, + "C++ style comments are not allowed in ISO C90"); + cpp_error (pfile, CPP_DL_PEDWARN, + "(this will be reported only once per input file)"); + buffer->warned_cplusplus_comments = 1; + } + + if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments)) + cpp_error (pfile, CPP_DL_WARNING, "multi-line comment"); + } else if (c == '=') - { - buffer->cur++; - result->type = CPP_DIV_EQ; - break; - } + { + buffer->cur++; + result->type = CPP_DIV_EQ; + break; + } else - { - result->type = CPP_DIV; - break; - } + { + result->type = CPP_DIV; + break; + } if (!pfile->state.save_comments) - { - result->flags |= PREV_WHITE; - goto update_tokens_line; - } + { + result->flags |= PREV_WHITE; + goto update_tokens_line; + } /* Save the comment as a token in its own right. */ save_comment (pfile, result, comment_start, c); @@ -1400,137 +1414,137 @@ _cpp_lex_direct (cpp_reader *pfile) case '<': if (pfile->state.angled_headers) - { - lex_string (pfile, result, buffer->cur - 1); - break; - } + { + lex_string (pfile, result, buffer->cur - 1); + break; + } result->type = CPP_LESS; if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_LESS_EQ; + buffer->cur++, result->type = CPP_LESS_EQ; else if (*buffer->cur == '<') - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); - } + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); + } else if (CPP_OPTION (pfile, digraphs)) - { - if (*buffer->cur == ':') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_OPEN_SQUARE; - } - else if (*buffer->cur == '%') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_OPEN_BRACE; - } - } + { + if (*buffer->cur == ':') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_SQUARE; + } + else if (*buffer->cur == '%') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_BRACE; + } + } break; case '>': result->type = CPP_GREATER; if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_GREATER_EQ; + buffer->cur++, result->type = CPP_GREATER_EQ; else if (*buffer->cur == '>') - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); - } + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); + } break; case '%': result->type = CPP_MOD; if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_MOD_EQ; + buffer->cur++, result->type = CPP_MOD_EQ; else if (CPP_OPTION (pfile, digraphs)) - { - if (*buffer->cur == ':') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_HASH; - if (*buffer->cur == '%' && buffer->cur[1] == ':') - buffer->cur += 2, result->type = CPP_PASTE; - } - else if (*buffer->cur == '>') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_CLOSE_BRACE; - } - } + { + if (*buffer->cur == ':') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_HASH; + if (*buffer->cur == '%' && buffer->cur[1] == ':') + buffer->cur += 2, result->type = CPP_PASTE; + } + else if (*buffer->cur == '>') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_BRACE; + } + } break; case '.': result->type = CPP_DOT; if (ISDIGIT (*buffer->cur)) - { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->type = CPP_NUMBER; - if (CPP_OPTION(pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str, &nst); - warn_about_normalization (pfile, result, &nst); - } + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + if (CPP_OPTION(pfile, pedantic_parse_number)) + pedantic_lex_number (pfile, &result->val.str); + else + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + } else if (*buffer->cur == '.' && buffer->cur[1] == '.') - buffer->cur += 2, result->type = CPP_ELLIPSIS; + buffer->cur += 2, result->type = CPP_ELLIPSIS; else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_DOT_STAR; + buffer->cur++, result->type = CPP_DOT_STAR; break; case '+': result->type = CPP_PLUS; if (*buffer->cur == '+') - buffer->cur++, result->type = CPP_PLUS_PLUS; + buffer->cur++, result->type = CPP_PLUS_PLUS; else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_PLUS_EQ; + buffer->cur++, result->type = CPP_PLUS_EQ; break; case '-': result->type = CPP_MINUS; if (*buffer->cur == '>') - { - buffer->cur++; - result->type = CPP_DEREF; - if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_DEREF_STAR; - } + { + buffer->cur++; + result->type = CPP_DEREF; + if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_DEREF_STAR; + } else if (*buffer->cur == '-') - buffer->cur++, result->type = CPP_MINUS_MINUS; + buffer->cur++, result->type = CPP_MINUS_MINUS; else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_MINUS_EQ; + buffer->cur++, result->type = CPP_MINUS_EQ; break; case '&': result->type = CPP_AND; if (*buffer->cur == '&') - buffer->cur++, result->type = CPP_AND_AND; + buffer->cur++, result->type = CPP_AND_AND; else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_AND_EQ; + buffer->cur++, result->type = CPP_AND_EQ; break; case '|': result->type = CPP_OR; if (*buffer->cur == '|') - buffer->cur++, result->type = CPP_OR_OR; + buffer->cur++, result->type = CPP_OR_OR; else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_OR_EQ; + buffer->cur++, result->type = CPP_OR_EQ; break; case ':': result->type = CPP_COLON; if (*buffer->cur == ':' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_SCOPE; + buffer->cur++, result->type = CPP_SCOPE; else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs)) - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_CLOSE_SQUARE; - } + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_SQUARE; + } break; case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break; @@ -1556,17 +1570,17 @@ _cpp_lex_direct (cpp_reader *pfile) case '$': case '\\': { - const uchar *base = --buffer->cur; - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - - if (forms_identifier_p (pfile, true, &nst)) - { - result->type = CPP_NAME; - result->val.node = lex_identifier (pfile, base, true, &nst); - warn_about_normalization (pfile, result, &nst); - break; - } - buffer->cur++; + const uchar *base = --buffer->cur; + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + + if (forms_identifier_p (pfile, true, &nst)) + { + result->type = CPP_NAME; + result->val.node = lex_identifier (pfile, base, true, &nst); + warn_about_normalization (pfile, result, &nst); + break; + } + buffer->cur++; } default: @@ -1586,9 +1600,9 @@ cpp_token_len (const cpp_token *token) switch (TOKEN_SPELL (token)) { - default: len = 4; break; - case SPELL_LITERAL: len = token->val.str.len; break; - case SPELL_IDENT: len = NODE_LEN (token->val.node) * 10; break; + default: len = 4; break; + case SPELL_LITERAL: len = token->val.str.len; break; + case SPELL_IDENT: len = NODE_LEN (token->val.node) * 10; break; } return len; @@ -1618,7 +1632,7 @@ utf8_to_ucn (unsigned char *buffer, const unsigned char *name) /* Ill-formed UTF-8. */ if ((*name & ~0x3F) != 0x80) - abort (); + abort (); } *buffer++ = '\\'; @@ -1637,50 +1651,50 @@ utf8_to_ucn (unsigned char *buffer, const unsigned char *name) FIXME: Would be nice if we didn't need the PFILE argument. */ unsigned char * cpp_spell_token (cpp_reader *pfile, const cpp_token *token, - unsigned char *buffer, bool forstring) + unsigned char *buffer, bool forstring) { switch (TOKEN_SPELL (token)) { case SPELL_OPERATOR: { - const unsigned char *spelling; - unsigned char c; - - if (token->flags & DIGRAPH) - spelling - = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; - else if (token->flags & NAMED_OP) - goto spell_ident; - else - spelling = TOKEN_NAME (token); - - while ((c = *spelling++) != '\0') - *buffer++ = c; + const unsigned char *spelling; + unsigned char c; + + if (token->flags & DIGRAPH) + spelling + = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + while ((c = *spelling++) != '\0') + *buffer++ = c; } break; spell_ident: case SPELL_IDENT: if (forstring) - { - memcpy (buffer, NODE_NAME (token->val.node), - NODE_LEN (token->val.node)); - buffer += NODE_LEN (token->val.node); - } + { + memcpy (buffer, NODE_NAME (token->val.node), + NODE_LEN (token->val.node)); + buffer += NODE_LEN (token->val.node); + } else - { - size_t i; - const unsigned char * name = NODE_NAME (token->val.node); - - for (i = 0; i < NODE_LEN (token->val.node); i++) - if (name[i] & ~0x7F) - { - i += utf8_to_ucn (buffer, name + i) - 1; - buffer += 10; - } - else - *buffer++ = NODE_NAME (token->val.node)[i]; - } + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node); + + for (i = 0; i < NODE_LEN (token->val.node); i++) + if (name[i] & ~0x7F) + { + i += utf8_to_ucn (buffer, name + i) - 1; + buffer += 10; + } + else + *buffer++ = NODE_NAME (token->val.node)[i]; + } break; case SPELL_LITERAL: @@ -1690,7 +1704,7 @@ cpp_spell_token (cpp_reader *pfile, const cpp_token *token, case SPELL_NONE: cpp_error (pfile, CPP_DL_ICE, - "unspellable token %s", TOKEN_NAME (token)); + "unspellable token %s", TOKEN_NAME (token)); break; } @@ -1729,39 +1743,39 @@ cpp_output_token (const cpp_token *token, FILE *fp) { case SPELL_OPERATOR: { - const unsigned char *spelling; - int c; - - if (token->flags & DIGRAPH) - spelling - = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; - else if (token->flags & NAMED_OP) - goto spell_ident; - else - spelling = TOKEN_NAME (token); - - c = *spelling; - do - putc (c, fp); - while ((c = *++spelling) != '\0'); + const unsigned char *spelling; + int c; + + if (token->flags & DIGRAPH) + spelling + = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + c = *spelling; + do + putc (c, fp); + while ((c = *++spelling) != '\0'); } break; spell_ident: case SPELL_IDENT: { - size_t i; - const unsigned char * name = NODE_NAME (token->val.node); - - for (i = 0; i < NODE_LEN (token->val.node); i++) - if (name[i] & ~0x7F) - { - unsigned char buffer[10]; - i += utf8_to_ucn (buffer, name + i) - 1; - fwrite (buffer, 1, 10, fp); - } - else - fputc (NODE_NAME (token->val.node)[i], fp); + size_t i; + const unsigned char * name = NODE_NAME (token->val.node); + + for (i = 0; i < NODE_LEN (token->val.node); i++) + if (name[i] & ~0x7F) + { + unsigned char buffer[10]; + i += utf8_to_ucn (buffer, name + i) - 1; + fwrite (buffer, 1, 10, fp); + } + else + fputc (NODE_NAME (token->val.node)[i], fp); } break; @@ -1782,17 +1796,17 @@ _cpp_equiv_tokens (const cpp_token *a, const cpp_token *b) if (a->type == b->type && a->flags == b->flags) switch (TOKEN_SPELL (a)) { - default: /* Keep compiler happy. */ + default: /* Keep compiler happy. */ case SPELL_OPERATOR: - return 1; + return 1; case SPELL_NONE: - return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no); + return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no); case SPELL_IDENT: - return a->val.node == b->val.node; + return a->val.node == b->val.node; case SPELL_LITERAL: - return (a->val.str.len == b->val.str.len - && !memcmp (a->val.str.text, b->val.str.text, - a->val.str.len)); + return (a->val.str.len == b->val.str.len + && !memcmp (a->val.str.text, b->val.str.text, + a->val.str.len)); } return 0; @@ -1804,7 +1818,7 @@ _cpp_equiv_tokens (const cpp_token *a, const cpp_token *b) needed, e.g. "." and ".2". */ int cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1, - const cpp_token *token2) + const cpp_token *token2) { enum cpp_ttype a = token1->type, b = token2->type; cppchar_t c; @@ -1826,31 +1840,31 @@ cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1, switch (a) { - case CPP_GREATER: return c == '>'; - case CPP_LESS: return c == '<' || c == '%' || c == ':'; - case CPP_PLUS: return c == '+'; - case CPP_MINUS: return c == '-' || c == '>'; - case CPP_DIV: return c == '/' || c == '*'; /* Comments. */ - case CPP_MOD: return c == ':' || c == '>'; - case CPP_AND: return c == '&'; - case CPP_OR: return c == '|'; - case CPP_COLON: return c == ':' || c == '>'; - case CPP_DEREF: return c == '*'; - case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER; - case CPP_HASH: return c == '#' || c == '%'; /* Digraph form. */ - case CPP_NAME: return ((b == CPP_NUMBER - && name_p (pfile, &token2->val.str)) - || b == CPP_NAME - || b == CPP_CHAR || b == CPP_STRING); /* L */ - case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME - || c == '.' || c == '+' || c == '-'); - /* UCNs */ - case CPP_OTHER: return ((token1->val.str.text[0] == '\\' - && b == CPP_NAME) - || (CPP_OPTION (pfile, objc) - && token1->val.str.text[0] == '@' - && (b == CPP_NAME || b == CPP_STRING))); - default: break; + case CPP_GREATER: return c == '>'; + case CPP_LESS: return c == '<' || c == '%' || c == ':'; + case CPP_PLUS: return c == '+'; + case CPP_MINUS: return c == '-' || c == '>'; + case CPP_DIV: return c == '/' || c == '*'; /* Comments. */ + case CPP_MOD: return c == ':' || c == '>'; + case CPP_AND: return c == '&'; + case CPP_OR: return c == '|'; + case CPP_COLON: return c == ':' || c == '>'; + case CPP_DEREF: return c == '*'; + case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER; + case CPP_HASH: return c == '#' || c == '%'; /* Digraph form. */ + case CPP_NAME: return ((b == CPP_NUMBER + && name_p (pfile, &token2->val.str)) + || b == CPP_NAME + || b == CPP_CHAR || b == CPP_STRING); /* L */ + case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME + || c == '.' || c == '+' || c == '-'); + /* UCNs */ + case CPP_OTHER: return ((token1->val.str.text[0] == '\\' + && b == CPP_NAME) + || (CPP_OPTION (pfile, objc) + && token1->val.str.text[0] == '@' + && (b == CPP_NAME || b == CPP_STRING))); + default: break; } return 0; @@ -1870,7 +1884,7 @@ cpp_output_line (cpp_reader *pfile, FILE *fp) cpp_output_token (token, fp); token = cpp_get_token (pfile); if (token->flags & PREV_WHITE) - putc (' ', fp); + putc (' ', fp); } putc ('\n', fp); @@ -1885,7 +1899,7 @@ cpp_output_line (cpp_reader *pfile, FILE *fp) #define MIN_BUFF_SIZE 8000 #define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2) #define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \ - (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2) + (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2) #if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0) #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE! @@ -1935,13 +1949,13 @@ _cpp_get_buff (cpp_reader *pfile, size_t min_size) size_t size; if (*p == NULL) - return new_buff (min_size); + return new_buff (min_size); result = *p; size = result->limit - result->base; /* Return a buffer that's big enough, but don't waste one that's way too big. */ if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size)) - break; + break; } *p = result->next; @@ -2055,11 +2069,11 @@ cpp_token_val_index (cpp_token *tok) return CPP_TOKEN_FLD_STR; case SPELL_NONE: if (tok->type == CPP_MACRO_ARG) - return CPP_TOKEN_FLD_ARG_NO; + return CPP_TOKEN_FLD_ARG_NO; else if (tok->type == CPP_PADDING) - return CPP_TOKEN_FLD_SOURCE; + return CPP_TOKEN_FLD_SOURCE; else if (tok->type == CPP_PRAGMA) - return CPP_TOKEN_FLD_PRAGMA; + return CPP_TOKEN_FLD_PRAGMA; /* else fall through */ default: return CPP_TOKEN_FLD_NONE; diff --git a/support/cpp2/libcpp/line-map.c b/support/cpp/libcpp/line-map.c similarity index 72% rename from support/cpp2/libcpp/line-map.c rename to support/cpp/libcpp/line-map.c index c95eacde..f24cca68 100644 --- a/support/cpp2/libcpp/line-map.c +++ b/support/cpp/libcpp/line-map.c @@ -1,5 +1,5 @@ /* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003, 2004 + Copyright (C) 2001, 2003, 2004, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -54,9 +54,9 @@ linemap_check_files_exited (struct line_maps *set) for (map = &set->maps[set->used - 1]; ! MAIN_FILE_P (map); map = INCLUDED_FROM (set, map)) fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", - map->to_file); + map->to_file); } - + /* Free a line map set. */ void @@ -86,7 +86,7 @@ linemap_free (struct line_maps *set) const struct line_map * linemap_add (struct line_maps *set, enum lc_reason reason, - unsigned int sysp, const char *to_file, unsigned int to_line) + unsigned int sysp, const char *to_file, unsigned int to_line) { struct line_map *map; source_location start_location = set->highest_location + 1; @@ -96,8 +96,15 @@ linemap_add (struct line_maps *set, enum lc_reason reason, if (set->used == set->allocated) { + line_map_realloc reallocator + = set->reallocator ? set->reallocator : xrealloc; set->allocated = 2 * set->allocated + 256; - set->maps = XRESIZEVEC (struct line_map, set->maps, set->allocated); + set->maps + = (struct line_map *) (*reallocator) (set->maps, + set->allocated + * sizeof (struct line_map)); + memset (&set->maps[set->used], 0, ((set->allocated - set->used) + * sizeof (struct line_map))); } map = &set->maps[set->used]; @@ -115,35 +122,35 @@ linemap_add (struct line_maps *set, enum lc_reason reason, bool error; if (MAIN_FILE_P (map - 1)) - { - if (to_file == NULL) - { - set->depth--; - return NULL; - } - error = true; + { + if (to_file == NULL) + { + set->depth--; + return NULL; + } + error = true; reason = LC_RENAME; from = map - 1; - } + } else - { - from = INCLUDED_FROM (set, map - 1); - error = to_file && strcmp (from->to_file, to_file); - } + { + from = INCLUDED_FROM (set, map - 1); + error = to_file && strcmp (from->to_file, to_file); + } /* Depending upon whether we are handling preprocessed input or - not, this can be a user error or an ICE. */ + not, this can be a user error or an ICE. */ if (error) - fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", - to_file); + fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", + to_file); /* A TO_FILE of NULL is special - we use the natural values. */ if (error || to_file == NULL) - { - to_file = from->to_file; - to_line = SOURCE_LINE (from, from[1].start_location); - sysp = from->sysp; - } + { + to_file = from->to_file; + to_line = SOURCE_LINE (from, from[1].start_location); + sysp = from->sysp; + } } map->reason = reason; @@ -162,7 +169,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason, map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2); set->depth++; if (set->trace_includes) - trace_include (set, map); + trace_include (set, map); } else if (reason == LC_RENAME) map->included_from = map[-1].included_from; @@ -177,7 +184,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason, source_location linemap_line_start (struct line_maps *set, unsigned int to_line, - unsigned int max_column_hint) + unsigned int max_column_hint) { struct line_map *map = &set->maps[set->used - 1]; source_location highest = set->highest_location; @@ -198,28 +205,28 @@ linemap_line_start (struct line_maps *set, unsigned int to_line, { int column_bits; if (max_column_hint > 100000 || highest > 0xC0000000) - { - /* If the column number is ridiculous or we've allocated a huge - number of source_locations, give up on column numbers. */ - max_column_hint = 0; - if (highest >0xF0000000) - return 0; - column_bits = 0; - } + { + /* If the column number is ridiculous or we've allocated a huge + number of source_locations, give up on column numbers. */ + max_column_hint = 0; + if (highest >0xF0000000) + return 0; + column_bits = 0; + } else - { - column_bits = 7; - while (max_column_hint >= (1U << column_bits)) - column_bits++; - max_column_hint = 1U << column_bits; - } + { + column_bits = 7; + while (max_column_hint >= (1U << column_bits)) + column_bits++; + max_column_hint = 1U << column_bits; + } /* Allocate the new line_map. However, if the current map only has a - single line we can sometimes just increase its column_bits instead. */ + single line we can sometimes just increase its column_bits instead. */ if (line_delta < 0 - || last_line != map->to_line - || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) - map = (struct line_map*) linemap_add (set, LC_RENAME, map->sysp, - map->to_file, to_line); + || last_line != map->to_line + || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) + map = (struct line_map*) linemap_add (set, LC_RENAME, map->sysp, + map->to_file, to_line); map->column_bits = column_bits; r = map->start_location + ((to_line - map->to_line) << column_bits); } @@ -240,15 +247,15 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column) if (to_column >= set->max_column_hint) { if (r >= 0xC000000 || to_column > 100000) - { - /* Running low on source_locations - disable column numbers. */ - return r; - } + { + /* Running low on source_locations - disable column numbers. */ + return r; + } else - { - struct line_map *map = &set->maps[set->used - 1]; - r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); - } + { + struct line_map *map = &set->maps[set->used - 1]; + r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); + } } r = r + to_column; if (r >= set->highest_location) @@ -269,13 +276,13 @@ linemap_lookup (struct line_maps *set, source_location line) mn = set->cache; mx = set->used; - + cached = &set->maps[mn]; /* We should get a segfault if no line_maps have been added yet. */ if (line >= cached->start_location) { if (mn + 1 == mx || line < cached[1].start_location) - return cached; + return cached; } else { @@ -287,9 +294,9 @@ linemap_lookup (struct line_maps *set, source_location line) { md = (mn + mx) / 2; if (set->maps[md].start_location > line) - mx = md; + mx = md; else - mn = md; + mn = md; } set->cache = mn; @@ -302,7 +309,7 @@ linemap_lookup (struct line_maps *set, source_location line) void linemap_print_containing_files (struct line_maps *set, - const struct line_map *map) + const struct line_map *map) { if (MAIN_FILE_P (map) || set->last_listed == map->included_from) return; @@ -311,25 +318,25 @@ linemap_print_containing_files (struct line_maps *set, map = INCLUDED_FROM (set, map); fprintf (stderr, _("In file included from %s:%u"), - map->to_file, LAST_SOURCE_LINE (map)); + map->to_file, LAST_SOURCE_LINE (map)); while (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (set, map); /* Translators note: this message is used in conjunction - with "In file included from %s:%ld" and some other - tricks. We want something like this: + with "In file included from %s:%ld" and some other + tricks. We want something like this: - | In file included from sys/select.h:123, - | from sys/types.h:234, - | from userfile.c:31: - | bits/select.h:45: + | In file included from sys/select.h:123, + | from sys/types.h:234, + | from userfile.c:31: + | bits/select.h:45: - with all the "from"s lined up. - The trailing comma is at the beginning of this message, - and the trailing colon is not translated. */ + with all the "from"s lined up. + The trailing comma is at the beginning of this message, + and the trailing colon is not translated. */ fprintf (stderr, _(",\n from %s:%u"), - map->to_file, LAST_SOURCE_LINE (map)); + map->to_file, LAST_SOURCE_LINE (map)); } fputs (":\n", stderr); diff --git a/support/cpp2/libcpp/macro.c b/support/cpp/libcpp/macro.c similarity index 51% rename from support/cpp2/libcpp/macro.c rename to support/cpp/libcpp/macro.c index c33b7fce..764d5e3a 100644 --- a/support/cpp2/libcpp/macro.c +++ b/support/cpp/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, 2007, 2008 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 @@ -31,20 +32,22 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. typedef struct macro_arg macro_arg; struct macro_arg { - const cpp_token **first; /* First token in unexpanded argument. */ - const cpp_token **expanded; /* Macro-expanded argument. */ - const cpp_token *stringified; /* Stringified argument. */ - unsigned int count; /* # of tokens in argument. */ - unsigned int expanded_count; /* # of tokens in expanded argument. */ + const cpp_token **first; /* First token in unexpanded argument. */ + const cpp_token **expanded; /* Macro-expanded argument. */ + const cpp_token *stringified; /* Stringified argument. */ + unsigned int count; /* # of tokens in argument. */ + unsigned int expanded_count; /* # of tokens in expanded argument. */ }; /* Macro expansion. */ -static int enter_macro_context (cpp_reader *, cpp_hashnode *); +static int enter_macro_context (cpp_reader *, cpp_hashnode *, + const cpp_token *); static int builtin_macro (cpp_reader *, cpp_hashnode *); static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, - const cpp_token **, unsigned int); -static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *); + const cpp_token **, unsigned int); +static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *, + _cpp_buff **); static cpp_context *next_context (cpp_reader *); static const cpp_token *padding_token (cpp_reader *, const cpp_token *); static void expand_arg (cpp_reader *, macro_arg *); @@ -53,8 +56,9 @@ static const cpp_token *stringify_arg (cpp_reader *, macro_arg *); static void paste_all_tokens (cpp_reader *, const cpp_token *); static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *); static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *, - macro_arg *); -static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *); + macro_arg *); +static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *, + _cpp_buff **); static bool create_iso_definition (cpp_reader *, cpp_macro *); /* #define directive parsing and handling. */ @@ -62,25 +66,25 @@ static bool create_iso_definition (cpp_reader *, cpp_macro *); static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *); static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *); static bool warn_of_redefinition (cpp_reader *, const cpp_hashnode *, - const cpp_macro *); + const cpp_macro *); static bool parse_params (cpp_reader *, cpp_macro *); static void check_trad_stringification (cpp_reader *, const cpp_macro *, - const cpp_string *); + const cpp_string *); /* Emits a warning if NODE is a macro defined in the main file that has not been used. */ int _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, - void *v ATTRIBUTE_UNUSED) + void *v ATTRIBUTE_UNUSED) { if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) { cpp_macro *macro = node->value.macro; if (!macro->used - && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line))) - cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0, - "macro \"%s\" is not used", NODE_NAME (node)); + && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line))) + cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0, + "macro \"%s\" is not used", NODE_NAME (node)); } return 1; @@ -120,147 +124,154 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) { default: cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", - NODE_NAME (node)); + NODE_NAME (node)); break; case BT_TIMESTAMP: { - cpp_buffer *pbuffer = cpp_get_buffer (pfile); - if (pbuffer->timestamp == NULL) - { - /* Initialize timestamp value of the assotiated file. */ + cpp_buffer *pbuffer = cpp_get_buffer (pfile); + if (pbuffer->timestamp == NULL) + { + /* Initialize timestamp value of the assotiated file. */ struct _cpp_file *file = cpp_get_file (pbuffer); - if (file) - { - /* Generate __TIMESTAMP__ string, that represents - the date and time of the last modification - of the current source file. The string constant - looks like "Sun Sep 16 01:03:52 1973". */ - struct tm *tb = NULL; - struct stat *st = _cpp_get_file_stat (file); - if (st) - tb = localtime (&st->st_mtime); - if (tb) - { - char *str = asctime (tb); - size_t len = strlen (str); - unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); - buf[0] = '"'; - strcpy ((char *) buf + 1, str); - buf[len] = '"'; - pbuffer->timestamp = buf; - } - else - { - cpp_errno (pfile, CPP_DL_WARNING, - "could not determine file timestamp"); - pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\""; - } - } - } - result = pbuffer->timestamp; + if (file) + { + /* Generate __TIMESTAMP__ string, that represents + the date and time of the last modification + of the current source file. The string constant + looks like "Sun Sep 16 01:03:52 1973". */ + struct tm *tb = NULL; + struct stat *st = _cpp_get_file_stat (file); + if (st) + tb = localtime (&st->st_mtime); + if (tb) + { + char *str = asctime (tb); + size_t len = strlen (str); + unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '"'; + strcpy ((char *) buf + 1, str); + buf[len] = '"'; + pbuffer->timestamp = buf; + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine file timestamp"); + pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\""; + } + } + } + result = pbuffer->timestamp; } break; case BT_FILE: case BT_BASE_FILE: { - unsigned int len; - const char *name; - uchar *buf; - map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line); - - if (node->value.builtin == BT_BASE_FILE) - while (! MAIN_FILE_P (map)) - map = INCLUDED_FROM (pfile->line_table, map); - - name = map->to_file; - len = strlen (name); - buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); - result = buf; - *buf = '"'; - buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); - *buf++ = '"'; - *buf = '\0'; + unsigned int len; + const char *name; + uchar *buf; + map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line); + + if (node->value.builtin == BT_BASE_FILE) + while (! MAIN_FILE_P (map)) + map = INCLUDED_FROM (pfile->line_table, map); + + name = map->to_file; + len = strlen (name); + buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); + result = buf; + *buf = '"'; + buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); + *buf++ = '"'; + *buf = '\0'; } break; case BT_INCLUDE_LEVEL: /* The line map depth counts the primary source as level 1, but - historically __INCLUDE_DEPTH__ has called the primary source - level 0. */ + historically __INCLUDE_DEPTH__ has called the primary source + level 0. */ number = pfile->line_table->depth - 1; break; case BT_SPECLINE: map = &pfile->line_table->maps[pfile->line_table->used-1]; /* If __LINE__ is embedded in a macro, it must expand to the - line of the macro's invocation, not its definition. - Otherwise things like assert() will not work properly. */ + line of the macro's invocation, not its definition. + Otherwise things like assert() will not work properly. */ if (CPP_OPTION (pfile, traditional)) - number = pfile->line_table->highest_line; + number = pfile->line_table->highest_line; else - number = pfile->cur_token[-1].src_loc; + number = pfile->cur_token[-1].src_loc; number = SOURCE_LINE (map, number); break; /* __STDC__ has the value 1 under normal circumstances. - However, if (a) we are in a system header, (b) the option - stdc_0_in_system_headers is true (set by target config), and - (c) we are not in strictly conforming mode, then it has the - value 0. (b) and (c) are already checked in cpp_init_builtins. */ + However, if (a) we are in a system header, (b) the option + stdc_0_in_system_headers is true (set by target config), and + (c) we are not in strictly conforming mode, then it has the + value 0. (b) and (c) are already checked in cpp_init_builtins. */ case BT_STDC: if (cpp_in_system_header (pfile)) - number = 0; + number = 0; else - number = 1; + number = 1; break; case BT_DATE: case BT_TIME: if (pfile->date == NULL) - { - /* Allocate __DATE__ and __TIME__ strings from permanent - storage. We only do this once, and don't generate them - at init time, because time() and localtime() are very - slow on some systems. */ - time_t tt; - struct tm *tb = NULL; - - /* (time_t) -1 is a legitimate value for "number of seconds - since the Epoch", so we have to do a little dance to - distinguish that from a genuine error. */ - errno = 0; - tt = time(NULL); - if (tt != (time_t)-1 || errno == 0) - tb = localtime (&tt); - - if (tb) - { - pfile->date = _cpp_unaligned_alloc (pfile, - sizeof ("\"Oct 11 1347\"")); - sprintf ((char *) pfile->date, "\"%s %2d %4d\"", - monthnames[tb->tm_mon], tb->tm_mday, - tb->tm_year + 1900); - - pfile->time = _cpp_unaligned_alloc (pfile, - sizeof ("\"12:34:56\"")); - sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", - tb->tm_hour, tb->tm_min, tb->tm_sec); - } - else - { - cpp_errno (pfile, CPP_DL_WARNING, - "could not determine date and time"); - - pfile->date = U"\"??? ?? ????\""; - pfile->time = U"\"??:??:??\""; - } - } + { + /* Allocate __DATE__ and __TIME__ strings from permanent + storage. We only do this once, and don't generate them + at init time, because time() and localtime() are very + slow on some systems. */ + time_t tt; + struct tm *tb = NULL; + + /* (time_t) -1 is a legitimate value for "number of seconds + since the Epoch", so we have to do a little dance to + distinguish that from a genuine error. */ + errno = 0; + tt = time(NULL); + if (tt != (time_t)-1 || errno == 0) + tb = localtime (&tt); + + if (tb) + { + pfile->date = _cpp_unaligned_alloc (pfile, + sizeof ("\"Oct 11 1347\"")); + sprintf ((char *) pfile->date, "\"%s %2d %4d\"", + monthnames[tb->tm_mon], tb->tm_mday, + tb->tm_year + 1900); + + pfile->time = _cpp_unaligned_alloc (pfile, + sizeof ("\"12:34:56\"")); + sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", + tb->tm_hour, tb->tm_min, tb->tm_sec); + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine date and time"); + + pfile->date = U"\"??? ?? ????\""; + pfile->time = U"\"??:??:??\""; + } + } if (node->value.builtin == BT_DATE) - result = pfile->date; + result = pfile->date; else - result = pfile->time; + result = pfile->time; + 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->counter++; break; } @@ -290,10 +301,9 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) /* Don't interpret _Pragma within directives. The standard is not clear on this, but to me this makes most sense. */ if (pfile->state.in_directive) - return 0; + return 0; - _cpp_do__Pragma (pfile); - return 1; + return _cpp_do__Pragma (pfile); } buf = _cpp_builtin_macro_text (pfile, node); @@ -310,7 +320,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node) _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); if (pfile->buffer->cur != pfile->buffer->rlimit) cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", - NODE_NAME (node)); + NODE_NAME (node)); _cpp_pop_buffer (pfile); return 1; @@ -327,12 +337,12 @@ cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) uchar c = *src++; if (c == '\\' || c == '"') - { - *dest++ = '\\'; - *dest++ = c; - } + { + *dest++ = '\\'; + *dest++ = c; + } else - *dest++ = c; + *dest++ = c; } return dest; @@ -359,61 +369,61 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) const cpp_token *token = arg->first[i]; if (token->type == CPP_PADDING) - { - if (source == NULL) - source = token->val.source; - continue; - } + { + if (source == NULL) + source = token->val.source; + continue; + } escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING - || token->type == CPP_CHAR || token->type == CPP_WCHAR); + || token->type == CPP_CHAR || token->type == CPP_WCHAR); /* Room for each char being written in octal, initial space and - final quote and NUL. */ + final quote and NUL. */ len = cpp_token_len (token); if (escape_it) - len *= 4; + len *= 4; len += 3; if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len) - { - size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); - _cpp_extend_buff (pfile, &pfile->u_buff, len); - dest = BUFF_FRONT (pfile->u_buff) + len_so_far; - } + { + size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); + _cpp_extend_buff (pfile, &pfile->u_buff, len); + dest = BUFF_FRONT (pfile->u_buff) + len_so_far; + } /* Leading white space? */ if (dest - 1 != BUFF_FRONT (pfile->u_buff)) - { - if (source == NULL) - source = token; - if (source->flags & PREV_WHITE) - *dest++ = ' '; - } + { + if (source == NULL) + source = token; + if (source->flags & PREV_WHITE) + *dest++ = ' '; + } source = NULL; if (escape_it) - { - _cpp_buff *buff = _cpp_get_buff (pfile, len); - unsigned char *buf = BUFF_FRONT (buff); - len = cpp_spell_token (pfile, token, buf, true) - buf; - dest = cpp_quote_string (dest, buf, len); - _cpp_release_buff (pfile, buff); - } + { + _cpp_buff *buff = _cpp_get_buff (pfile, len); + unsigned char *buf = BUFF_FRONT (buff); + len = cpp_spell_token (pfile, token, buf, true) - buf; + dest = cpp_quote_string (dest, buf, len); + _cpp_release_buff (pfile, buff); + } else - dest = cpp_spell_token (pfile, token, dest, true); + dest = cpp_spell_token (pfile, token, dest, true); if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') - backslash_count++; + backslash_count++; else - backslash_count = 0; + backslash_count = 0; } /* Ignore the final \ of invalid string literals. */ if (backslash_count & 1) { cpp_error (pfile, CPP_DL_WARNING, - "invalid string literal, ignoring final '\\'"); + "invalid string literal, ignoring final '\\'"); dest--; } @@ -431,21 +441,22 @@ 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); + /* In one obscure case we might see padding here. */ + if (rhs->type != CPP_PADDING) + end = cpp_spell_token (pfile, rhs, end, false); *end = '\n'; cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); @@ -453,21 +464,31 @@ 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, - "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", - buf, cpp_token_as_text (pfile, rhs)); + cpp_error (pfile, CPP_DL_ERROR, + "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", + buf, cpp_token_as_text (pfile, rhs)); return false; } + *plhs = lhs; _cpp_pop_buffer (pfile); return true; } @@ -488,20 +509,22 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) do { /* Take the token directly from the current context. We can do - this, because we are in the replacement list of either an - object-like macro, or a function-like macro with arguments - inserted. In either case, the constraints to #define - guarantee we have at least one more token. */ + this, because we are in the replacement list of either an + object-like macro, or a function-like macro with arguments + inserted. In either case, the constraints to #define + guarantee we have at least one more token. */ if (context->direct_p) - rhs = FIRST (context).token++; + rhs = FIRST (context).token++; else - rhs = *FIRST (context).ptoken++; + rhs = *FIRST (context).ptoken++; if (rhs->type == CPP_PADDING) - abort (); - + { + if (rhs->flags & PASTE_LEFT) + abort (); + } if (!paste_tokens (pfile, &lhs, rhs)) - break; + break; } while (rhs->flags & PASTE_LEFT); @@ -524,29 +547,29 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node if (argc < macro->paramc) { /* As an extension, a rest argument is allowed to not appear in - the invocation at all. - e.g. #define debug(format, args...) something - debug("string"); + the invocation at all. + e.g. #define debug(format, args...) something + debug("string"); - This is exactly the same as if there had been an empty rest - argument - debug("string", ). */ + This is exactly the same as if there had been an empty rest + argument - debug("string", ). */ if (argc + 1 == macro->paramc && macro->variadic) - { - if (CPP_PEDANTIC (pfile) && ! macro->syshdr) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C99 requires rest arguments to be used"); - return true; - } + { + if (CPP_PEDANTIC (pfile) && ! macro->syshdr) + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires rest arguments to be used"); + return true; + } cpp_error (pfile, CPP_DL_ERROR, - "macro \"%s\" requires %u arguments, but only %u given", - NODE_NAME (node), macro->paramc, argc); + "macro \"%s\" requires %u arguments, but only %u given", + NODE_NAME (node), macro->paramc, argc); } else cpp_error (pfile, CPP_DL_ERROR, - "macro \"%s\" passed %u arguments, but takes just %u", - NODE_NAME (node), argc, macro->paramc); + "macro \"%s\" passed %u arguments, but takes just %u", + NODE_NAME (node), argc, macro->paramc); return false; } @@ -555,9 +578,12 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node invocation. Assumes the opening parenthesis has been processed. If there is an error, emits an appropriate diagnostic and returns NULL. Each argument is terminated by a CPP_EOF token, for the - future benefit of expand_arg(). */ + future benefit of expand_arg(). If there are any deferred + #pragma directives among macro arguments, store pointers to the + CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. */ static _cpp_buff * -collect_args (cpp_reader *pfile, const cpp_hashnode *node) +collect_args (cpp_reader *pfile, const cpp_hashnode *node, + _cpp_buff **pragma_buff) { _cpp_buff *buff, *base_buff; cpp_macro *macro; @@ -571,7 +597,7 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node) else argc = 1; buff = _cpp_get_buff (pfile, argc * (50 * sizeof (cpp_token *) - + sizeof (macro_arg))); + + sizeof (macro_arg))); base_buff = buff; args = (macro_arg *) buff->base; memset (args, 0, argc * sizeof (macro_arg)); @@ -590,95 +616,140 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node) arg->first = (const cpp_token **) buff->cur; for (;;) - { - /* Require space for 2 new tokens (including a CPP_EOF). */ - if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit) - { - buff = _cpp_append_extend_buff (pfile, buff, - 1000 * sizeof (cpp_token *)); - arg->first = (const cpp_token **) buff->cur; - } - - token = cpp_get_token (pfile); - - if (token->type == CPP_PADDING) - { - /* Drop leading padding. */ - if (ntokens == 0) - continue; - } - else if (token->type == CPP_OPEN_PAREN) - paren_depth++; - else if (token->type == CPP_CLOSE_PAREN) - { - if (paren_depth-- == 0) - break; - } - else if (token->type == CPP_COMMA) - { - /* A comma does not terminate an argument within - parentheses or as part of a variable argument. */ - if (paren_depth == 0 - && ! (macro->variadic && argc == macro->paramc)) - break; - } - else if (token->type == CPP_EOF - || (token->type == CPP_HASH && token->flags & BOL)) - break; - - arg->first[ntokens++] = token; - } + { + /* Require space for 2 new tokens (including a CPP_EOF). */ + if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit) + { + buff = _cpp_append_extend_buff (pfile, buff, + 1000 * sizeof (cpp_token *)); + arg->first = (const cpp_token **) buff->cur; + } + + token = cpp_get_token (pfile); + + if (token->type == CPP_PADDING) + { + /* Drop leading padding. */ + if (ntokens == 0) + continue; + } + else if (token->type == CPP_OPEN_PAREN) + paren_depth++; + else if (token->type == CPP_CLOSE_PAREN) + { + if (paren_depth-- == 0) + break; + } + else if (token->type == CPP_COMMA) + { + /* A comma does not terminate an argument within + parentheses or as part of a variable argument. */ + if (paren_depth == 0 + && ! (macro->variadic && argc == macro->paramc)) + break; + } + else if (token->type == CPP_EOF + || (token->type == CPP_HASH && token->flags & BOL)) + break; + else if (token->type == CPP_PRAGMA) + { + cpp_token *newtok = _cpp_temp_token (pfile); + + /* CPP_PRAGMA token lives in directive_result, which will + be overwritten on the next directive. */ + *newtok = *token; + token = newtok; + do + { + if (*pragma_buff == NULL + || BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *)) + { + _cpp_buff *next; + if (*pragma_buff == NULL) + *pragma_buff + = _cpp_get_buff (pfile, 32 * sizeof (cpp_token *)); + else + { + next = *pragma_buff; + *pragma_buff + = _cpp_get_buff (pfile, + (BUFF_FRONT (*pragma_buff) + - (*pragma_buff)->base) * 2); + (*pragma_buff)->next = next; + } + } + *(const cpp_token **) BUFF_FRONT (*pragma_buff) = token; + BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *); + if (token->type == CPP_PRAGMA_EOL) + break; + token = cpp_get_token (pfile); + } + while (token->type != CPP_EOF); + + /* In deferred pragmas parsing_args and prevent_expansion + had been changed, reset it. */ + pfile->state.parsing_args = 2; + pfile->state.prevent_expansion = 1; + + if (token->type == CPP_EOF) + break; + else + continue; + } + + arg->first[ntokens++] = token; + } /* Drop trailing padding. */ while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING) - ntokens--; + ntokens--; arg->count = ntokens; arg->first[ntokens] = &pfile->eof; /* Terminate the argument. Excess arguments loop back and - overwrite the final legitimate argument, before failing. */ + overwrite the final legitimate argument, before failing. */ if (argc <= macro->paramc) - { - buff->cur = (unsigned char *) &arg->first[ntokens + 1]; - if (argc != macro->paramc) - arg++; - } + { + buff->cur = (unsigned char *) &arg->first[ntokens + 1]; + if (argc != macro->paramc) + arg++; + } } while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF); if (token->type == CPP_EOF) { /* We still need the CPP_EOF to end directives, and to end - pre-expansion of a macro argument. Step back is not - unconditional, since we don't want to return a CPP_EOF to our - callers at the end of an -include-d file. */ + pre-expansion of a macro argument. Step back is not + unconditional, since we don't want to return a CPP_EOF to our + callers at the end of an -include-d file. */ if (pfile->context->prev || pfile->state.in_directive) - _cpp_backup_tokens (pfile, 1); + _cpp_backup_tokens (pfile, 1); cpp_error (pfile, CPP_DL_ERROR, - "unterminated argument list invoking macro \"%s\"", - NODE_NAME (node)); + "unterminated argument list invoking macro \"%s\"", + NODE_NAME (node)); } else { /* A single empty argument is counted as no argument. */ if (argc == 1 && macro->paramc == 0 && args[0].count == 0) - argc = 0; + argc = 0; if (_cpp_arguments_ok (pfile, macro, node, argc)) - { - /* GCC has special semantics for , ## b where b is a varargs - parameter: we remove the comma if b was omitted entirely. - If b was merely an empty argument, the comma is retained. - If the macro takes just one (varargs) parameter, then we - retain the comma only if we are standards conforming. - - If FIRST is NULL replace_args () swallows the comma. */ - if (macro->variadic && (argc < macro->paramc - || (argc == 1 && args[0].count == 0 - && !CPP_OPTION (pfile, std)))) - args[macro->paramc - 1].first = NULL; - return base_buff; - } + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + return base_buff; + } } /* An error occurred. */ @@ -689,9 +760,11 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node) /* Search for an opening parenthesis to the macro of NODE, in such a way that, if none is found, we don't lose the information in any intervening padding tokens. If we find the parenthesis, collect - the arguments and return the buffer containing them. */ + the arguments and return the buffer containing them. PRAGMA_BUFF + argument is the same as in collect_args. */ static _cpp_buff * -funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) +funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node, + _cpp_buff **pragma_buff) { const cpp_token *token, *padding = NULL; @@ -699,16 +772,16 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) { token = cpp_get_token (pfile); if (token->type != CPP_PADDING) - break; + break; if (padding == NULL - || (!(padding->flags & PREV_WHITE) && token->val.source == NULL)) - padding = token; + || (!(padding->flags & PREV_WHITE) && token->val.source == NULL)) + padding = token; } if (token->type == CPP_OPEN_PAREN) { pfile->state.parsing_args = 2; - return collect_args (pfile, node); + return collect_args (pfile, node, pragma_buff); } /* CPP_EOF can be the end of macro arguments, or the end of the @@ -716,11 +789,11 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) if (token->type != CPP_EOF || token == &pfile->eof) { /* Back up. We may have skipped padding, in which case backing - up more than one token when expanding macros is in general - too difficult. We re-insert it in its own context. */ + up more than one token when expanding macros is in general + too difficult. We re-insert it in its own context. */ _cpp_backup_tokens (pfile, 1); if (padding) - _cpp_push_token_context (pfile, NULL, padding, 1); + _cpp_push_token_context (pfile, NULL, padding, 1); } return NULL; @@ -729,9 +802,13 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) /* Push the context of a macro with hash entry NODE onto the context stack. If we can successfully expand the macro, we push a context containing its yet-to-be-rescanned replacement list and return one. - Otherwise, we don't push a context and return zero. */ + If there were additionally any unexpanded deferred #pragma directives + among macro arguments, push another context containing the + pragma tokens before the yet-to-be-rescanned replacement list + and return two. Otherwise, we don't push a context and return zero. */ static int -enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) +enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, + const cpp_token *result) { /* The presence of a macro invalidates a file's controlling macro. */ pfile->mi_valid = false; @@ -742,33 +819,37 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) if (! (node->flags & NODE_BUILTIN)) { cpp_macro *macro = node->value.macro; + _cpp_buff *pragma_buff = NULL; if (macro->fun_like) - { - _cpp_buff *buff; - - pfile->state.prevent_expansion++; - pfile->keep_tokens++; - pfile->state.parsing_args = 1; - buff = funlike_invocation_p (pfile, node); - pfile->state.parsing_args = 0; - pfile->keep_tokens--; - pfile->state.prevent_expansion--; - - if (buff == NULL) - { - if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) - cpp_error (pfile, CPP_DL_WARNING, + { + _cpp_buff *buff; + + pfile->state.prevent_expansion++; + pfile->keep_tokens++; + pfile->state.parsing_args = 1; + buff = funlike_invocation_p (pfile, node, &pragma_buff); + pfile->state.parsing_args = 0; + pfile->keep_tokens--; + pfile->state.prevent_expansion--; + + if (buff == NULL) + { + if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) + cpp_error (pfile, CPP_DL_WARNING, "function-like macro \"%s\" must be used with arguments in traditional C", - NODE_NAME (node)); + NODE_NAME (node)); + + if (pragma_buff) + _cpp_release_buff (pfile, pragma_buff); - return 0; - } + return 0; + } - if (macro->paramc > 0) - replace_args (pfile, node, macro, (macro_arg *) buff->base); - _cpp_release_buff (pfile, buff); - } + if (macro->paramc > 0) + replace_args (pfile, node, macro, (macro_arg *) buff->base); + _cpp_release_buff (pfile, buff); + } /* Disable the macro within its expansion. */ node->flags |= NODE_DISABLED; @@ -776,7 +857,26 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) macro->used = 1; if (macro->paramc == 0) - _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count); + _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count); + + if (pragma_buff) + { + if (!pfile->state.in_directive) + _cpp_push_token_context (pfile, NULL, + padding_token (pfile, result), 1); + do + { + _cpp_buff *tail = pragma_buff->next; + pragma_buff->next = NULL; + push_ptoken_context (pfile, NULL, pragma_buff, + (const cpp_token **) pragma_buff->base, + ((const cpp_token **) BUFF_FRONT (pragma_buff) + - (const cpp_token **) pragma_buff->base)); + pragma_buff = tail; + } + while (pragma_buff != NULL); + return 2; + } return 1; } @@ -808,27 +908,27 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg for (src = macro->exp.tokens; src < limit; src++) if (src->type == CPP_MACRO_ARG) { - /* Leading and trailing padding tokens. */ - total += 2; - - /* We have an argument. If it is not being stringified or - pasted it is macro-replaced before insertion. */ - arg = &args[src->val.arg_no - 1]; - - if (src->flags & STRINGIFY_ARG) - { - if (!arg->stringified) - arg->stringified = stringify_arg (pfile, arg); - } - else if ((src->flags & PASTE_LEFT) - || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT))) - total += arg->count - 1; - else - { - if (!arg->expanded) - expand_arg (pfile, arg); - total += arg->expanded_count - 1; - } + /* Leading and trailing padding tokens. */ + total += 2; + + /* We have an argument. If it is not being stringified or + pasted it is macro-replaced before insertion. */ + arg = &args[src->val.arg_no - 1]; + + if (src->flags & STRINGIFY_ARG) + { + if (!arg->stringified) + arg->stringified = stringify_arg (pfile, arg); + } + else if ((src->flags & PASTE_LEFT) + || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT))) + total += arg->count - 1; + else + { + if (!arg->expanded) + expand_arg (pfile, arg); + total += arg->expanded_count - 1; + } } /* Now allocate space for the expansion, copy the tokens and replace @@ -843,73 +943,73 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg const cpp_token **from, **paste_flag; if (src->type != CPP_MACRO_ARG) - { - *dest++ = src; - continue; - } + { + *dest++ = src; + continue; + } paste_flag = 0; arg = &args[src->val.arg_no - 1]; if (src->flags & STRINGIFY_ARG) - count = 1, from = &arg->stringified; + count = 1, from = &arg->stringified; else if (src->flags & PASTE_LEFT) - count = arg->count, from = arg->first; + count = arg->count, from = arg->first; else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)) - { - count = arg->count, from = arg->first; - if (dest != first) - { - if (dest[-1]->type == CPP_COMMA - && macro->variadic - && src->val.arg_no == macro->paramc) - { - /* Swallow a pasted comma if from == NULL, otherwise - drop the paste flag. */ - if (from == NULL) - dest--; - else - paste_flag = dest - 1; - } - /* Remove the paste flag if the RHS is a placemarker. */ - else if (count == 0) - paste_flag = dest - 1; - } - } + { + count = arg->count, from = arg->first; + if (dest != first) + { + if (dest[-1]->type == CPP_COMMA + && macro->variadic + && src->val.arg_no == macro->paramc) + { + /* Swallow a pasted comma if from == NULL, otherwise + drop the paste flag. */ + if (from == NULL) + dest--; + else + paste_flag = dest - 1; + } + /* Remove the paste flag if the RHS is a placemarker. */ + else if (count == 0) + paste_flag = dest - 1; + } + } else - count = arg->expanded_count, from = arg->expanded; + count = arg->expanded_count, from = arg->expanded; /* Padding on the left of an argument (unless RHS of ##). */ if ((!pfile->state.in_directive || pfile->state.directive_wants_padding) - && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) - *dest++ = padding_token (pfile, src); + && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) + *dest++ = padding_token (pfile, src); if (count) - { - memcpy (dest, from, count * sizeof (cpp_token *)); - dest += count; + { + memcpy (dest, from, count * sizeof (cpp_token *)); + dest += count; - /* With a non-empty argument on the LHS of ##, the last - token should be flagged PASTE_LEFT. */ - if (src->flags & PASTE_LEFT) - paste_flag = dest - 1; - } + /* With a non-empty argument on the LHS of ##, the last + token should be flagged PASTE_LEFT. */ + if (src->flags & PASTE_LEFT) + paste_flag = dest - 1; + } /* Avoid paste on RHS (even case count == 0). */ if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT)) - *dest++ = &pfile->avoid_paste; + *dest++ = &pfile->avoid_paste; /* Add a new paste flag, or remove an unwanted one. */ if (paste_flag) - { - cpp_token *token = _cpp_temp_token (pfile); - token->type = (*paste_flag)->type; - token->val = (*paste_flag)->val; - if (src->flags & PASTE_LEFT) - token->flags = (*paste_flag)->flags | PASTE_LEFT; - else - token->flags = (*paste_flag)->flags & ~PASTE_LEFT; - *paste_flag = token; - } + { + cpp_token *token = _cpp_temp_token (pfile); + token->type = (*paste_flag)->type; + token->val = (*paste_flag)->val; + if (src->flags & PASTE_LEFT) + token->flags = (*paste_flag)->flags | PASTE_LEFT; + else + token->flags = (*paste_flag)->flags & ~PASTE_LEFT; + *paste_flag = token; + } } /* Free the expanded arguments. */ @@ -957,7 +1057,7 @@ next_context (cpp_reader *pfile) /* Push a list of pointers to tokens. */ static void push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, - const cpp_token **first, unsigned int count) + const cpp_token **first, unsigned int count) { cpp_context *context = next_context (pfile); @@ -971,7 +1071,7 @@ push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, /* Push a list of tokens. */ void _cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, - const cpp_token *first, unsigned int count) + const cpp_token *first, unsigned int count) { cpp_context *context = next_context (pfile); @@ -985,7 +1085,7 @@ _cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, /* Push a traditional macro's replacement text. */ void _cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro, - const uchar *start, size_t len) + const uchar *start, size_t len) { cpp_context *context = next_context (pfile); @@ -1026,16 +1126,16 @@ expand_arg (cpp_reader *pfile, macro_arg *arg) const cpp_token *token; if (arg->expanded_count + 1 >= capacity) - { - capacity *= 2; - arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, + { + capacity *= 2; + arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, capacity); - } + } token = cpp_get_token (pfile); if (token->type == CPP_EOF) - break; + break; arg->expanded[arg->expanded_count++] = token; } @@ -1077,6 +1177,8 @@ const cpp_token * cpp_get_token (cpp_reader *pfile) { const cpp_token *result; + bool can_set = pfile->set_invocation_location; + pfile->set_invocation_location = false; for (;;) { @@ -1085,61 +1187,68 @@ cpp_get_token (cpp_reader *pfile) /* Context->prev == 0 <=> base context. */ if (!context->prev) - result = _cpp_lex_token (pfile); + result = _cpp_lex_token (pfile); else if (FIRST (context).token != LAST (context).token) - { - if (context->direct_p) - result = FIRST (context).token++; - else - result = *FIRST (context).ptoken++; - - if (result->flags & PASTE_LEFT) - { - paste_all_tokens (pfile, result); - if (pfile->state.in_directive) - continue; - return padding_token (pfile, result); - } - } + { + if (context->direct_p) + result = FIRST (context).token++; + else + result = *FIRST (context).ptoken++; + + if (result->flags & PASTE_LEFT) + { + paste_all_tokens (pfile, result); + if (pfile->state.in_directive) + continue; + return padding_token (pfile, result); + } + } else - { - _cpp_pop_context (pfile); - if (pfile->state.in_directive) - continue; - return &pfile->avoid_paste; - } + { + _cpp_pop_context (pfile); + if (pfile->state.in_directive) + continue; + return &pfile->avoid_paste; + } if (pfile->state.in_directive && result->type == CPP_COMMENT) - continue; + continue; if (result->type != CPP_NAME) - break; + break; node = result->val.node; if (node->type != NT_MACRO || (result->flags & NO_EXPAND)) - break; + break; if (!(node->flags & NODE_DISABLED)) - { - if (!pfile->state.prevent_expansion - && enter_macro_context (pfile, node)) - { - if (pfile->state.in_directive) - continue; - return padding_token (pfile, result); - } - } + { + int ret; + /* If not in a macro context, and we're going to start an + expansion, record the location. */ + if (can_set && !context->macro) + pfile->invocation_location = result->src_loc; + if (pfile->state.prevent_expansion) + break; + ret = enter_macro_context (pfile, node, result); + if (ret) + { + if (pfile->state.in_directive || ret == 2) + continue; + return padding_token (pfile, result); + } + } else - { - /* Flag this token as always unexpandable. FIXME: move this - to collect_args()?. */ - cpp_token *t = _cpp_temp_token (pfile); - t->type = result->type; - t->flags = result->flags | NO_EXPAND; - t->val = result->val; - result = t; - } + { + /* Flag this token as always unexpandable. FIXME: move this + to collect_args()?. */ + cpp_token *t = _cpp_temp_token (pfile); + t->type = result->type; + t->flags = result->flags | NO_EXPAND; + t->val = result->val; + result = t; + } break; } @@ -1147,6 +1256,27 @@ cpp_get_token (cpp_reader *pfile) return result; } +/* Like cpp_get_token, but also returns a location separate from the + one provided by the returned token. LOC is an out parameter; *LOC + is set to the location "as expected by the user". This matters + when a token results from macro expansion -- the token's location + will indicate where the macro is defined, but *LOC will be the + location of the start of the expansion. */ +const cpp_token * +cpp_get_token_with_location (cpp_reader *pfile, source_location *loc) +{ + const cpp_token *result; + + pfile->set_invocation_location = true; + result = cpp_get_token (pfile); + if (pfile->context->macro) + *loc = pfile->invocation_location; + else + *loc = result->src_loc; + + return result; +} + /* Returns true if we're expanding an object-like macro that was defined in a system header. Just checks the macro at the top of the stack. Used for diagnostic suppression. */ @@ -1190,25 +1320,25 @@ _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) { pfile->lookaheads += count; while (count--) - { - pfile->cur_token--; - if (pfile->cur_token == pfile->cur_run->base - /* Possible with -fpreprocessed and no leading #line. */ - && pfile->cur_run->prev != NULL) - { - pfile->cur_run = pfile->cur_run->prev; - pfile->cur_token = pfile->cur_run->limit; - } - } + { + pfile->cur_token--; + if (pfile->cur_token == pfile->cur_run->base + /* Possible with -fpreprocessed and no leading #line. */ + && pfile->cur_run->prev != NULL) + { + pfile->cur_run = pfile->cur_run->prev; + pfile->cur_token = pfile->cur_run->limit; + } + } } else { if (count != 1) - abort (); + abort (); if (pfile->context->direct_p) - FIRST (pfile->context).token--; + FIRST (pfile->context).token--; else - FIRST (pfile->context).ptoken--; + FIRST (pfile->context).ptoken--; } } @@ -1217,7 +1347,7 @@ _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) /* Returns nonzero if a macro redefinition warning is required. */ static bool warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node, - const cpp_macro *macro2) + const cpp_macro *macro2) { const cpp_macro *macro1; unsigned int i; @@ -1276,7 +1406,7 @@ _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node) if (node->flags & NODE_MACRO_ARG) { cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", - NODE_NAME (node)); + NODE_NAME (node)); return true; } @@ -1312,74 +1442,74 @@ parse_params (cpp_reader *pfile, cpp_macro *macro) const cpp_token *token = _cpp_lex_token (pfile); switch (token->type) - { - default: - /* Allow/ignore comments in parameter lists if we are - preserving comments in macro expansions. */ - if (token->type == CPP_COMMENT - && ! CPP_OPTION (pfile, discard_comments_in_macro_exp)) - continue; - - cpp_error (pfile, CPP_DL_ERROR, - "\"%s\" may not appear in macro parameter list", - cpp_token_as_text (pfile, token)); - return false; - - case CPP_NAME: - if (prev_ident) - { - cpp_error (pfile, CPP_DL_ERROR, - "macro parameters must be comma-separated"); - return false; - } - prev_ident = 1; - - if (_cpp_save_parameter (pfile, macro, token->val.node)) - return false; - continue; - - case CPP_CLOSE_PAREN: - if (prev_ident || macro->paramc == 0) - return true; - - /* Fall through to pick up the error. */ - case CPP_COMMA: - if (!prev_ident) - { - cpp_error (pfile, CPP_DL_ERROR, "parameter name missing"); - return false; - } - prev_ident = 0; - continue; - - case CPP_ELLIPSIS: - macro->variadic = 1; - if (!prev_ident) - { - _cpp_save_parameter (pfile, macro, - pfile->spec_nodes.n__VA_ARGS__); - pfile->state.va_args_ok = 1; - if (! CPP_OPTION (pfile, c99) - && CPP_OPTION (pfile, pedantic) - && CPP_OPTION (pfile, warn_variadic_macros)) - cpp_error (pfile, CPP_DL_PEDWARN, - "anonymous variadic macros were introduced in C99"); - } - else if (CPP_OPTION (pfile, pedantic) - && CPP_OPTION (pfile, warn_variadic_macros)) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C does not permit named variadic macros"); - - /* We're at the end, and just expect a closing parenthesis. */ - token = _cpp_lex_token (pfile); - if (token->type == CPP_CLOSE_PAREN) - return true; - /* Fall through. */ - - case CPP_EOF: - cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list"); - return false; - } + { + default: + /* Allow/ignore comments in parameter lists if we are + preserving comments in macro expansions. */ + if (token->type == CPP_COMMENT + && ! CPP_OPTION (pfile, discard_comments_in_macro_exp)) + continue; + + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" may not appear in macro parameter list", + cpp_token_as_text (pfile, token)); + return false; + + case CPP_NAME: + if (prev_ident) + { + cpp_error (pfile, CPP_DL_ERROR, + "macro parameters must be comma-separated"); + return false; + } + prev_ident = 1; + + if (_cpp_save_parameter (pfile, macro, token->val.node)) + return false; + continue; + + case CPP_CLOSE_PAREN: + if (prev_ident || macro->paramc == 0) + return true; + + /* Fall through to pick up the error. */ + case CPP_COMMA: + if (!prev_ident) + { + cpp_error (pfile, CPP_DL_ERROR, "parameter name missing"); + return false; + } + prev_ident = 0; + continue; + + case CPP_ELLIPSIS: + macro->variadic = 1; + if (!prev_ident) + { + _cpp_save_parameter (pfile, macro, + pfile->spec_nodes.n__VA_ARGS__); + pfile->state.va_args_ok = 1; + if (! CPP_OPTION (pfile, c99) + && CPP_OPTION (pfile, pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_error (pfile, CPP_DL_PEDWARN, + "anonymous variadic macros were introduced in C99"); + } + else if (CPP_OPTION (pfile, pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C does not permit named variadic macros"); + + /* We're at the end, and just expect a closing parenthesis. */ + token = _cpp_lex_token (pfile); + if (token->type == CPP_CLOSE_PAREN) + return true; + /* Fall through. */ + + case CPP_EOF: + cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list"); + return false; + } } } @@ -1398,10 +1528,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 @@ -1411,7 +1543,7 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) token->val.arg_no = token->val.node->value.arg_index; } else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0 - && (token->type == CPP_STRING || token->type == CPP_CHAR)) + && (token->type == CPP_STRING || token->type == CPP_CHAR)) check_trad_stringification (pfile, macro, &token->val.str); return token; @@ -1422,6 +1554,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) { cpp_token *token; const cpp_token *ctoken; + bool following_paste_op = false; + const char *paste_op_error_msg = + N_("'##' cannot appear at either end of a macro expansion"); /* Get the first token of the expansion (or the '(' of a function-like macro). */ @@ -1432,55 +1567,55 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) bool ok = parse_params (pfile, macro); macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); if (!ok) - return false; + return false; /* Success. Commit or allocate the parameter array. */ if (pfile->hash_table->alloc_subobject) - { - cpp_hashnode **params = + { + cpp_hashnode **params = (cpp_hashnode **) pfile->hash_table->alloc_subobject (sizeof (cpp_hashnode *) * macro->paramc); - memcpy (params, macro->params, - sizeof (cpp_hashnode *) * macro->paramc); - macro->params = params; - } + memcpy (params, macro->params, + sizeof (cpp_hashnode *) * macro->paramc); + macro->params = params; + } else - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; + BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; macro->fun_like = 1; } else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE)) { /* While ISO C99 requires whitespace before replacement text - in a macro definition, ISO C90 with TC1 allows there characters - from the basic source character set. */ + in a macro definition, ISO C90 with TC1 allows there characters + from the basic source character set. */ if (CPP_OPTION (pfile, c99)) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C99 requires whitespace after the macro name"); + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires whitespace after the macro name"); else - { - int warntype = CPP_DL_WARNING; - switch (ctoken->type) - { - case CPP_ATSIGN: - case CPP_AT_NAME: - case CPP_OBJC_STRING: - /* '@' is not in basic character set. */ - warntype = CPP_DL_PEDWARN; - break; - case CPP_OTHER: - /* Basic character set sans letters, digits and _. */ - if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", - ctoken->val.str.text[0]) == NULL) - warntype = CPP_DL_PEDWARN; - break; - default: - /* All other tokens start with a character from basic - character set. */ - break; - } - cpp_error (pfile, warntype, - "missing whitespace after the macro name"); - } + { + int warntype = CPP_DL_WARNING; + switch (ctoken->type) + { + case CPP_ATSIGN: + case CPP_AT_NAME: + case CPP_OBJC_STRING: + /* '@' is not in basic character set. */ + warntype = CPP_DL_PEDWARN; + break; + case CPP_OTHER: + /* Basic character set sans letters, digits and _. */ + if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", + ctoken->val.str.text[0]) == NULL) + warntype = CPP_DL_PEDWARN; + break; + default: + /* All other tokens start with a character from basic + character set. */ + break; + } + cpp_error (pfile, warntype, + "missing whitespace after the macro name"); + } } if (macro->fun_like) @@ -1494,48 +1629,56 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro) for (;;) { /* Check the stringifying # constraint 6.10.3.2.1 of - function-like macros when lexing the subsequent token. */ + function-like macros when lexing the subsequent token. */ if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like) - { - if (token->type == CPP_MACRO_ARG) - { - token->flags &= ~PREV_WHITE; - token->flags |= STRINGIFY_ARG; - token->flags |= token[-1].flags & PREV_WHITE; - token[-1] = token[0]; - macro->count--; - } - /* Let assembler get away with murder. */ - else if ((CPP_OPTION (pfile, lang) != CLK_ASM) - && (!CPP_OPTION(pfile, allow_naked_hash))) - { - cpp_error (pfile, CPP_DL_ERROR, - "'#' is not followed by a macro parameter"); - return false; - } - } + { + if (token->type == CPP_MACRO_ARG) + { + token->flags &= ~PREV_WHITE; + token->flags |= STRINGIFY_ARG; + token->flags |= token[-1].flags & PREV_WHITE; + token[-1] = token[0]; + macro->count--; + } + /* Let assembler get away with murder. */ + else if ((CPP_OPTION (pfile, lang) != CLK_ASM) + && (!CPP_OPTION(pfile, allow_naked_hash))) + { + cpp_error (pfile, CPP_DL_ERROR, + "'#' is not followed by a macro parameter"); + return false; + } + } if (token->type == CPP_EOF) - break; + { + /* Paste operator constraint 6.10.3.3.1: + Token-paste ##, can appear in both object-like and + function-like macros, but not at the end. */ + if (following_paste_op) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + return false; + } + break; + } /* Paste operator constraint 6.10.3.3.1. */ if (token->type == CPP_PASTE) - { - /* Token-paste ##, can appear in both object-like and - function-like macros, but not at the ends. */ - if (--macro->count > 0) - token = lex_expansion_token (pfile, macro); - - if (macro->count == 0 || token->type == CPP_EOF) - { - cpp_error (pfile, CPP_DL_ERROR, - "'##' cannot appear at either end of a macro expansion"); - return false; - } - - token[-1].flags |= PASTE_LEFT; - } - + { + /* Token-paste ##, can appear in both object-like and + function-like macros, but not at the beginning. */ + if (macro->count == 1) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + return false; + } + + --macro->count; + token[-1].flags |= PASTE_LEFT; + } + + following_paste_op = (token->type == CPP_PASTE); token = lex_expansion_token (pfile, macro); } @@ -1591,18 +1734,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; + Longer term we should lex the whole line before coming here, + and just copy the expansion. */ /* Stop the lexer accepting __VA_ARGS__. */ pfile->state.va_args_ok = 0; @@ -1622,18 +1759,18 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) if (node->type == NT_MACRO) { if (CPP_OPTION (pfile, warn_unused_macros)) - _cpp_warn_if_unused_macro (pfile, node, NULL); + _cpp_warn_if_unused_macro (pfile, node, NULL); if (warn_of_redefinition (pfile, node, macro)) - { - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0, - "\"%s\" redefined", NODE_NAME (node)); - - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) - cpp_error_with_line (pfile, CPP_DL_PEDWARN, - node->value.macro->line, 0, - "this is the location of the previous definition"); - } + { + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0, + "\"%s\" redefined", NODE_NAME (node)); + + if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, + node->value.macro->line, 0, + "this is the location of the previous definition"); + } } if (node->type != NT_VOID) @@ -1642,7 +1779,14 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) /* Enter definition in hash table. */ node->type = NT_MACRO; node->value.macro = macro; - if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))) + if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")) + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS") + /* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned + in the C standard, as something that one must use in C++. + However DR#593 indicates that these aren't actually mentioned + in the C++ standard. We special-case them anyway. */ + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS") + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS")) node->flags |= NODE_WARN; return ok; @@ -1652,7 +1796,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) parameters. */ static void check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, - const cpp_string *string) + const cpp_string *string) { unsigned int i, len; const uchar *p, *q, *limit; @@ -1663,30 +1807,30 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, { /* Find the start of an identifier. */ while (p < limit && !is_idstart (*p)) - p++; + p++; /* Find the end of the identifier. */ q = p; while (q < limit && is_idchar (*q)) - q++; + q++; len = q - p; /* Loop over the function macro arguments to see if the - identifier inside the string matches one of them. */ + identifier inside the string matches one of them. */ for (i = 0; i < macro->paramc; i++) - { - const cpp_hashnode *node = macro->params[i]; - - if (NODE_LEN (node) == len - && !memcmp (p, NODE_NAME (node), len)) - { - cpp_error (pfile, CPP_DL_WARNING, - "macro argument \"%s\" would be stringified in traditional C", - NODE_NAME (node)); - break; - } - } + { + const cpp_hashnode *node = macro->params[i]; + + if (NODE_LEN (node) == len + && !memcmp (p, NODE_NAME (node), len)) + { + cpp_error (pfile, CPP_DL_WARNING, + "macro argument \"%s\" would be stringified in traditional C", + NODE_NAME (node)); + break; + } + } } } @@ -1705,18 +1849,18 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN)) { cpp_error (pfile, CPP_DL_ICE, - "invalid hash type %d in cpp_macro_definition", node->type); + "invalid hash type %d in cpp_macro_definition", node->type); return 0; } /* Calculate length. */ - len = NODE_LEN (node) + 2; /* ' ' and NUL. */ + len = NODE_LEN (node) + 2; /* ' ' and NUL. */ if (macro->fun_like) { - len += 4; /* "()" plus possible final ".." of named - varargs (we have + 1 below). */ + len += 4; /* "()" plus possible final ".." of named + varargs (we have + 1 below). */ for (i = 0; i < macro->paramc; i++) - len += NODE_LEN (macro->params[i]) + 1; /* "," */ + len += NODE_LEN (macro->params[i]) + 1; /* "," */ } /* This should match below where we fill in the buffer. */ @@ -1725,21 +1869,21 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) else { for (i = 0; i < macro->count; i++) - { - cpp_token *token = ¯o->exp.tokens[i]; - - if (token->type == CPP_MACRO_ARG) - len += NODE_LEN (macro->params[token->val.arg_no - 1]); - else - len += cpp_token_len (token); - - if (token->flags & STRINGIFY_ARG) - len++; /* "#" */ - if (token->flags & PASTE_LEFT) - len += 3; /* " ##" */ - if (token->flags & PREV_WHITE) - len++; /* " " */ - } + { + cpp_token *token = ¯o->exp.tokens[i]; + + if (token->type == CPP_MACRO_ARG) + len += NODE_LEN (macro->params[token->val.arg_no - 1]); + else + len += cpp_token_len (token); + + if (token->flags & STRINGIFY_ARG) + len++; /* "#" */ + if (token->flags & PASTE_LEFT) + len += 3; /* " ##" */ + if (token->flags & PREV_WHITE) + len++; /* " " */ + } } if (len > pfile->macro_buffer_len) @@ -1759,23 +1903,23 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) { *buffer++ = '('; for (i = 0; i < macro->paramc; i++) - { - cpp_hashnode *param = macro->params[i]; - - if (param != pfile->spec_nodes.n__VA_ARGS__) - { - memcpy (buffer, NODE_NAME (param), NODE_LEN (param)); - buffer += NODE_LEN (param); - } - - if (i + 1 < macro->paramc) - /* Don't emit a space after the comma here; we're trying - to emit a Dwarf-friendly definition, and the Dwarf spec - forbids spaces in the argument list. */ - *buffer++ = ','; - else if (macro->variadic) - *buffer++ = '.', *buffer++ = '.', *buffer++ = '.'; - } + { + cpp_hashnode *param = macro->params[i]; + + if (param != pfile->spec_nodes.n__VA_ARGS__) + { + memcpy (buffer, NODE_NAME (param), NODE_LEN (param)); + buffer += NODE_LEN (param); + } + + if (i + 1 < macro->paramc) + /* Don't emit a space after the comma here; we're trying + to emit a Dwarf-friendly definition, and the Dwarf spec + forbids spaces in the argument list. */ + *buffer++ = ','; + else if (macro->variadic) + *buffer++ = '.', *buffer++ = '.', *buffer++ = '.'; + } *buffer++ = ')'; } @@ -1789,32 +1933,32 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) /* Expansion tokens. */ { for (i = 0; i < macro->count; i++) - { - cpp_token *token = ¯o->exp.tokens[i]; - - if (token->flags & PREV_WHITE) - *buffer++ = ' '; - if (token->flags & STRINGIFY_ARG) - *buffer++ = '#'; - - if (token->type == CPP_MACRO_ARG) - { - memcpy (buffer, - NODE_NAME (macro->params[token->val.arg_no - 1]), - NODE_LEN (macro->params[token->val.arg_no - 1])); - buffer += NODE_LEN (macro->params[token->val.arg_no - 1]); - } - else - buffer = cpp_spell_token (pfile, token, buffer, false); - - if (token->flags & PASTE_LEFT) - { - *buffer++ = ' '; - *buffer++ = '#'; - *buffer++ = '#'; - /* Next has PREV_WHITE; see _cpp_create_definition. */ - } - } + { + cpp_token *token = ¯o->exp.tokens[i]; + + if (token->flags & PREV_WHITE) + *buffer++ = ' '; + if (token->flags & STRINGIFY_ARG) + *buffer++ = '#'; + + if (token->type == CPP_MACRO_ARG) + { + memcpy (buffer, + NODE_NAME (macro->params[token->val.arg_no - 1]), + NODE_LEN (macro->params[token->val.arg_no - 1])); + buffer += NODE_LEN (macro->params[token->val.arg_no - 1]); + } + else + buffer = cpp_spell_token (pfile, token, buffer, false); + + if (token->flags & PASTE_LEFT) + { + *buffer++ = ' '; + *buffer++ = '#'; + *buffer++ = '#'; + /* Next has PREV_WHITE; see _cpp_create_definition. */ + } + } } *buffer = '\0'; diff --git a/support/cpp2/libcpp/mkdeps.c b/support/cpp/libcpp/mkdeps.c similarity index 100% rename from support/cpp2/libcpp/mkdeps.c rename to support/cpp/libcpp/mkdeps.c diff --git a/support/cpp2/libcpp/symtab.c b/support/cpp/libcpp/symtab.c similarity index 100% rename from support/cpp2/libcpp/symtab.c rename to support/cpp/libcpp/symtab.c diff --git a/support/cpp2/libcpp/system.h b/support/cpp/libcpp/system.h similarity index 99% rename from support/cpp2/libcpp/system.h rename to support/cpp/libcpp/system.h index 3e0d89da..1691b34f 100644 --- a/support/cpp2/libcpp/system.h +++ b/support/cpp/libcpp/system.h @@ -370,7 +370,7 @@ extern void abort (void); #endif #ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) #endif /* __builtin_expect(A, B) evaluates to A, but notifies the compiler that diff --git a/support/cpp2/libcpp/traditional.c b/support/cpp/libcpp/traditional.c similarity index 53% rename from support/cpp2/libcpp/traditional.c rename to support/cpp/libcpp/traditional.c index a543348d..6a9e695c 100644 --- a/support/cpp2/libcpp/traditional.c +++ b/support/cpp/libcpp/traditional.c @@ -1,5 +1,5 @@ /* CPP Library - traditional lexical analysis and macro expansion. - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Contributed by Neil Booth, May 2002 This program is free software; you can redistribute it and/or modify it @@ -67,14 +67,14 @@ struct fun_macro }; /* Lexing state. It is mostly used to prevent macro expansion. */ -enum ls {ls_none = 0, /* Normal state. */ - ls_fun_open, /* When looking for '('. */ - ls_fun_close, /* When looking for ')'. */ - ls_defined, /* After defined. */ - ls_defined_close, /* Looking for ')' of defined(). */ - ls_hash, /* After # in preprocessor conditional. */ - ls_predicate, /* After the predicate, maybe paren? */ - ls_answer}; /* In answer to predicate. */ +enum ls {ls_none = 0, /* Normal state. */ + ls_fun_open, /* When looking for '('. */ + ls_fun_close, /* When looking for ')'. */ + ls_defined, /* After defined. */ + ls_defined_close, /* Looking for ')' of defined(). */ + ls_hash, /* After # in preprocessor conditional. */ + ls_predicate, /* After the predicate, maybe paren? */ + ls_answer}; /* In answer to predicate. */ /* Lexing TODO: Maybe handle space in escaped newlines. Stop lex.c from recognizing comments and directives during its lexing pass. */ @@ -88,7 +88,7 @@ static bool scan_parameters (cpp_reader *, cpp_macro *); static bool recursive_macro (cpp_reader *, cpp_hashnode *); static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int); static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *, - struct fun_macro *); + struct fun_macro *); static void save_argument (struct fun_macro *, size_t); static void replace_args_and_push (cpp_reader *, struct fun_macro *); static size_t canonicalize_text (uchar *, const uchar *, size_t, uchar *); @@ -156,10 +156,10 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) unterminated = false, skip_macro_block_comment (pfile); else unterminated = _cpp_skip_block_comment (pfile); - + if (unterminated) cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, - "unterminated comment"); + "unterminated comment"); /* Comments in directives become spaces so that tokens are properly separated when the ISO preprocessor re-lexes the line. The @@ -167,14 +167,14 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) if (pfile->state.in_directive) { if (in_define) - { - if (CPP_OPTION (pfile, discard_comments_in_macro_exp)) - pfile->out.cur--; - else - copy = true; - } + { + if (CPP_OPTION (pfile, discard_comments_in_macro_exp)) + pfile->out.cur--; + else + copy = true; + } else - pfile->out.cur[-1] = ' '; + pfile->out.cur[-1] = ' '; } else if (CPP_OPTION (pfile, discard_comments)) pfile->out.cur--; @@ -187,10 +187,10 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) memcpy (pfile->out.cur, cur, len); pfile->out.cur += len; if (unterminated) - { - *pfile->out.cur++ = '*'; - *pfile->out.cur++ = '/'; - } + { + *pfile->out.cur++ = '*'; + *pfile->out.cur++ = '/'; + } } return buffer->cur; @@ -219,15 +219,15 @@ skip_whitespace (cpp_reader *pfile, const uchar *cur, int skip_comments) *out++ = c; if (is_nvspace (c)) - continue; + continue; if (c == '/' && *cur == '*' && skip_comments) - { - pfile->out.cur = out; - cur = copy_comment (pfile, cur, false /* in_define */); - out = pfile->out.cur; - continue; - } + { + pfile->out.cur = out; + cur = copy_comment (pfile, cur, false /* in_define */); + out = pfile->out.cur; + continue; + } out--; break; @@ -254,7 +254,7 @@ lex_identifier (cpp_reader *pfile, const uchar *cur) CUR (pfile->context) = cur; len = out - pfile->out.cur; result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur, - len, HT_ALLOC); + len, HT_ALLOC); pfile->out.cur = out; return result; } @@ -300,7 +300,7 @@ _cpp_read_logical_line_trad (cpp_reader *pfile) do { if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile)) - return false; + return false; } while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile->state.skipping); @@ -353,6 +353,11 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) const uchar *start_of_input_line; fmacro.buff = NULL; + fmacro.args = NULL; + fmacro.node = NULL; + fmacro.offset = 0; + fmacro.line = 0; + fmacro.argc = 0; quote = 0; header_ok = pfile->state.angled_headers; @@ -372,296 +377,296 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) for (;;) { if (!context->prev - && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos) - { - pfile->buffer->cur = cur; - _cpp_process_line_notes (pfile, false); - } + && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos) + { + pfile->buffer->cur = cur; + _cpp_process_line_notes (pfile, false); + } c = *cur++; *out++ = c; /* Whitespace should "continue" out of the switch, - non-whitespace should "break" out of it. */ + non-whitespace should "break" out of it. */ switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\0': - continue; - - case '\n': - /* If this is a macro's expansion, pop it. */ - if (context->prev) - { - pfile->out.cur = out - 1; - _cpp_pop_context (pfile); - goto new_context; - } - - /* Omit the newline from the output buffer. */ - pfile->out.cur = out - 1; - pfile->buffer->cur = cur; - pfile->buffer->need_line = true; - CPP_INCREMENT_LINE (pfile, 0); - - if ((lex_state == ls_fun_open || lex_state == ls_fun_close) - && !pfile->state.in_directive - && _cpp_get_fresh_line (pfile)) - { - /* Newlines in arguments become a space, but we don't - clear any in-progress quote. */ - if (lex_state == ls_fun_close) - out[-1] = ' '; - cur = pfile->buffer->cur; - continue; - } - goto done; - - case '<': - if (header_ok) - quote = '>'; - break; - case '>': - if (c == quote) - quote = 0; - break; - - case '"': - case '\'': - if (c == quote) - quote = 0; - else if (!quote) - quote = c; - break; - - case '\\': - /* Skip escaped quotes here, it's easier than above. */ - if (*cur == '\\' || *cur == '"' || *cur == '\'') - *out++ = *cur++; - break; - - case '/': - /* Traditional CPP does not recognize comments within - literals. */ - if (!quote && *cur == '*') - { - pfile->out.cur = out; - cur = copy_comment (pfile, cur, macro != 0); - out = pfile->out.cur; - continue; - } - break; - - case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': - case 's': case 't': case 'u': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - if (!pfile->state.skipping && (quote == 0 || macro)) - { - cpp_hashnode *node; - uchar *out_start = out - 1; - - pfile->out.cur = out_start; - node = lex_identifier (pfile, cur - 1); - out = pfile->out.cur; - cur = CUR (context); - - if (node->type == NT_MACRO - /* Should we expand for ls_answer? */ - && (lex_state == ls_none || lex_state == ls_fun_open) - && !pfile->state.prevent_expansion) - { - /* Macros invalidate MI optimization. */ - pfile->mi_valid = false; - if (! (node->flags & NODE_BUILTIN) - && node->value.macro->fun_like) - { - maybe_start_funlike (pfile, node, out_start, &fmacro); - lex_state = ls_fun_open; - fmacro.line = pfile->line_table->highest_line; - continue; - } - else if (!recursive_macro (pfile, node)) - { - /* Remove the object-like macro's name from the - output, and push its replacement text. */ - pfile->out.cur = out_start; - push_replacement_text (pfile, node); - lex_state = ls_none; - goto new_context; - } - } - else if (macro && (node->flags & NODE_MACRO_ARG) != 0) - { - /* Found a parameter in the replacement text of a - #define. Remove its name from the output. */ - pfile->out.cur = out_start; - save_replacement_text (pfile, macro, node->value.arg_index); - out = pfile->out.base; - } - else if (lex_state == ls_hash) - { - lex_state = ls_predicate; - continue; - } - else if (pfile->state.in_expression - && node == pfile->spec_nodes.n_defined) - { - lex_state = ls_defined; - continue; - } - } - break; - - case '(': - if (quote == 0) - { - paren_depth++; - if (lex_state == ls_fun_open) - { - if (recursive_macro (pfile, fmacro.node)) - lex_state = ls_none; - else - { - lex_state = ls_fun_close; - paren_depth = 1; - out = pfile->out.base + fmacro.offset; - fmacro.args[0] = fmacro.offset; - } - } - else if (lex_state == ls_predicate) - lex_state = ls_answer; - else if (lex_state == ls_defined) - lex_state = ls_defined_close; - } - break; - - case ',': - if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1) - save_argument (&fmacro, out - pfile->out.base); - break; - - case ')': - if (quote == 0) - { - paren_depth--; - if (lex_state == ls_fun_close && paren_depth == 0) - { - cpp_macro *m = fmacro.node->value.macro; - - m->used = 1; - lex_state = ls_none; - save_argument (&fmacro, out - pfile->out.base); - - /* A single zero-length argument is no argument. */ - if (fmacro.argc == 1 - && m->paramc == 0 - && out == pfile->out.base + fmacro.offset + 1) - fmacro.argc = 0; - - if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc)) - { - /* Remove the macro's invocation from the - output, and push its replacement text. */ - pfile->out.cur = (pfile->out.base - + fmacro.offset); - CUR (context) = cur; - replace_args_and_push (pfile, &fmacro); - goto new_context; - } - } - else if (lex_state == ls_answer || lex_state == ls_defined_close) - lex_state = ls_none; - } - break; - - case '#': - if (cur - 1 == start_of_input_line - /* A '#' from a macro doesn't start a directive. */ - && !pfile->context->prev - && !pfile->state.in_directive) - { - /* A directive. With the way _cpp_handle_directive - currently works, we only want to call it if either we - know the directive is OK, or we want it to fail and - be removed from the output. If we want it to be - passed through (the assembler case) then we must not - call _cpp_handle_directive. */ - pfile->out.cur = out; - cur = skip_whitespace (pfile, cur, true /* skip_comments */); - out = pfile->out.cur; - - if (*cur == '\n') - { - /* Null directive. Ignore it and don't invalidate - the MI optimization. */ - pfile->buffer->need_line = true; - CPP_INCREMENT_LINE (pfile, 0); - result = false; - goto done; - } - else - { - bool do_it = false; - - if (is_numstart (*cur) - && CPP_OPTION (pfile, lang) != CLK_ASM) - do_it = true; - else if (is_idstart (*cur)) - /* Check whether we know this directive, but don't - advance. */ - do_it = lex_identifier (pfile, cur)->is_directive; - - if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM) - { - /* This is a kludge. We want to have the ISO - preprocessor lex the next token. */ - pfile->buffer->cur = cur; - _cpp_handle_directive (pfile, false /* indented */); - result = false; - goto done; - } - } - } - - if (pfile->state.in_expression) - { - lex_state = ls_hash; - continue; - } - break; - - default: - break; - } + { + case ' ': + case '\t': + case '\f': + case '\v': + case '\0': + continue; + + case '\n': + /* If this is a macro's expansion, pop it. */ + if (context->prev) + { + pfile->out.cur = out - 1; + _cpp_pop_context (pfile); + goto new_context; + } + + /* Omit the newline from the output buffer. */ + pfile->out.cur = out - 1; + pfile->buffer->cur = cur; + pfile->buffer->need_line = true; + CPP_INCREMENT_LINE (pfile, 0); + + if ((lex_state == ls_fun_open || lex_state == ls_fun_close) + && !pfile->state.in_directive + && _cpp_get_fresh_line (pfile)) + { + /* Newlines in arguments become a space, but we don't + clear any in-progress quote. */ + if (lex_state == ls_fun_close) + out[-1] = ' '; + cur = pfile->buffer->cur; + continue; + } + goto done; + + case '<': + if (header_ok) + quote = '>'; + break; + case '>': + if (c == quote) + quote = 0; + break; + + case '"': + case '\'': + if (c == quote) + quote = 0; + else if (!quote) + quote = c; + break; + + case '\\': + /* Skip escaped quotes here, it's easier than above. */ + if (*cur == '\\' || *cur == '"' || *cur == '\'') + *out++ = *cur++; + break; + + case '/': + /* Traditional CPP does not recognize comments within + literals. */ + if (!quote && *cur == '*') + { + pfile->out.cur = out; + cur = copy_comment (pfile, cur, macro != 0); + out = pfile->out.cur; + continue; + } + break; + + case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + if (!pfile->state.skipping && (quote == 0 || macro)) + { + cpp_hashnode *node; + uchar *out_start = out - 1; + + pfile->out.cur = out_start; + node = lex_identifier (pfile, cur - 1); + out = pfile->out.cur; + cur = CUR (context); + + if (node->type == NT_MACRO + /* Should we expand for ls_answer? */ + && (lex_state == ls_none || lex_state == ls_fun_open) + && !pfile->state.prevent_expansion) + { + /* Macros invalidate MI optimization. */ + pfile->mi_valid = false; + if (! (node->flags & NODE_BUILTIN) + && node->value.macro->fun_like) + { + maybe_start_funlike (pfile, node, out_start, &fmacro); + lex_state = ls_fun_open; + fmacro.line = pfile->line_table->highest_line; + continue; + } + else if (!recursive_macro (pfile, node)) + { + /* Remove the object-like macro's name from the + output, and push its replacement text. */ + pfile->out.cur = out_start; + push_replacement_text (pfile, node); + lex_state = ls_none; + goto new_context; + } + } + else if (macro && (node->flags & NODE_MACRO_ARG) != 0) + { + /* Found a parameter in the replacement text of a + #define. Remove its name from the output. */ + pfile->out.cur = out_start; + save_replacement_text (pfile, macro, node->value.arg_index); + out = pfile->out.base; + } + else if (lex_state == ls_hash) + { + lex_state = ls_predicate; + continue; + } + else if (pfile->state.in_expression + && node == pfile->spec_nodes.n_defined) + { + lex_state = ls_defined; + continue; + } + } + break; + + case '(': + if (quote == 0) + { + paren_depth++; + if (lex_state == ls_fun_open) + { + if (recursive_macro (pfile, fmacro.node)) + lex_state = ls_none; + else + { + lex_state = ls_fun_close; + paren_depth = 1; + out = pfile->out.base + fmacro.offset; + fmacro.args[0] = fmacro.offset; + } + } + else if (lex_state == ls_predicate) + lex_state = ls_answer; + else if (lex_state == ls_defined) + lex_state = ls_defined_close; + } + break; + + case ',': + if (quote == 0 && lex_state == ls_fun_close && paren_depth == 1) + save_argument (&fmacro, out - pfile->out.base); + break; + + case ')': + if (quote == 0) + { + paren_depth--; + if (lex_state == ls_fun_close && paren_depth == 0) + { + cpp_macro *m = fmacro.node->value.macro; + + m->used = 1; + lex_state = ls_none; + save_argument (&fmacro, out - pfile->out.base); + + /* A single zero-length argument is no argument. */ + if (fmacro.argc == 1 + && m->paramc == 0 + && out == pfile->out.base + fmacro.offset + 1) + fmacro.argc = 0; + + if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc)) + { + /* Remove the macro's invocation from the + output, and push its replacement text. */ + pfile->out.cur = (pfile->out.base + + fmacro.offset); + CUR (context) = cur; + replace_args_and_push (pfile, &fmacro); + goto new_context; + } + } + else if (lex_state == ls_answer || lex_state == ls_defined_close) + lex_state = ls_none; + } + break; + + case '#': + if (cur - 1 == start_of_input_line + /* A '#' from a macro doesn't start a directive. */ + && !pfile->context->prev + && !pfile->state.in_directive) + { + /* A directive. With the way _cpp_handle_directive + currently works, we only want to call it if either we + know the directive is OK, or we want it to fail and + be removed from the output. If we want it to be + passed through (the assembler case) then we must not + call _cpp_handle_directive. */ + pfile->out.cur = out; + cur = skip_whitespace (pfile, cur, true /* skip_comments */); + out = pfile->out.cur; + + if (*cur == '\n') + { + /* Null directive. Ignore it and don't invalidate + the MI optimization. */ + pfile->buffer->need_line = true; + CPP_INCREMENT_LINE (pfile, 0); + result = false; + goto done; + } + else + { + bool do_it = false; + + if (is_numstart (*cur) + && CPP_OPTION (pfile, lang) != CLK_ASM) + do_it = true; + else if (is_idstart (*cur)) + /* Check whether we know this directive, but don't + advance. */ + do_it = lex_identifier (pfile, cur)->is_directive; + + if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM) + { + /* This is a kludge. We want to have the ISO + preprocessor lex the next token. */ + pfile->buffer->cur = cur; + _cpp_handle_directive (pfile, false /* indented */); + result = false; + goto done; + } + } + } + + if (pfile->state.in_expression) + { + lex_state = ls_hash; + continue; + } + break; + + default: + break; + } /* Non-whitespace disables MI optimization and stops treating - '<' as a quote in #include. */ + '<' as a quote in #include. */ header_ok = false; if (!pfile->state.in_directive) - pfile->mi_valid = false; + pfile->mi_valid = false; if (lex_state == ls_none) - continue; + continue; /* Some of these transitions of state are syntax errors. The - ISO preprocessor will issue errors later. */ + ISO preprocessor will issue errors later. */ if (lex_state == ls_fun_open) - /* Missing '('. */ - lex_state = ls_none; + /* Missing '('. */ + lex_state = ls_none; else if (lex_state == ls_hash - || lex_state == ls_predicate - || lex_state == ls_defined) - lex_state = ls_none; + || lex_state == ls_predicate + || lex_state == ls_defined) + lex_state = ls_none; /* ls_answer and ls_defined_close keep going until ')'. */ } @@ -672,8 +677,8 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) if (lex_state == ls_fun_close) cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0, - "unterminated argument list invoking macro \"%s\"", - NODE_NAME (fmacro.node)); + "unterminated argument list invoking macro \"%s\"", + NODE_NAME (fmacro.node)); return result; } @@ -730,20 +735,20 @@ recursive_macro (cpp_reader *pfile, cpp_hashnode *node) cpp_context *context = pfile->context; do - { - depth++; - if (context->macro == node && depth > 20) - break; - context = context->prev; - } + { + depth++; + if (context->macro == node && depth > 20) + break; + context = context->prev; + } while (context); recursing = context != NULL; } if (recursing) cpp_error (pfile, CPP_DL_ERROR, - "detected recursion whilst expanding macro \"%s\"", - NODE_NAME (node)); + "detected recursion whilst expanding macro \"%s\"", + NODE_NAME (node)); return recursing; } @@ -761,19 +766,19 @@ _cpp_replacement_text_len (const cpp_macro *macro) len = 0; for (exp = macro->exp.text;;) - { - struct block *b = (struct block *) exp; - - len += b->text_len; - if (b->arg_index == 0) - break; - len += NODE_LEN (macro->params[b->arg_index - 1]); - exp += BLOCK_LEN (b->text_len); - } + { + struct block *b = (struct block *) exp; + + len += b->text_len; + if (b->arg_index == 0) + break; + len += NODE_LEN (macro->params[b->arg_index - 1]); + exp += BLOCK_LEN (b->text_len); + } } else len = macro->count; - + return len; } @@ -788,19 +793,19 @@ _cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest) const uchar *exp; for (exp = macro->exp.text;;) - { - struct block *b = (struct block *) exp; - cpp_hashnode *param; - - memcpy (dest, b->text, b->text_len); - dest += b->text_len; - if (b->arg_index == 0) - break; - param = macro->params[b->arg_index - 1]; - memcpy (dest, NODE_NAME (param), NODE_LEN (param)); - dest += NODE_LEN (param); - exp += BLOCK_LEN (b->text_len); - } + { + struct block *b = (struct block *) exp; + cpp_hashnode *param; + + memcpy (dest, b->text, b->text_len); + dest += b->text_len; + if (b->arg_index == 0) + break; + param = macro->params[b->arg_index - 1]; + memcpy (dest, NODE_NAME (param), NODE_LEN (param)); + dest += NODE_LEN (param); + exp += BLOCK_LEN (b->text_len); + } } else { @@ -827,41 +832,92 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro) uchar *p; _cpp_buff *buff; size_t len = 0; + int cxtquote = 0; - /* Calculate the length of the argument-replaced text. */ + /* Get an estimate of the length of the argument-replaced text. + This is a worst case estimate, assuming that every replacement + text character needs quoting. */ for (exp = macro->exp.text;;) - { - struct block *b = (struct block *) exp; + { + struct block *b = (struct block *) exp; - len += b->text_len; - if (b->arg_index == 0) - break; - len += (fmacro->args[b->arg_index] - - fmacro->args[b->arg_index - 1] - 1); - exp += BLOCK_LEN (b->text_len); - } + len += b->text_len; + if (b->arg_index == 0) + break; + len += 2 * (fmacro->args[b->arg_index] + - fmacro->args[b->arg_index - 1] - 1); + exp += BLOCK_LEN (b->text_len); + } /* Allocate room for the expansion plus \n. */ buff = _cpp_get_buff (pfile, len + 1); /* Copy the expansion and replace arguments. */ + /* Accumulate actual length, including quoting as necessary */ p = BUFF_FRONT (buff); + len = 0; for (exp = macro->exp.text;;) - { - struct block *b = (struct block *) exp; - size_t arglen; - - memcpy (p, b->text, b->text_len); - p += b->text_len; - if (b->arg_index == 0) - break; - arglen = (fmacro->args[b->arg_index] - - fmacro->args[b->arg_index - 1] - 1); - memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1], - arglen); - p += arglen; - exp += BLOCK_LEN (b->text_len); - } + { + struct block *b = (struct block *) exp; + size_t arglen; + int argquote; + uchar *base; + uchar *in; + + len += b->text_len; + /* Copy the non-argument text literally, keeping + track of whether matching quotes have been seen. */ + for (arglen = b->text_len, in = b->text; arglen > 0; arglen--) + { + if (*in == '"') + cxtquote = ! cxtquote; + *p++ = *in++; + } + /* Done if no more arguments */ + if (b->arg_index == 0) + break; + arglen = (fmacro->args[b->arg_index] + - fmacro->args[b->arg_index - 1] - 1); + base = pfile->out.base + fmacro->args[b->arg_index - 1]; + in = base; +#if 0 + /* Skip leading whitespace in the text for the argument to + be substituted. To be compatible with gcc 2.95, we would + also need to trim trailing whitespace. Gcc 2.95 trims + leading and trailing whitespace, which may be a bug. The + current gcc testsuite explicitly checks that this leading + and trailing whitespace in actual arguments is + preserved. */ + while (arglen > 0 && is_space (*in)) + { + in++; + arglen--; + } +#endif + for (argquote = 0; arglen > 0; arglen--) + { + if (cxtquote && *in == '"') + { + if (in > base && *(in-1) != '\\') + argquote = ! argquote; + /* Always add backslash before double quote if argument + is expanded in a quoted context */ + *p++ = '\\'; + len++; + } + else if (cxtquote && argquote && *in == '\\') + { + /* Always add backslash before a backslash in an argument + that is expanded in a quoted context and also in the + range of a quoted context in the argument itself. */ + *p++ = '\\'; + len++; + } + *p++ = *in++; + len++; + } + exp += BLOCK_LEN (b->text_len); + } /* \n-terminate. */ *p = '\n'; @@ -889,20 +945,20 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro) cur = skip_whitespace (pfile, cur, true /* skip_comments */); if (is_idstart (*cur)) - { - ok = false; - if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur))) - break; - cur = skip_whitespace (pfile, CUR (pfile->context), - true /* skip_comments */); - if (*cur == ',') - { - cur++; - continue; - } - ok = (*cur == ')'); - break; - } + { + ok = false; + if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur))) + break; + cur = skip_whitespace (pfile, CUR (pfile->context), + true /* skip_comments */); + if (*cur == ',') + { + cur++; + continue; + } + ok = (*cur == ')'); + break; + } ok = (*cur == ')' && macro->paramc == 0); break; @@ -922,7 +978,7 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro) text. */ static void save_replacement_text (cpp_reader *pfile, cpp_macro *macro, - unsigned int arg_index) + unsigned int arg_index) { size_t len = pfile->out.cur - pfile->out.base; uchar *exp; @@ -930,7 +986,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, if (macro->paramc == 0) { /* Object-like and function-like macros without parameters - simply store their \n-terminated replacement text. */ + simply store their \n-terminated replacement text. */ exp = _cpp_unaligned_alloc (pfile, len + 1); memcpy (exp, pfile->out.base, len); exp[len] = '\n'; @@ -941,12 +997,12 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, else { /* Store the text's length (unsigned int), the argument index - (unsigned short, base 1) and then the text. */ + (unsigned short, base 1) and then the text. */ size_t blen = BLOCK_LEN (len); struct block *block; if (macro->count + blen > BUFF_ROOM (pfile->a_buff)) - _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen); + _cpp_extend_buff (pfile, &pfile->a_buff, macro->count + blen); exp = BUFF_FRONT (pfile->a_buff); block = (struct block *) (exp + macro->count); @@ -965,7 +1021,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, /* If we've finished, commit the memory. */ if (arg_index == 0) - BUFF_FRONT (pfile->a_buff) += macro->count; + BUFF_FRONT (pfile->a_buff) += macro->count; } } @@ -994,20 +1050,20 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); /* Setting macro to NULL indicates an error occurred, and - prevents unnecessary work in _cpp_scan_out_logical_line. */ + prevents unnecessary work in _cpp_scan_out_logical_line. */ if (!ok) - macro = NULL; + macro = NULL; else - { - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; - macro->fun_like = 1; - } + { + BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; + macro->fun_like = 1; + } } /* Skip leading whitespace in the replacement text. */ pfile->buffer->cur = skip_whitespace (pfile, CUR (context), - CPP_OPTION (pfile, discard_comments_in_macro_exp)); + CPP_OPTION (pfile, discard_comments_in_macro_exp)); pfile->state.prevent_expansion++; _cpp_scan_out_logical_line (pfile, macro); @@ -1040,23 +1096,23 @@ canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote) while (len) { if (is_space (*src) && !quote) - { - do - src++, len--; - while (len && is_space (*src)); - *dest++ = ' '; - } + { + do + src++, len--; + while (len && is_space (*src)); + *dest++ = ' '; + } else - { - if (*src == '\'' || *src == '"') - { - if (!quote) - quote = *src; - else if (quote == *src) - quote = 0; - } - *dest++ = *src++, len--; - } + { + if (*src == '\'' || *src == '"') + { + if (!quote) + quote = *src; + else if (quote == *src) + quote = 0; + } + *dest++ = *src++, len--; + } } *pquote = quote; @@ -1067,7 +1123,7 @@ canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote) than in the form of their whitespace. */ bool _cpp_expansions_different_trad (const cpp_macro *macro1, - const cpp_macro *macro2) + const cpp_macro *macro2) { uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count); uchar *p2 = p1 + macro1->count; @@ -1081,25 +1137,25 @@ _cpp_expansions_different_trad (const cpp_macro *macro1, mismatch = true; for (;;) - { - struct block *b1 = (struct block *) exp1; - struct block *b2 = (struct block *) exp2; - - if (b1->arg_index != b2->arg_index) - break; - - len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1); - len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2); - if (len1 != len2 || memcmp (p1, p2, len1)) - break; - if (b1->arg_index == 0) - { - mismatch = false; - break; - } - exp1 += BLOCK_LEN (b1->text_len); - exp2 += BLOCK_LEN (b2->text_len); - } + { + struct block *b1 = (struct block *) exp1; + struct block *b2 = (struct block *) exp2; + + if (b1->arg_index != b2->arg_index) + break; + + len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1); + len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2); + if (len1 != len2 || memcmp (p1, p2, len1)) + break; + if (b1->arg_index == 0) + { + mismatch = false; + break; + } + exp1 += BLOCK_LEN (b1->text_len); + exp2 += BLOCK_LEN (b2->text_len); + } } else { diff --git a/support/cpp2/libcpp/ucnid.h b/support/cpp/libcpp/ucnid.h similarity index 100% rename from support/cpp2/libcpp/ucnid.h rename to support/cpp/libcpp/ucnid.h diff --git a/support/cpp2/libiberty.h b/support/cpp/libiberty.h similarity index 100% rename from support/cpp2/libiberty.h rename to support/cpp/libiberty.h diff --git a/support/cpp2/libiberty/concat.c b/support/cpp/libiberty/concat.c similarity index 100% rename from support/cpp2/libiberty/concat.c rename to support/cpp/libiberty/concat.c diff --git a/support/cpp2/libiberty/filenames.h b/support/cpp/libiberty/filenames.h similarity index 79% rename from support/cpp2/libiberty/filenames.h rename to support/cpp/libiberty/filenames.h index 6b72fd24..c82950f4 100644 --- a/support/cpp2/libiberty/filenames.h +++ b/support/cpp/libiberty/filenames.h @@ -5,7 +5,7 @@ use forward- and back-slash in path names interchangeably, and some of them have case-insensitive file names. - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2007 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -32,20 +32,21 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #define HAVE_DOS_BASED_FILE_SYSTEM 1 #endif -#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') /* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is only semi-absolute. This is because the users of IS_ABSOLUTE_PATH want to know whether to prepend the current working directory to a file name, which should not be done with a name like d:foo. */ -#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) -#define FILENAME_CMP(s1, s2) strcasecmp(s1, s2) +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) #else /* not DOSish */ -#define IS_DIR_SEPARATOR(c) ((c) == '/') -#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) -#define FILENAME_CMP(s1, s2) strcmp(s1, s2) +#define IS_DIR_SEPARATOR(c) ((c) == '/') +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) #endif /* not DOSish */ +extern int filename_cmp (const char *s1, const char *s2); +#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2) + #endif /* FILENAMES_H */ diff --git a/support/cpp2/libiberty/fopen_unlocked.c b/support/cpp/libiberty/fopen_unlocked.c similarity index 100% rename from support/cpp2/libiberty/fopen_unlocked.c rename to support/cpp/libiberty/fopen_unlocked.c diff --git a/support/cpp2/libiberty/getpwd.c b/support/cpp/libiberty/getpwd.c similarity index 100% rename from support/cpp2/libiberty/getpwd.c rename to support/cpp/libiberty/getpwd.c diff --git a/support/cpp2/libiberty/hashtab.c b/support/cpp/libiberty/hashtab.c similarity index 100% rename from support/cpp2/libiberty/hashtab.c rename to support/cpp/libiberty/hashtab.c diff --git a/support/cpp2/libiberty/hashtab.h b/support/cpp/libiberty/hashtab.h similarity index 100% rename from support/cpp2/libiberty/hashtab.h rename to support/cpp/libiberty/hashtab.h diff --git a/support/cpp2/libiberty/hex.c b/support/cpp/libiberty/hex.c similarity index 86% rename from support/cpp2/libiberty/hex.c rename to support/cpp/libiberty/hex.c index 86ba0b5b..30046977 100644 --- a/support/cpp2/libiberty/hex.c +++ b/support/cpp/libiberty/hex.c @@ -50,7 +50,7 @@ or zero if it is not. Note that the value you pass will be cast to @deftypefn Extension {unsigned int} hex_value (int @var{c}) Returns the numeric equivalent of the given character when interpreted -as a hexidecimal digit. The result is undefined if you pass an +as a hexadecimal digit. The result is undefined if you pass an invalid hex digit. Note that the value you pass will be cast to @code{unsigned char} within the macro. @@ -164,29 +164,29 @@ hex_init (void) for (i=0; i<_hex_array_size; i++) { switch (i) - { - case '0': _hex_value[i] = 0; break; - case '1': _hex_value[i] = 1; break; - case '2': _hex_value[i] = 2; break; - case '3': _hex_value[i] = 3; break; - case '4': _hex_value[i] = 4; break; - case '5': _hex_value[i] = 5; break; - case '6': _hex_value[i] = 6; break; - case '7': _hex_value[i] = 7; break; - case '8': _hex_value[i] = 8; break; - case '9': _hex_value[i] = 9; break; - - case 'a': case 'A': _hex_value[i] = 10; break; - case 'b': case 'B': _hex_value[i] = 11; break; - case 'c': case 'C': _hex_value[i] = 12; break; - case 'd': case 'D': _hex_value[i] = 13; break; - case 'e': case 'E': _hex_value[i] = 14; break; - case 'f': case 'F': _hex_value[i] = 15; break; - - default: - _hex_value[i] = _hex_bad; - break; - } + { + case '0': _hex_value[i] = 0; break; + case '1': _hex_value[i] = 1; break; + case '2': _hex_value[i] = 2; break; + case '3': _hex_value[i] = 3; break; + case '4': _hex_value[i] = 4; break; + case '5': _hex_value[i] = 5; break; + case '6': _hex_value[i] = 6; break; + case '7': _hex_value[i] = 7; break; + case '8': _hex_value[i] = 8; break; + case '9': _hex_value[i] = 9; break; + + case 'a': case 'A': _hex_value[i] = 10; break; + case 'b': case 'B': _hex_value[i] = 11; break; + case 'c': case 'C': _hex_value[i] = 12; break; + case 'd': case 'D': _hex_value[i] = 13; break; + case 'e': case 'E': _hex_value[i] = 14; break; + case 'f': case 'F': _hex_value[i] = 15; break; + + default: + _hex_value[i] = _hex_bad; + break; + } } #endif } diff --git a/support/cpp2/libiberty/lbasename.c b/support/cpp/libiberty/lbasename.c similarity index 100% rename from support/cpp2/libiberty/lbasename.c rename to support/cpp/libiberty/lbasename.c diff --git a/support/cpp2/libiberty/md5.c b/support/cpp/libiberty/md5.c similarity index 100% rename from support/cpp2/libiberty/md5.c rename to support/cpp/libiberty/md5.c diff --git a/support/cpp2/libiberty/obstack.c b/support/cpp/libiberty/obstack.c similarity index 100% rename from support/cpp2/libiberty/obstack.c rename to support/cpp/libiberty/obstack.c diff --git a/support/cpp2/libiberty/obstack.h b/support/cpp/libiberty/obstack.h similarity index 100% rename from support/cpp2/libiberty/obstack.h rename to support/cpp/libiberty/obstack.h diff --git a/support/cpp2/libiberty/safe-ctype.c b/support/cpp/libiberty/safe-ctype.c similarity index 100% rename from support/cpp2/libiberty/safe-ctype.c rename to support/cpp/libiberty/safe-ctype.c diff --git a/support/cpp2/libiberty/safe-ctype.h b/support/cpp/libiberty/safe-ctype.h similarity index 100% rename from support/cpp2/libiberty/safe-ctype.h rename to support/cpp/libiberty/safe-ctype.h diff --git a/support/cpp2/libiberty/splay-tree.c b/support/cpp/libiberty/splay-tree.c similarity index 81% rename from support/cpp2/libiberty/splay-tree.c rename to support/cpp/libiberty/splay-tree.c index 060f900a..9eff94aa 100644 --- a/support/cpp2/libiberty/splay-tree.c +++ b/support/cpp/libiberty/splay-tree.c @@ -1,9 +1,9 @@ -/* A splay-tree datatype. +/* A splay-tree datatype. Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com). This file is part of GNU CC. - + GNU CC 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) @@ -39,16 +39,16 @@ Boston, MA 02110-1301, USA. */ static void splay_tree_delete_helper (splay_tree, splay_tree_node); static inline void rotate_left (splay_tree_node *, - splay_tree_node, splay_tree_node); + splay_tree_node, splay_tree_node); static inline void rotate_right (splay_tree_node *, - splay_tree_node, splay_tree_node); + splay_tree_node, splay_tree_node); static void splay_tree_splay (splay_tree, splay_tree_key); static int splay_tree_foreach_helper (splay_tree, splay_tree_node, splay_tree_foreach_fn, void*); /* Deallocate NODE (a member of SP), and all its sub-trees. */ -static void +static void splay_tree_delete_helper (splay_tree sp, splay_tree_node node) { splay_tree_node pending = 0; @@ -76,38 +76,38 @@ splay_tree_delete_helper (splay_tree sp, splay_tree_node node) active = pending; pending = 0; while (active) - { - splay_tree_node temp; - - /* active points to a node which has its key and value - deallocated, we just need to process left and right. */ - - if (active->left) - { - KDEL (active->left->key); - VDEL (active->left->value); - active->left->key = (splay_tree_key)pending; - pending = (splay_tree_node)(active->left); - } - if (active->right) - { - KDEL (active->right->key); - VDEL (active->right->value); - active->right->key = (splay_tree_key)pending; - pending = (splay_tree_node)(active->right); - } - - temp = active; - active = (splay_tree_node)(temp->key); - (*sp->deallocate) ((char*) temp, sp->allocate_data); - } + { + splay_tree_node temp; + + /* active points to a node which has its key and value + deallocated, we just need to process left and right. */ + + if (active->left) + { + KDEL (active->left->key); + VDEL (active->left->value); + active->left->key = (splay_tree_key)pending; + pending = (splay_tree_node)(active->left); + } + if (active->right) + { + KDEL (active->right->key); + VDEL (active->right->value); + active->right->key = (splay_tree_key)pending; + pending = (splay_tree_node)(active->right); + } + + temp = active; + active = (splay_tree_node)(temp->key); + (*sp->deallocate) ((char*) temp, sp->allocate_data); + } } #undef KDEL #undef VDEL } /* Rotate the edge joining the left child N with its parent P. PP is the - grandparents pointer to P. */ + grandparents' pointer to P. */ static inline void rotate_left (splay_tree_node *pp, splay_tree_node p, splay_tree_node n) @@ -120,7 +120,7 @@ rotate_left (splay_tree_node *pp, splay_tree_node p, splay_tree_node n) } /* Rotate the edge joining the right child N with its parent P. PP is the - grandparents pointer to P. */ + grandparents' pointer to P. */ static inline void rotate_right (splay_tree_node *pp, splay_tree_node p, splay_tree_node n) @@ -166,33 +166,33 @@ splay_tree_splay (splay_tree sp, splay_tree_key key) || (cmp2 < 0 && !c->left) || (cmp2 > 0 && !c->right)) { - if (cmp1 < 0) - rotate_left (&sp->root, n, c); - else - rotate_right (&sp->root, n, c); + if (cmp1 < 0) + rotate_left (&sp->root, n, c); + else + rotate_right (&sp->root, n, c); return; } /* Now we have the four cases of double-rotation. */ if (cmp1 < 0 && cmp2 < 0) { - rotate_left (&n->left, c, c->left); - rotate_left (&sp->root, n, n->left); + rotate_left (&n->left, c, c->left); + rotate_left (&sp->root, n, n->left); } else if (cmp1 > 0 && cmp2 > 0) { - rotate_right (&n->right, c, c->right); - rotate_right (&sp->root, n, n->right); + rotate_right (&n->right, c, c->right); + rotate_right (&sp->root, n, n->right); } else if (cmp1 < 0 && cmp2 > 0) { - rotate_right (&n->left, c, c->right); - rotate_left (&sp->root, n, n->left); + rotate_right (&n->left, c, c->right); + rotate_left (&sp->root, n, n->left); } else if (cmp1 > 0 && cmp2 < 0) { - rotate_left (&n->right, c, c->left); - rotate_right (&sp->root, n, n->right); + rotate_left (&n->right, c, c->left); + rotate_right (&sp->root, n, n->right); } } while (1); } @@ -242,7 +242,7 @@ splay_tree_xmalloc_deallocate (void *object, void *data ATTRIBUTE_UNUSED) values. Use xmalloc to allocate the splay tree structure, and any nodes added. */ -splay_tree +splay_tree splay_tree_new (splay_tree_compare_fn compare_fn, splay_tree_delete_key_fn delete_key_fn, splay_tree_delete_value_fn delete_value_fn) @@ -257,7 +257,7 @@ splay_tree_new (splay_tree_compare_fn compare_fn, DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate values. */ -splay_tree +splay_tree splay_tree_new_with_allocator (splay_tree_compare_fn compare_fn, splay_tree_delete_key_fn delete_key_fn, splay_tree_delete_value_fn delete_value_fn, @@ -280,7 +280,7 @@ splay_tree_new_with_allocator (splay_tree_compare_fn compare_fn, /* Deallocate SP. */ -void +void splay_tree_delete (splay_tree sp) { splay_tree_delete_helper (sp, sp->root); @@ -304,36 +304,36 @@ splay_tree_insert (splay_tree sp, splay_tree_key key, splay_tree_value value) if (sp->root && comparison == 0) { /* If the root of the tree already has the indicated KEY, just - replace the value with VALUE. */ + replace the value with VALUE. */ if (sp->delete_value) - (*sp->delete_value)(sp->root->value); + (*sp->delete_value)(sp->root->value); sp->root->value = value; - } - else + } + else { /* Create a new node, and insert it at the root. */ splay_tree_node node; - + node = ((splay_tree_node) (*sp->allocate) (sizeof (struct splay_tree_node_s), sp->allocate_data)); node->key = key; node->value = value; - + if (!sp->root) - node->left = node->right = 0; + node->left = node->right = 0; else if (comparison < 0) - { - node->left = sp->root; - node->right = node->left->right; - node->left->right = 0; - } + { + node->left = sp->root; + node->right = node->left->right; + node->left->right = 0; + } else - { - node->right = sp->root; - node->left = node->right->left; - node->right->left = 0; - } + { + node->right = sp->root; + node->left = node->right->left; + node->right->left = 0; + } sp->root = node; } @@ -357,30 +357,30 @@ splay_tree_remove (splay_tree sp, splay_tree_key key) /* Delete the root node itself. */ if (sp->delete_value) - (*sp->delete_value) (sp->root->value); + (*sp->delete_value) (sp->root->value); (*sp->deallocate) (sp->root, sp->allocate_data); /* One of the children is now the root. Doesn't matter much - which, so long as we preserve the properties of the tree. */ + which, so long as we preserve the properties of the tree. */ if (left) - { - sp->root = left; - - /* If there was a right child as well, hang it off the - right-most leaf of the left child. */ - if (right) - { - while (left->right) - left = left->right; - left->right = right; - } - } + { + sp->root = left; + + /* If there was a right child as well, hang it off the + right-most leaf of the left child. */ + if (right) + { + while (left->right) + left = left->right; + left->right = right; + } + } else - sp->root = right; + sp->root = right; } } -/* Lookup KEY in SP, returning VALUE if present, and NULL +/* Lookup KEY in SP, returning VALUE if present, and NULL otherwise. */ splay_tree_node @@ -508,7 +508,7 @@ splay_tree_compare_ints (splay_tree_key k1, splay_tree_key k2) return -1; else if ((int) k1 > (int) k2) return 1; - else + else return 0; } @@ -521,6 +521,6 @@ splay_tree_compare_pointers (splay_tree_key k1, splay_tree_key k2) return -1; else if ((char*) k1 > (char*) k2) return 1; - else + else return 0; } diff --git a/support/cpp2/libiberty/splay-tree.h b/support/cpp/libiberty/splay-tree.h similarity index 72% rename from support/cpp2/libiberty/splay-tree.h rename to support/cpp/libiberty/splay-tree.h index 78d8f71c..f9425db7 100644 --- a/support/cpp2/libiberty/splay-tree.h +++ b/support/cpp/libiberty/splay-tree.h @@ -1,28 +1,28 @@ -/* A splay-tree datatype. - Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +/* A splay-tree datatype. + Copyright 1998, 1999, 2000, 2002, 2007 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com). -This file is part of GCC. - -GCC 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 file is part of GCC. -GCC 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. + GCC 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. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ + GCC 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 GCC; see the file COPYING. If not, write to + the Free Software Foundation, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ /* For an easily readable description of splay-trees, see: Lewis, Harry R. and Denenberg, Larry. Data Structures and Their - Algorithms. Harper-Collins, Inc. 1991. + Algorithms. Harper-Collins, Inc. 1991. The major feature of splay trees is that all basic tree operations are amortized O(log n) time for a tree with n nodes. */ @@ -36,6 +36,14 @@ extern "C" { #include "ansidecl.h" +#ifndef _WIN64 + typedef unsigned long int libi_uhostptr_t; + typedef long int libi_shostptr_t; +#else + typedef unsigned long long libi_uhostptr_t; + typedef long long libi_shostptr_t; +#endif + #ifndef GTY #define GTY(X) #endif @@ -44,8 +52,8 @@ extern "C" { these types, if necessary. These types should be sufficiently wide that any pointer or scalar can be cast to these types, and then cast back, without loss of precision. */ -typedef unsigned long int splay_tree_key; -typedef unsigned long int splay_tree_value; +typedef libi_uhostptr_t splay_tree_key; +typedef libi_uhostptr_t splay_tree_value; /* Forward declaration for a node in the tree. */ typedef struct splay_tree_node_s *splay_tree_node; @@ -110,24 +118,24 @@ struct splay_tree_s GTY(()) splay_tree_allocate_fn allocate; splay_tree_deallocate_fn deallocate; void * GTY((skip)) allocate_data; - }; + typedef struct splay_tree_s *splay_tree; -extern splay_tree splay_tree_new (splay_tree_compare_fn, - splay_tree_delete_key_fn, - splay_tree_delete_value_fn); +extern splay_tree splay_tree_new (splay_tree_compare_fn, + splay_tree_delete_key_fn, + splay_tree_delete_value_fn); extern splay_tree splay_tree_new_with_allocator (splay_tree_compare_fn, splay_tree_delete_key_fn, - splay_tree_delete_value_fn, + splay_tree_delete_value_fn, splay_tree_allocate_fn, splay_tree_deallocate_fn, void *); -extern void splay_tree_delete (splay_tree); +extern void splay_tree_delete (splay_tree); extern splay_tree_node splay_tree_insert (splay_tree, splay_tree_key, splay_tree_value); -extern void splay_tree_remove (splay_tree, splay_tree_key); +extern void splay_tree_remove (splay_tree, splay_tree_key); extern splay_tree_node splay_tree_lookup (splay_tree, splay_tree_key); extern splay_tree_node splay_tree_predecessor (splay_tree, splay_tree_key); extern splay_tree_node splay_tree_successor (splay_tree, splay_tree_key); @@ -135,8 +143,8 @@ extern splay_tree_node splay_tree_max (splay_tree); extern splay_tree_node splay_tree_min (splay_tree); extern int splay_tree_foreach (splay_tree, splay_tree_foreach_fn, void*); extern int splay_tree_compare_ints (splay_tree_key, splay_tree_key); -extern int splay_tree_compare_pointers (splay_tree_key, splay_tree_key); - +extern int splay_tree_compare_pointers (splay_tree_key, splay_tree_key); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/support/cpp2/libiberty/vasprintf.c b/support/cpp/libiberty/vasprintf.c similarity index 100% rename from support/cpp2/libiberty/vasprintf.c rename to support/cpp/libiberty/vasprintf.c diff --git a/support/cpp2/libiberty/xexit.c b/support/cpp/libiberty/xexit.c similarity index 100% rename from support/cpp2/libiberty/xexit.c rename to support/cpp/libiberty/xexit.c diff --git a/support/cpp2/libiberty/xmalloc.c b/support/cpp/libiberty/xmalloc.c similarity index 100% rename from support/cpp2/libiberty/xmalloc.c rename to support/cpp/libiberty/xmalloc.c diff --git a/support/cpp2/libiberty/xmemdup.c b/support/cpp/libiberty/xmemdup.c similarity index 100% rename from support/cpp2/libiberty/xmemdup.c rename to support/cpp/libiberty/xmemdup.c diff --git a/support/cpp2/libiberty/xstrdup.c b/support/cpp/libiberty/xstrdup.c similarity index 100% rename from support/cpp2/libiberty/xstrdup.c rename to support/cpp/libiberty/xstrdup.c diff --git a/support/cpp2/libiberty/xstrerror.c b/support/cpp/libiberty/xstrerror.c similarity index 100% rename from support/cpp2/libiberty/xstrerror.c rename to support/cpp/libiberty/xstrerror.c diff --git a/support/cpp2/md5.h b/support/cpp/md5.h similarity index 100% rename from support/cpp2/md5.h rename to support/cpp/md5.h diff --git a/support/cpp2/move-if-change b/support/cpp/move-if-change similarity index 100% rename from support/cpp2/move-if-change rename to support/cpp/move-if-change diff --git a/support/cpp2/opt-functions.awk b/support/cpp/opt-functions.awk similarity index 100% rename from support/cpp2/opt-functions.awk rename to support/cpp/opt-functions.awk diff --git a/support/cpp2/opt-gather.awk b/support/cpp/opt-gather.awk similarity index 100% rename from support/cpp2/opt-gather.awk rename to support/cpp/opt-gather.awk diff --git a/support/cpp2/optc-gen.awk b/support/cpp/optc-gen.awk similarity index 100% rename from support/cpp2/optc-gen.awk rename to support/cpp/optc-gen.awk diff --git a/support/cpp2/opth-gen.awk b/support/cpp/opth-gen.awk similarity index 100% rename from support/cpp2/opth-gen.awk rename to support/cpp/opth-gen.awk diff --git a/support/cpp2/opts-common.c b/support/cpp/opts-common.c similarity index 100% rename from support/cpp2/opts-common.c rename to support/cpp/opts-common.c diff --git a/support/cpp2/opts.c b/support/cpp/opts.c similarity index 100% rename from support/cpp2/opts.c rename to support/cpp/opts.c diff --git a/support/cpp2/opts.h b/support/cpp/opts.h similarity index 100% rename from support/cpp2/opts.h rename to support/cpp/opts.h diff --git a/support/cpp2/output.h b/support/cpp/output.h similarity index 100% rename from support/cpp2/output.h rename to support/cpp/output.h diff --git a/support/cpp2/prefix.c b/support/cpp/prefix.c similarity index 100% rename from support/cpp2/prefix.c rename to support/cpp/prefix.c diff --git a/support/cpp2/prefix.h b/support/cpp/prefix.h similarity index 100% rename from support/cpp2/prefix.h rename to support/cpp/prefix.h diff --git a/support/cpp2/sdcpp-opts.c b/support/cpp/sdcpp-opts.c similarity index 100% rename from support/cpp2/sdcpp-opts.c rename to support/cpp/sdcpp-opts.c diff --git a/support/cpp2/sdcpp.c b/support/cpp/sdcpp.c similarity index 100% rename from support/cpp2/sdcpp.c rename to support/cpp/sdcpp.c diff --git a/support/cpp2/sdcpp.dsp b/support/cpp/sdcpp.dsp similarity index 100% rename from support/cpp2/sdcpp.dsp rename to support/cpp/sdcpp.dsp diff --git a/support/cpp2/sdcpp.h b/support/cpp/sdcpp.h similarity index 100% rename from support/cpp2/sdcpp.h rename to support/cpp/sdcpp.h diff --git a/support/cpp2/sdcpp.opt b/support/cpp/sdcpp.opt similarity index 100% rename from support/cpp2/sdcpp.opt rename to support/cpp/sdcpp.opt diff --git a/support/cpp2/sdcppa.dsp b/support/cpp/sdcppa.dsp similarity index 100% rename from support/cpp2/sdcppa.dsp rename to support/cpp/sdcppa.dsp diff --git a/support/cpp2/symcat.h b/support/cpp/symcat.h similarity index 100% rename from support/cpp2/symcat.h rename to support/cpp/symcat.h diff --git a/support/cpp2/system.h b/support/cpp/system.h similarity index 100% rename from support/cpp2/system.h rename to support/cpp/system.h diff --git a/support/cpp2/version.c b/support/cpp/version.c similarity index 100% rename from support/cpp2/version.c rename to support/cpp/version.c diff --git a/support/cpp2/version.h b/support/cpp/version.h similarity index 100% rename from support/cpp2/version.h rename to support/cpp/version.h diff --git a/support/cpp2/win32/dirent.c b/support/cpp/win32/dirent.c similarity index 100% rename from support/cpp2/win32/dirent.c rename to support/cpp/win32/dirent.c diff --git a/support/cpp2/win32/dirent.h b/support/cpp/win32/dirent.h similarity index 100% rename from support/cpp2/win32/dirent.h rename to support/cpp/win32/dirent.h -- 2.30.2