diff options
author | kan <kan@FreeBSD.org> | 2004-08-12 16:41:42 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2004-08-12 16:41:42 +0000 |
commit | d42790ccc00a70f00d10a3b8f17967a5b396bd4d (patch) | |
tree | 05895ca3fdba11097afd624bf6f64962995c416e /contrib/gcc/cp | |
parent | d42b9316c71d1b89b1b05d36be366eadf7bd8cdf (diff) | |
download | FreeBSD-src-d42790ccc00a70f00d10a3b8f17967a5b396bd4d.zip FreeBSD-src-d42790ccc00a70f00d10a3b8f17967a5b396bd4d.tar.gz |
Remove files that are not part of GCC 3.4.x from the vendor branch.
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/cfns.h | 467 | ||||
-rw-r--r-- | contrib/gcc/cp/g++.c | 582 | ||||
-rw-r--r-- | contrib/gcc/cp/lang-options.h | 159 | ||||
-rw-r--r-- | contrib/gcc/cp/parse.y | 4237 | ||||
-rw-r--r-- | contrib/gcc/cp/reno.texi | 752 | ||||
-rw-r--r-- | contrib/gcc/cp/spew.c | 1558 |
6 files changed, 0 insertions, 7755 deletions
diff --git a/contrib/gcc/cp/cfns.h b/contrib/gcc/cp/cfns.h deleted file mode 100644 index c7e6a9d..0000000 --- a/contrib/gcc/cp/cfns.h +++ /dev/null @@ -1,467 +0,0 @@ -/* C code produced by gperf version 2.7 */ -/* Command-line: gperf -o -C -E -k 1-6,$ -j1 -D -N libc_name_p ../../../egcs-CVS20000404/gcc/cp/cfns.gperf */ -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash PARAMS ((const char *, unsigned int)); -#ifdef __GNUC__ -__inline -#endif -const char * libc_name_p PARAMS ((const char *, unsigned int)); -/* maximum key range = 1020, duplicates = 1 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -hash (str, len) - register const char *str; - register unsigned int len; -{ - static const unsigned short asso_values[] = - { - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 0, 1, - 0, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 247, 218, 144, - 0, 0, 40, 7, 126, 184, 2, 15, 146, 67, - 9, 60, 0, 0, 3, 0, 7, 8, 197, 1, - 40, 8, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, - 1038, 1038, 1038, 1038, 1038, 1038 - }; - register int hval = len; - - switch (hval) - { - default: - case 6: - hval += asso_values[(unsigned char)str[5]]; - case 5: - hval += asso_values[(unsigned char)str[4]]; - case 4: - hval += asso_values[(unsigned char)str[3]]; - case 3: - hval += asso_values[(unsigned char)str[2]]; - case 2: - hval += asso_values[(unsigned char)str[1]]; - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -#ifdef __GNUC__ -__inline -#endif -const char * -libc_name_p (str, len) - register const char *str; - register unsigned int len; -{ - enum - { - TOTAL_KEYWORDS = 207, - MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 10, - MIN_HASH_VALUE = 18, - MAX_HASH_VALUE = 1037 - }; - - static const char * const wordlist[] = - { - "gets", - "puts", - "sqrt", - "strerror", - "strstr", - "strspn", - "exp", - "free", - "fgets", - "fputs", - "fgetws", - "fputws", - "pow", - "fseek", - "perror", - "strtod", - "toupper", - "towupper", - "frexp", - "strtok", - "fsetpos", - "ferror", - "freopen", - "fgetpos", - "fopen", - "wmemset", - "memset", - "system", - "wcsstr", - "wctype", - "strxfrm", - "wcsspn", - "strcspn", - "fmod", - "strcpy", - "strncpy", - "strlen", - "ungetwc", - "feof", - "ldexp", - "isupper", - "rewind", - "iswupper", - "sin", - "cos", - "modf", - "iswpunct", - "wcstod", - "log10", - "log", - "wcsrtombs", - "strcmp", - "fwide", - "towctrans", - "strncmp", - "strtoul", - "fwrite", - "exit", - "swprintf", - "wcstok", - "strftime", - "sprintf", - "wprintf", - "strpbrk", - "time", - "rand", - "srand", - "wmemmove", - "tan", - "tolower", - "fwprintf", - "towlower", - "wcstombs", - "printf", - "fprintf", - "strchr", - "strrchr", - "wmemcpy", - "fread", - "getwchar", - "putwchar", - "longjmp", - "memcpy", - "wcsxfrm", - "wcscspn", - "getc", - "putc", - "getwc", - "putwc", - "wcscpy", - "wcsncpy", - "wcslen", - "floor", - "setbuf", - "ungetc", - "rename", - "remove", - "gmtime", - "mktime", - "fgetc", - "fputc", - "fgetwc", - "fputwc", - "memcmp", - "iswctype", - "wmemcmp", - "ispunct", - "mbstowcs", - "wcscmp", - "mbsrtowcs", - "setlocale", - "wcsncmp", - "wcstoul", - "strtol", - "wcsftime", - "iswprint", - "wcspbrk", - "iswdigit", - "isprint", - "fclose", - "atof", - "islower", - "iswlower", - "ctime", - "wmemchr", - "memchr", - "wctrans", - "strcat", - "getenv", - "strncat", - "iswxdigit", - "wcschr", - "wcsrchr", - "isxdigit", - "vswprintf", - "raise", - "iswspace", - "vsprintf", - "vwprintf", - "vprintf", - "swscanf", - "sinh", - "tmpfile", - "asin", - "mblen", - "acos", - "mbrlen", - "cosh", - "difftime", - "memmove", - "abs", - "tmpnam", - "vfwprintf", - "setvbuf", - "vfprintf", - "scanf", - "sscanf", - "wscanf", - "fwscanf", - "ftell", - "fflush", - "atexit", - "iswcntrl", - "iscntrl", - "mbrtowc", - "wcrtomb", - "fabs", - "wcstol", - "strcoll", - "atan2", - "tanh", - "atan", - "fscanf", - "clock", - "getchar", - "putchar", - "abort", - "clearerr", - "wcscat", - "wcsncat", - "isdigit", - "isgraph", - "iswgraph", - "btowc", - "div", - "isspace", - "atol", - "labs", - "ceil", - "mbtowc", - "wcscoll", - "wctob", - "asctime", - "iswalnum", - "isalnum", - "mbsinit", - "atoi", - "wctomb", - "ldiv", - "signal", - "realloc", - "localtime", - "iswalpha", - "localeconv", - "isalpha", - "malloc", - "calloc" - }; - - static const short lookup[] = - { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 0, 1, -1, 2, -1, -1, - -1, -1, -1, 3, -1, 4, -1, -1, - -1, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, 6, -1, -1, -1, 7, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, 9, 10, 11, -1, - -1, 12, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 13, -1, -1, 14, -1, - -1, -1, -1, 15, -1, 16, -1, 17, - 18, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, -1, -1, -1, 21, 22, - -1, 23, -1, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 25, -1, -1, - -1, -1, 26, 27, -1, -1, -1, -1, - -1, -1, -1, -1, 28, -1, 29, 30, - -1, 31, 32, 33, -1, -1, -1, -1, - 34, -1, 35, -1, 36, -1, -1, 37, - 38, -1, -1, -1, -1, -1, -1, 39, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 40, 41, 42, 43, -1, 44, - -1, -1, -1, 45, -1, -1, -1, -1, - -1, 46, 47, 48, -1, -1, -1, 49, - 50, -1, -1, 51, -1, -1, 52, 53, - -1, -1, -1, -1, -1, 54, 55, -1, - -1, 56, 57, -1, -1, 58, -1, -1, - 59, 60, 61, 62, -1, 63, -1, -1, - -1, -1, -1, -1, -1, -1, 64, 65, - 66, -1, -1, -1, -1, -1, 67, -1, - -1, -1, -1, 68, -1, -1, -1, -1, - -1, -1, -1, -1, 69, 70, 71, 72, - -1, 73, 74, -1, 75, 76, 77, 78, - 79, 80, 81, -1, 82, -1, 83, -1, - -1, 84, 85, 86, 87, 88, -1, 89, - -1, 90, -1, 91, -1, 92, -1, 93, - -1, -1, -1, -1, -1, 94, -1, -1, - -1, -1, -1, -1, 95, 96, -1, -1, - -1, -1, 97, -1, -1, -1, -1, -1, - -1, -1, 98, 99, 100, 101, 102, 103, - 104, 105, -1, -1, -1, -1, -1, 106, - -1, 107, 108, -1, 109, -1, 110, -1, - -1, -1, -1, -1, 111, 112, -1, 113, - -1, -1, -1, -1, -1, -1, -1, -1, - 114, -1, -1, 115, 116, -1, -1, 117, - -1, -1, 118, -1, 119, -1, 120, -1, - -1, 121, -1, 122, -1, -1, -1, 123, - -1, -1, -1, -1, -1, -1, -1, 124, - 125, -1, 126, -1, -1, 127, -1, 128, - 129, 130, -1, 131, 132, -1, 133, -1, - -1, -1, 134, -1, -1, -1, -1, 135, - 136, 137, 138, -1, -1, -1, -1, 139, - 140, 141, -1, 142, -1, 143, 144, 145, - -1, -1, 146, -1, 147, -1, -1, 148, - -1, 149, -1, -1, 150, -1, 151, -1, - -1, -1, 152, -1, -1, 153, -1, -1, - -1, 154, -1, -1, -1, 155, 156, 157, - 158, -1, 159, -1, 160, -1, -1, -1, - -1, -1, 161, 162, 163, -1, -1, -1, - -1, -1, -1, -719, -1, 166, 167, -43, - -2, 168, -1, 169, -1, -1, -1, 170, - -1, -1, -1, 171, -1, -1, 172, -1, - -1, 173, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 174, 175, -1, - -1, -1, -1, 176, -1, -1, -1, 177, - -1, -1, -1, -1, 178, -1, -1, 179, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 180, 181, -1, - 182, -1, -1, 183, -1, 184, 185, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 186, -1, -1, -1, -1, 187, - -1, -1, -1, -1, -1, -1, -1, -1, - 188, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 189, - 190, -1, -1, -1, -1, 191, -1, -1, - 192, -1, -1, -1, -1, -1, 193, -1, - -1, -1, -1, -1, 194, -1, -1, -1, - -1, -1, -1, -1, 195, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 196, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 197, -1, -1, -1, -1, -1, -1, - 198, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 199, -1, -1, -1, -1, -1, -1, - -1, 200, -1, -1, -1, -1, -1, 201, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, 202, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 203, -1, - -1, -1, -1, -1, -1, 204, -1, -1, - 205, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 206 - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int index = lookup[key]; - - if (index >= 0) - { - register const char *s = wordlist[index]; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return s; - } - else if (index < -TOTAL_KEYWORDS) - { - register int offset = - 1 - TOTAL_KEYWORDS - index; - register const char * const *wordptr = &wordlist[TOTAL_KEYWORDS + lookup[offset]]; - register const char * const *wordendptr = wordptr + -lookup[offset + 1]; - - while (wordptr < wordendptr) - { - register const char *s = *wordptr; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return s; - wordptr++; - } - } - } - } - return 0; -} diff --git a/contrib/gcc/cp/g++.c b/contrib/gcc/cp/g++.c deleted file mode 100644 index f694898..0000000 --- a/contrib/gcc/cp/g++.c +++ /dev/null @@ -1,582 +0,0 @@ -/* G++ preliminary semantic processing for the compiler driver. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Contributed by Brendan Kehoe (brendan@cygnus.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) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This program is a wrapper to the main `gcc' driver. For GNU C++, - we need to do two special things: a) append `-lg++' in situations - where it's appropriate, to link in libg++, and b) add `-xc++'..`-xnone' - around file arguments named `foo.c' or `foo.i'. So, we do all of - this semantic processing then just exec gcc with the new argument - list. - - We used to do all of this in a small shell script, but many users - found the performance of this as a shell script to be unacceptable. - In situations where your PATH has a lot of NFS-mounted directories, - using a script that runs sed and other things would be a nasty - performance hit. With this program, we never search the PATH at all. */ - -#include "config.h" -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include <stdio.h> -#include <sys/types.h> -#if !defined(_WIN32) -#include <sys/file.h> /* May get R_OK, etc. on some systems. */ -#else -#include <process.h> -#endif -#include <errno.h> - -/* Defined to the name of the compiler; if using a cross compiler, the - Makefile should compile this file with the proper name - (e.g., "i386-aout-gcc"). */ -#ifndef GCC_NAME -#define GCC_NAME "gcc" -#endif - -/* This bit is set if we saw a `-xfoo' language specification. */ -#define LANGSPEC (1<<1) -/* This bit is set if they did `-lm' or `-lmath'. */ -#define MATHLIB (1<<2) - -#ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" -#endif - -/* On MSDOS, write temp files in current dir - because there's no place else we can expect to use. */ -#ifdef __MSDOS__ -#ifndef P_tmpdir -#define P_tmpdir "." -#endif -#ifndef R_OK -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#endif -#endif - -#ifndef VPROTO -#ifdef __STDC__ -#define PVPROTO(ARGS) ARGS -#define VPROTO(ARGS) ARGS -#define VA_START(va_list,var) va_start(va_list,var) -#else -#define PVPROTO(ARGS) () -#define VPROTO(ARGS) (va_alist) va_dcl -#define VA_START(va_list,var) va_start(va_list) -#endif -#endif - -#ifndef errno -extern int errno; -#endif - -extern int sys_nerr; -#ifndef HAVE_STRERROR -#if defined(bsd4_4) -extern const char *const sys_errlist[]; -#else -extern char *sys_errlist[]; -#endif -#else -extern char *strerror(); -#endif - -/* Name with which this program was invoked. */ -static char *programname; - -char * -my_strerror(e) - int e; -{ - -#ifdef HAVE_STRERROR - return strerror(e); - -#else - - static char buffer[30]; - if (!e) - return ""; - - if (e > 0 && e < sys_nerr) - return sys_errlist[e]; - - sprintf (buffer, "Unknown error %d", e); - return buffer; -#endif -} - -#ifdef HAVE_VPRINTF -/* Output an error message and exit */ - -static void -fatal VPROTO((char *format, ...)) -{ -#ifndef __STDC__ - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef __STDC__ - format = va_arg (ap, char*); -#endif - - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, format, ap); - va_end (ap); - fprintf (stderr, "\n"); -#if 0 - /* XXX Not needed for g++ driver. */ - delete_temp_files (); -#endif - exit (1); -} - -static void -error VPROTO((char *format, ...)) -{ -#ifndef __STDC__ - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef __STDC__ - format = va_arg (ap, char*); -#endif - - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, format, ap); - va_end (ap); - - fprintf (stderr, "\n"); -} - -#else /* not HAVE_VPRINTF */ - -static void -error (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - fprintf (stderr, "%s: ", programname); - fprintf (stderr, msg, arg1, arg2); - fprintf (stderr, "\n"); -} - -static void -fatal (msg, arg1, arg2) - char *msg, *arg1, *arg2; -{ - error (msg, arg1, arg2); -#if 0 - /* XXX Not needed for g++ driver. */ - delete_temp_files (); -#endif - exit (1); -} - -#endif /* not HAVE_VPRINTF */ - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal g++ abort."); -} - -char * -xmalloc (size) - unsigned size; -{ - register char *value = (char *) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -/* Return a newly-allocated string whose contents concatenate those - of s1, s2, s3. */ -static char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - *(result + len1 + len2 + len3) = 0; - - return result; -} - -static void -pfatal_with_name (name) - char *name; -{ - fatal (concat ("%s: ", my_strerror (errno), ""), name); -} - -#ifdef __MSDOS__ -/* This is the common prefix we use to make temp file names. */ -char *temp_filename; - -/* Length of the prefix. */ -int temp_filename_length; - -/* Compute a string to use as the base of all temporary file names. */ -static char * -choose_temp_base_try (try, base) -char *try; -char *base; -{ - char *rv; - if (base) - rv = base; - else if (try == (char *)0) - rv = 0; - else if (access (try, R_OK | W_OK) != 0) - rv = 0; - else - rv = try; - return rv; -} - -static void -choose_temp_base () -{ - char *base = 0; - int len; - - base = choose_temp_base_try (getenv ("TMPDIR"), base); - base = choose_temp_base_try (getenv ("TMP"), base); - base = choose_temp_base_try (getenv ("TEMP"), base); - -#ifdef P_tmpdir - base = choose_temp_base_try (P_tmpdir, base); -#endif - - base = choose_temp_base_try ("/usr/tmp", base); - base = choose_temp_base_try ("/tmp", base); - - /* If all else fails, use the current directory! */ - if (base == (char *)0) - base = "./"; - - len = strlen (base); - temp_filename = xmalloc (len + sizeof("/ccXXXXXX")); - strcpy (temp_filename, base); - if (len > 0 && temp_filename[len-1] != '/') - temp_filename[len++] = '/'; - strcpy (temp_filename + len, "ccXXXXXX"); - - mktemp (temp_filename); - temp_filename_length = strlen (temp_filename); - if (temp_filename_length == 0) - abort (); -} - -static void -perror_exec (name) - char *name; -{ - char *s; - - if (errno < sys_nerr) - s = concat ("installation problem, cannot exec %s: ", - my_strerror( errno ), ""); - else - s = "installation problem, cannot exec %s"; - error (s, name); -} - -/* This is almost exactly what's in gcc.c:pexecute for MSDOS. */ -void -run_dos (program, argv) - char *program; - char *argv[]; -{ - char *scmd, *rf; - FILE *argfile; - int i; - - choose_temp_base (); /* not in gcc.c */ - - scmd = (char *) malloc (strlen (program) + strlen (temp_filename) + 10); - rf = scmd + strlen (program) + 6; - sprintf (scmd, "%s.exe @%s.gp", program, temp_filename); - - argfile = fopen (rf, "w"); - if (argfile == 0) - pfatal_with_name (rf); - - for (i=1; argv[i]; i++) - { - char *cp; - for (cp = argv[i]; *cp; cp++) - { - if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) - fputc ('\\', argfile); - fputc (*cp, argfile); - } - fputc ('\n', argfile); - } - fclose (argfile); - - i = system (scmd); - - remove (rf); - - if (i == -1) - perror_exec (program); -} -#endif /* __MSDOS__ */ - -int -main (argc, argv) - int argc; - char **argv; -{ - register int i, j = 0; - register char *p; - int verbose = 0; - - /* This will be 0 if we encounter a situation where we should not - link in libstdc++, or 2 if we should link in libg++ as well. */ - int library = 1; - - /* Used to track options that take arguments, so we don't go wrapping - those with -xc++/-xnone. */ - char *quote = NULL; - - /* The new argument list will be contained in this. */ - char **arglist; - - /* The name of the compiler we will want to run---by default, it - will be the definition of `GCC_NAME', e.g., `gcc'. */ - char *gcc = GCC_NAME; - - /* Non-zero if we saw a `-xfoo' language specification on the - command line. Used to avoid adding our own -xc++ if the user - already gave a language for the file. */ - int saw_speclang = 0; - - /* Non-zero if we saw `-lm' or `-lmath' on the command line. */ - char *saw_math = 0; - - /* The number of arguments being added to what's in argv, other than - libraries. We use this to track the number of times we've inserted - -xc++/-xnone. */ - int added = 0; - - /* An array used to flag each argument that needs a bit set for - LANGSPEC or MATHLIB. */ - int *args; - - p = argv[0] + strlen (argv[0]); - - /* If we're called as g++ (or i386-aout-g++), link in libg++ as well. */ - - if (strcmp (p - 3, "g++") == 0) - { - library = 2; - } - - while (p != argv[0] && p[-1] != '/') - --p; - programname = p; - - if (argc == 1) - fatal ("No input files specified.\n"); - -#ifndef __MSDOS__ - /* We do a little magic to find out where the main gcc executable - is. If they ran us as /usr/local/bin/g++, then we will look - for /usr/local/bin/gcc; similarly, if they just ran us as `g++', - we'll just look for `gcc'. */ - if (p != argv[0]) - { - *--p = '\0'; - gcc = (char *) malloc ((strlen (argv[0]) + 1 + strlen (GCC_NAME) + 1) - * sizeof (char)); - sprintf (gcc, "%s/%s", argv[0], GCC_NAME); - } -#endif - - args = (int *) malloc (argc * sizeof (int)); - bzero ((char *) args, argc * sizeof (int)); - - for (i = 1; i < argc; i++) - { - /* If the previous option took an argument, we swallow it here. */ - if (quote) - { - quote = NULL; - continue; - } - - if (argv[i][0] == '\0' || argv[i][1] == '\0') - continue; - - if (argv[i][0] == '-') - { - if (library != 0 && strcmp (argv[i], "-nostdlib") == 0) - { - library = 0; - } - else if (strcmp (argv[i], "-lm") == 0 - || strcmp (argv[i], "-lmath") == 0) - args[i] |= MATHLIB; - else if (strcmp (argv[i], "-v") == 0) - { - verbose = 1; - if (argc == 2) - { - /* If they only gave us `-v', don't try to link - in libg++. */ - library = 0; - } - } - else if (strncmp (argv[i], "-x", 2) == 0) - saw_speclang = 1; - else if (((argv[i][2] == '\0' - && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) - || strcmp (argv[i], "-Tdata") == 0)) - quote = argv[i]; - else if (library != 0 && ((argv[i][2] == '\0' - && (char *) strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0)) - { - /* Don't specify libraries if we won't link, since that would - cause a warning. */ - library = 0; - } - else - /* Pass other options through. */ - continue; - } - else - { - int len; - - if (saw_speclang) - { - saw_speclang = 0; - continue; - } - - /* If the filename ends in .c or .i, put options around it. - But not if a specified -x option is currently active. */ - len = strlen (argv[i]); - if (len > 2 - && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i') - && argv[i][len - 2] == '.') - { - args[i] |= LANGSPEC; - added += 2; - } - } - } - - if (quote) - fatal ("argument to `%s' missing\n", quote); - - if (added || library) - { - arglist = (char **) malloc ((argc + added + 4) * sizeof (char *)); - - for (i = 1, j = 1; i < argc; i++, j++) - { - arglist[j] = argv[i]; - - /* Make sure -lg++ is before the math library, since libg++ - itself uses those math routines. */ - if (!saw_math && (args[i] & MATHLIB) && library) - { - --j; - saw_math = argv[i]; - } - - /* Wrap foo.c and foo.i files in a language specification to - force the gcc compiler driver to run cc1plus on them. */ - if (args[i] & LANGSPEC) - { - int len = strlen (argv[i]); - if (argv[i][len - 1] == 'i') - arglist[j++] = "-xc++-cpp-output"; - else - arglist[j++] = "-xc++"; - arglist[j++] = argv[i]; - arglist[j] = "-xnone"; - } - } - - /* Add `-lg++' if we haven't already done so. */ - if (library == 2) - arglist[j++] = "-lg++"; - if (library) - arglist[j++] = "-lstdc++"; - if (saw_math) - arglist[j++] = saw_math; - else if (library) - arglist[j++] = MATH_LIBRARY; - - arglist[j] = NULL; - } - else - /* No need to copy 'em all. */ - arglist = argv; - - arglist[0] = gcc; - - if (verbose) - { - if (j == 0) - j = argc; - - for (i = 0; i < j; i++) - fprintf (stderr, " %s", arglist[i]); - fprintf (stderr, "\n"); - } -#if !defined(OS2) && !defined (_WIN32) -#ifdef __MSDOS__ - run_dos (gcc, arglist); -#else /* !__MSDOS__ */ - if (execvp (gcc, arglist) < 0) - pfatal_with_name (gcc); -#endif /* __MSDOS__ */ -#else /* OS2 or _WIN32 */ - if (spawnvp (1, gcc, arglist) < 0) - pfatal_with_name (gcc); -#endif - - return 0; -} diff --git a/contrib/gcc/cp/lang-options.h b/contrib/gcc/cp/lang-options.h deleted file mode 100644 index d4748be..0000000 --- a/contrib/gcc/cp/lang-options.h +++ /dev/null @@ -1,159 +0,0 @@ -/* Definitions for switches for C++. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - -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) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -DEFINE_LANG_NAME ("C++") - -/* This is the contribution to the `documented_lang_options' array in - toplev.c for g++. */ - - { "-faccess-control", "" }, - { "-fno-access-control", - N_("Do not obey access control semantics") }, - { "-falt-external-templates", - N_("Change when template instances are emitted") }, - { "-fno-alt-external-templates", "" }, - { "-fansi-overloading", "" }, - { "-fno-ansi-overloading", "" }, - { "-fcheck-new", - N_("Check the return value of new") }, - { "-fno-check-new", "" }, - { "-fconserve-space", - N_("Reduce size of object files") }, - { "-fno-conserve-space", "" }, - { "-fconst-strings", "" }, - { "-fno-const-strings", - N_("Make string literals `char[]' instead of `const char[]'") }, - { "-fdefault-inline", "" }, - { "-fdump-translation-unit-", - N_("Dump the entire translation unit to a file") }, - { "-fno-default-inline", - N_("Do not inline member functions by default") }, - { "-frtti", "" }, - { "-fno-rtti", - N_("Do not generate run time type descriptor information") }, - { "-felide-constructors", "" }, - { "-fno-elide-constructors", "" }, - { "-fenforce-eh-specs", "" }, - { "-fno-enforce-eh-specs", - N_("Do not generate code to check exception specifications") }, - { "-fexternal-templates", "" }, - { "-fno-external-templates", "" }, - { "-ffor-scope", "" }, - { "-fno-for-scope", - N_("Scope of for-init-statement vars extends outside") }, - { "-fgnu-keywords", "" }, - { "-fno-gnu-keywords", - N_("Do not recognize GNU defined keywords") }, - { "-fhandle-exceptions", "" }, - { "-fno-handle-exceptions", "" }, - { "-fhuge-objects", - N_("Enable support for huge objects") }, - { "-fno-huge-objects", "" }, - { "-fimplement-inlines", "" }, - { "-fno-implement-inlines", - N_("Export functions even if they can be inlined") }, - { "-fimplicit-templates", "" }, - { "-fno-implicit-templates", - N_("Only emit explicit template instantiations") }, - { "-fimplicit-inline-templates", "" }, - { "-fno-implicit-inline-templates", - N_("Only emit explicit instantiations of inline templates") }, - { "-finit-priority", "" }, - { "-fno-init-priority", "" }, - { "-fmemoize-lookups", "" }, - { "-fno-memoize-lookups", "" }, - { "-fms-extensions", - N_("Don't pedwarn about uses of Microsoft extensions") }, - { "-fno-ms-extensions", "" }, - { "-foperator-names", - N_("Recognize and/bitand/bitor/compl/not/or/xor") }, - { "-fno-operator-names", "" }, - { "-foptional-diags", "" }, - { "-fno-optional-diags", - N_("Disable optional diagnostics") }, - { "-fpermissive", - N_("Downgrade conformance errors to warnings") }, - { "-fno-permissive", "" }, - { "-frepo", - N_("Enable automatic template instantiation") }, - { "-fno-repo", "" }, - { "-fsave-memoized", "" }, - { "-fno-save-memoized", "" }, - { "-fstats", - N_("Display statistics accumulated during compilation") }, - { "-fno-stats", "" }, - { "-ftemplate-depth-", - N_("Specify maximum template instantiation depth") }, - { "-fuse-cxa-atexit", - N_("Use __cxa_atexit to register destructors") }, - { "-fno-use-cxa-atexit", "" }, - { "-fvtable-gc", - N_("Discard unused virtual functions") }, - { "-fno-vtable-gc", "" }, - { "-fvtable-thunks", - N_("Implement vtables using thunks") }, - { "-fno-vtable-thunks", "" }, - { "-fweak", - N_("Emit common-like symbols as weak symbols") }, - { "-fno-weak", "" }, - { "-fxref", - N_("Emit cross referencing information") }, - { "-fno-xref", "" }, - - { "-Wreturn-type", - N_("Warn about inconsistent return types") }, - { "-Wno-return-type", "" }, - { "-Woverloaded-virtual", - N_("Warn about overloaded virtual function names") }, - { "-Wno-overloaded-virtual", "" }, - { "-Wctor-dtor-privacy", "" }, - { "-Wno-ctor-dtor-privacy", - N_("Don't warn when all ctors/dtors are private") }, - { "-Wnon-virtual-dtor", - N_("Warn about non virtual destructors") }, - { "-Wno-non-virtual-dtor", "" }, - { "-Wextern-inline", - N_("Warn when a function is declared extern, then inline") }, - { "-Wno-extern-inline", "" }, - { "-Wreorder", - N_("Warn when the compiler reorders code") }, - { "-Wno-reorder", "" }, - { "-Wsynth", - N_("Warn when synthesis behavior differs from Cfront") }, - { "-Wno-synth", "" }, - { "-Wpmf-conversions", "" }, - { "-Wno-pmf-conversions", - N_("Don't warn when type converting pointers to member functions") }, - { "-Weffc++", - N_("Warn about violations of Effective C++ style rules") }, - { "-Wno-effc++", "" }, - { "-Wsign-promo", - N_("Warn when overload promotes from unsigned to signed") }, - { "-Wno-sign-promo", "" }, - { "-Wold-style-cast", - N_("Warn if a C style cast is used in a program") }, - { "-Wno-old-style-cast", "" }, - { "-Wnon-template-friend", "" }, - { "-Wno-non-template-friend", - N_("Don't warn when non-templatized friend functions are declared within a template") }, - { "-Wdeprecated", "" }, - { "-Wno-deprecated", - N_("Don't announce deprecation of compiler features") }, diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y deleted file mode 100644 index 157a210..0000000 --- a/contrib/gcc/cp/parse.y +++ /dev/null @@ -1,4237 +0,0 @@ -/* YACC parser for C++ syntax. - Copyright (C) 1988, 1989, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.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) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This grammar is based on the GNU CC grammar. */ - -/* Note: Bison automatically applies a default action of "$$ = $1" for - all derivations; this is applied before the explicit action, if one - is given. Keep this in mind when reading the actions. */ - -%{ -#include "config.h" - -#include "system.h" - -#include "tree.h" -#include "input.h" -#include "flags.h" -#include "cp-tree.h" -#include "decl.h" -#include "lex.h" -#include "c-pragma.h" /* For YYDEBUG definition. */ -#include "output.h" -#include "except.h" -#include "toplev.h" -#include "ggc.h" - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -/* Like the default stack expander, except (1) use realloc when possible, - (2) impose no hard maxiumum on stack size, (3) REALLY do not use alloca. - - Irritatingly, YYSTYPE is defined after this %{ %} block, so we cannot - give malloced_yyvs its proper type. This is ok since all we need from - it is to be able to free it. */ - -static short *malloced_yyss; -static void *malloced_yyvs; -static int class_template_ok_as_expr; - -#define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \ -do { \ - size_t newsize; \ - short *newss; \ - YYSTYPE *newvs; \ - newsize = *(YYSSZ) *= 2; \ - if (malloced_yyss) \ - { \ - newss = (short *) \ - really_call_realloc (*(SS), newsize * sizeof (short)); \ - newvs = (YYSTYPE *) \ - really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ - } \ - else \ - { \ - newss = (short *) really_call_malloc (newsize * sizeof (short)); \ - newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \ - if (newss) \ - memcpy (newss, *(SS), (SSSIZE)); \ - if (newvs) \ - memcpy (newvs, *(VS), (VSSIZE)); \ - } \ - if (!newss || !newvs) \ - { \ - yyerror (MSG); \ - return 2; \ - } \ - *(SS) = newss; \ - *(VS) = newvs; \ - malloced_yyss = newss; \ - malloced_yyvs = (void *) newvs; \ -} while (0) -#define OP0(NODE) (TREE_OPERAND (NODE, 0)) -#define OP1(NODE) (TREE_OPERAND (NODE, 1)) - -/* Contains the statement keyword (if/while/do) to include in an - error message if the user supplies an empty conditional expression. */ -static const char *cond_stmt_keyword; - -/* List of types and structure classes of the current declaration. */ -static GTY(()) tree current_declspecs; - -/* List of prefix attributes in effect. - Prefix attributes are parsed by the reserved_declspecs and declmods - rules. They create a list that contains *both* declspecs and attrs. */ -/* ??? It is not clear yet that all cases where an attribute can now appear in - a declspec list have been updated. */ -static GTY(()) tree prefix_attributes; - -/* When defining an enumeration, this is the type of the enumeration. */ -static GTY(()) tree current_enum_type; - -/* When parsing a conversion operator name, this is the scope of the - operator itself. */ -static GTY(()) tree saved_scopes; - -static tree empty_parms PARAMS ((void)); -static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int)); -static tree parse_decl PARAMS ((tree, tree, int)); -static void parse_end_decl PARAMS ((tree, tree, tree)); -static tree parse_field0 PARAMS ((tree, tree, tree, tree, tree, tree)); -static tree parse_field PARAMS ((tree, tree, tree, tree)); -static tree parse_bitfield0 PARAMS ((tree, tree, tree, tree, tree)); -static tree parse_bitfield PARAMS ((tree, tree, tree)); -static tree parse_method PARAMS ((tree, tree, tree)); -static void frob_specs PARAMS ((tree, tree)); -static void check_class_key PARAMS ((tree, tree)); -static tree parse_scoped_id PARAMS ((tree)); -static tree parse_xref_tag (tree, tree, int); -static tree parse_handle_class_head (tree, tree, tree, int, int *); -static void parse_decl_instantiation (tree, tree, tree); -static int parse_begin_function_definition (tree, tree); -static tree parse_finish_call_expr (tree, tree, int); - -/* Cons up an empty parameter list. */ -static inline tree -empty_parms () -{ - tree parms; - -#ifndef NO_IMPLICIT_EXTERN_C - if (in_system_header && current_class_type == NULL - && current_lang_name == lang_name_c) - parms = NULL_TREE; - else -#endif - parms = void_list_node; - return parms; -} - -/* Record the decl-specifiers, attributes and type lookups from the - decl-specifier-seq in a declaration. */ - -static void -frob_specs (specs_attrs, lookups) - tree specs_attrs, lookups; -{ - save_type_access_control (lookups); - split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); - if (current_declspecs - && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = build_tree_list (NULL_TREE, current_declspecs); - if (have_extern_spec) - { - /* We have to indicate that there is an "extern", but that it - was part of a language specifier. For instance, - - extern "C" typedef int (*Ptr) (); - - is well formed. */ - current_declspecs = tree_cons (error_mark_node, - get_identifier ("extern"), - current_declspecs); - have_extern_spec = false; - } -} - -static tree -parse_decl (declarator, attributes, initialized) - tree declarator, attributes; - int initialized; -{ - return start_decl (declarator, current_declspecs, initialized, - attributes, prefix_attributes); -} - -static tree -parse_decl0 (declarator, specs_attrs, lookups, attributes, initialized) - tree declarator, specs_attrs, lookups, attributes; - int initialized; -{ - frob_specs (specs_attrs, lookups); - return parse_decl (declarator, attributes, initialized); -} - -static void -parse_end_decl (decl, init, asmspec) - tree decl, init, asmspec; -{ - /* If decl is NULL_TREE, then this was a variable declaration using - () syntax for the initializer, so we handled it in grokdeclarator. */ - if (decl) - decl_type_access_control (decl); - cp_finish_decl (decl, init, asmspec, init ? LOOKUP_ONLYCONVERTING : 0); -} - -static tree -parse_field (declarator, attributes, asmspec, init) - tree declarator, attributes, asmspec, init; -{ - tree d = grokfield (declarator, current_declspecs, init, asmspec, - chainon (attributes, prefix_attributes)); - decl_type_access_control (d); - return d; -} - -static tree -parse_field0 (declarator, specs_attrs, lookups, attributes, asmspec, init) - tree declarator, specs_attrs, lookups, attributes, asmspec, init; -{ - frob_specs (specs_attrs, lookups); - return parse_field (declarator, attributes, asmspec, init); -} - -static tree -parse_bitfield (declarator, attributes, width) - tree declarator, attributes, width; -{ - tree d = grokbitfield (declarator, current_declspecs, width); - cplus_decl_attributes (&d, chainon (attributes, prefix_attributes), 0); - decl_type_access_control (d); - return d; -} - -static tree -parse_bitfield0 (declarator, specs_attrs, lookups, attributes, width) - tree declarator, specs_attrs, lookups, attributes, width; -{ - frob_specs (specs_attrs, lookups); - return parse_bitfield (declarator, attributes, width); -} - -static tree -parse_method (declarator, specs_attrs, lookups) - tree declarator, specs_attrs, lookups; -{ - tree d; - frob_specs (specs_attrs, lookups); - d = start_method (current_declspecs, declarator, prefix_attributes); - decl_type_access_control (d); - return d; -} - -static void -check_class_key (key, aggr) - tree key; - tree aggr; -{ - if (TREE_CODE (key) == TREE_LIST) - key = TREE_VALUE (key); - if ((key == union_type_node) != (TREE_CODE (aggr) == UNION_TYPE)) - pedwarn ("`%s' tag used in naming `%#T'", - key == union_type_node ? "union" - : key == record_type_node ? "struct" : "class", aggr); -} - -%} - -%start program - -%union { GTY(()) - long itype; - tree ttype; - char *strtype; - enum tree_code code; - flagged_type_tree ftype; - struct unparsed_text *pi; -} - -/* All identifiers that are not reserved words - and are not declared typedefs in the current block */ -%token IDENTIFIER - -/* All identifiers that are declared typedefs in the current block. - In some contexts, they are treated just like IDENTIFIER, - but they can also serve as typespecs in declarations. */ -%token tTYPENAME -%token SELFNAME - -/* A template function. */ -%token PFUNCNAME - -/* Reserved words that specify storage class. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token SCSPEC - -/* Reserved words that specify type. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token TYPESPEC - -/* Reserved words that qualify type: "const" or "volatile". - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token CV_QUALIFIER - -/* Character or numeric constants. - yylval is the node for the constant. */ -%token CONSTANT - -/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token <ttype> VAR_FUNC_NAME - -/* String constants in raw form. - yylval is a STRING_CST node. */ -%token STRING - -/* "...", used for functions with variable arglists. */ -%token ELLIPSIS - -/* the reserved words */ -/* SCO include files test "ASM", so use something else. */ -%token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT -%token BREAK CONTINUE RETURN_KEYWORD GOTO ASM_KEYWORD TYPEOF ALIGNOF -%token SIGOF -%token ATTRIBUTE EXTENSION LABEL -%token REALPART IMAGPART VA_ARG - -/* the reserved words... C++ extensions */ -%token <ttype> AGGR -%token <ttype> VISSPEC -%token DELETE NEW THIS OPERATOR CXX_TRUE CXX_FALSE -%token NAMESPACE TYPENAME_KEYWORD USING -%token LEFT_RIGHT TEMPLATE -%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST -%token SCOPE EXPORT - -/* Define the operator tokens and their precedences. - The value is an integer because, if used, it is the tree code - to use in the expression made from the operator. */ - -%left EMPTY /* used to resolve s/r with epsilon */ - -%left error - -/* Add precedence rules to solve dangling else s/r conflict */ -%nonassoc IF -%nonassoc ELSE - -%left IDENTIFIER PFUNCNAME tTYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE - -%left '{' ',' ';' - -%nonassoc THROW -%right <code> ':' -%right <code> ASSIGN '=' -%right <code> '?' -%left <code> OROR -%left <code> ANDAND -%left <code> '|' -%left <code> '^' -%left <code> '&' -%left <code> MIN_MAX -%left <code> EQCOMPARE -%left <code> ARITHCOMPARE '<' '>' -%left <code> LSHIFT RSHIFT -%left <code> '+' '-' -%left <code> '*' '/' '%' -%left <code> POINTSAT_STAR DOT_STAR -%right <code> UNARY PLUSPLUS MINUSMINUS '~' -%left HYPERUNARY -%left <ttype> LEFT_RIGHT -%left <code> POINTSAT '.' '(' '[' - -%right SCOPE /* C++ extension */ -%nonassoc NEW DELETE TRY CATCH - -%type <code> unop - -%type <ttype> identifier IDENTIFIER tTYPENAME CONSTANT expr nonnull_exprlist -%type <ttype> PFUNCNAME maybe_identifier -%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME -%type <ttype> expr_no_commas expr_no_comma_rangle -%type <ttype> cast_expr unary_expr primary STRING -%type <ttype> reserved_declspecs boolean_literal -%type <ttype> reserved_typespecquals -%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier -%type <ttype> init initlist maybeasm maybe_init defarg defarg1 -%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers -%type <ttype> maybe_attribute attributes attribute attribute_list attrib -%type <ttype> any_word unoperator - -%type <itype> save_lineno -%type <ttype> simple_stmt simple_if - -%type <ttype> declarator notype_declarator after_type_declarator -%type <ttype> notype_declarator_intern absdcl_intern -%type <ttype> after_type_declarator_intern -%type <ttype> direct_notype_declarator direct_after_type_declarator -%type <itype> components notype_components -%type <ttype> component_decl component_decl_1 -%type <ttype> component_declarator component_declarator0 -%type <ttype> notype_component_declarator notype_component_declarator0 -%type <ttype> after_type_component_declarator after_type_component_declarator0 -%type <ttype> absdcl cv_qualifiers -%type <ttype> direct_abstract_declarator conversion_declarator -%type <ttype> new_declarator direct_new_declarator -%type <ttype> xexpr parmlist parms bad_parm -%type <ttype> identifiers_or_typenames -%type <ttype> fcast_or_absdcl regcast_or_absdcl -%type <ttype> expr_or_declarator expr_or_declarator_intern -%type <ttype> complex_notype_declarator -%type <ttype> notype_unqualified_id unqualified_id qualified_id -%type <ttype> template_id do_id object_template_id notype_template_declarator -%type <ttype> overqualified_id notype_qualified_id any_id -%type <ttype> complex_direct_notype_declarator functional_cast -%type <ttype> complex_parmlist parms_comma -%type <ttype> namespace_qualifier namespace_using_decl - -%type <ftype> type_id new_type_id typed_typespecs typespec typed_declspecs -%type <ftype> typed_declspecs1 type_specifier_seq nonempty_cv_qualifiers -%type <ftype> structsp typespecqual_reserved parm named_parm full_parm -%type <ftype> declmods - -%type <itype> extension - -/* C++ extensions */ -%token <ttype> PTYPENAME -%token <ttype> EXTERN_LANG_STRING ALL -%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER -%token <pi> PRE_PARSED_FUNCTION_DECL -%type <ttype> component_constructor_declarator -%type <ttype> fn_def2 return_id constructor_declarator -%type <ttype> begin_function_body_ -%type <ttype> class_head class_head_apparent_template -%type <ftype> class_head_decl class_head_defn -%type <ttype> base_class_list -%type <ttype> base_class_access_list -%type <ttype> base_class maybe_base_class_list base_class_1 -%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers -%type <ttype> operator_name -%type <ttype> object aggr -%type <itype> new delete -/* %type <ttype> primary_no_id */ -%type <ttype> maybe_parmlist -%type <ttype> begin_member_init member_init -%type <ftype> member_init_list -%type <ttype> template_parm_header template_spec_header template_header -%type <ttype> template_parm_list template_parm -%type <ttype> template_type_parm template_template_parm -%type <code> template_close_bracket -%type <ttype> apparent_template_type -%type <ttype> template_type template_arg_list template_arg_list_opt -%type <ttype> template_arg template_arg_1 -%type <ttype> condition xcond paren_cond_or_null -%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem -%type <ttype> complete_type_name notype_identifier nonnested_type -%type <ttype> complex_type_name nested_name_specifier_1 -%type <ttype> new_initializer new_placement -%type <ttype> using_decl -%type <ttype> typename_sub typename_sub0 typename_sub1 typename_sub2 -%type <ttype> explicit_template_type -/* in order to recognize aggr tags as defining and thus shadowing. */ -%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN -%type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN -%type <ttype> handler_args -%type <ttype> self_template_type finish_template_type_ - -%token NSNAME -%type <ttype> NSNAME - -/* Used in lex.c for parsing pragmas. */ -%token END_OF_LINE - -/* lex.c and pt.c depend on this being the last token. Define - any new tokens before this one! */ -%token END_OF_SAVED_INPUT - -%{ -/* Tell yyparse how to print a token's value, if yydebug is set. */ -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); -%} - -%% -program: - /* empty */ - { finish_translation_unit (); } - | extdefs - { finish_translation_unit (); } - ; - -/* the reason for the strange actions in this rule - is so that notype_initdecls when reached via datadef - can find a valid list of type and sc specs in $0. */ - -extdefs: - { $<ttype>$ = NULL_TREE; } - lang_extdef - { $<ttype>$ = NULL_TREE; ggc_collect (); } - | extdefs lang_extdef - { $<ttype>$ = NULL_TREE; ggc_collect (); } - ; - -extdefs_opt: - extdefs - | /* empty */ - ; - -.hush_warning: - { have_extern_spec = true; - $<ttype>$ = NULL_TREE; } - ; -.warning_ok: - { have_extern_spec = false; } - ; - -extension: - EXTENSION - { $$ = pedantic; - pedantic = 0; } - ; - -asm_keyword: - ASM_KEYWORD - ; - -lang_extdef: - { if (pending_lang_change) do_pending_lang_change(); - type_lookups = NULL_TREE; } - extdef - { if (! toplevel_bindings_p ()) - pop_everything (); } - ; - -extdef: - fndef eat_saved_input - { do_pending_inlines (); } - | datadef - { do_pending_inlines (); } - - | EXPORT - { warning ("keyword `export' not implemented, and will be ignored"); } - template_def - { do_pending_inlines (); } - | template_def - { do_pending_inlines (); } - | asm_keyword '(' STRING ')' ';' - { assemble_asm ($3); } - | extern_lang_string '{' extdefs_opt '}' - { pop_lang_context (); } - | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { do_pending_inlines (); pop_lang_context (); } - | extern_lang_string .hush_warning datadef .warning_ok - { do_pending_inlines (); pop_lang_context (); } - | NAMESPACE identifier '{' - { push_namespace ($2); } - extdefs_opt '}' - { pop_namespace (); } - | NAMESPACE '{' - { push_namespace (NULL_TREE); } - extdefs_opt '}' - { pop_namespace (); } - | namespace_alias - | using_decl ';' - { do_toplevel_using_decl ($1); } - | using_directive - | extension extdef - { pedantic = $1; } - ; - -namespace_alias: - NAMESPACE identifier '=' - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - if (lastiddecl) - $5 = lastiddecl; - do_namespace_alias ($2, $5); - } - ; - -using_decl: - USING qualified_id - { $$ = $2; } - | USING global_scope qualified_id - { $$ = $3; } - | USING global_scope unqualified_id - { $$ = $3; } - ; - -namespace_using_decl: - USING namespace_qualifier identifier - { $$ = build_nt (SCOPE_REF, $2, $3); } - | USING global_scope identifier - { $$ = build_nt (SCOPE_REF, global_namespace, $3); } - | USING global_scope namespace_qualifier identifier - { $$ = build_nt (SCOPE_REF, $3, $4); } - ; - -using_directive: - USING NAMESPACE - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - /* If no declaration was found, the using-directive is - invalid. Since that was not reported, we need the - identifier for the error message. */ - if (TREE_CODE ($4) == IDENTIFIER_NODE && lastiddecl) - $4 = lastiddecl; - do_using_directive ($4); - } - ; - -namespace_qualifier: - NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | namespace_qualifier NSNAME SCOPE - { - $$ = $2; - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - ; - -any_id: - unqualified_id - | qualified_id - | global_scope qualified_id - { $$ = $2; } - | global_scope unqualified_id - { $$ = $2; } - ; - -extern_lang_string: - EXTERN_LANG_STRING - { push_lang_context ($1); } - | extern_lang_string EXTERN_LANG_STRING - { if (current_lang_name != $2) - error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name); - pop_lang_context (); push_lang_context ($2); } - ; - -template_parm_header: - TEMPLATE '<' - { begin_template_parm_list (); } - template_parm_list '>' - { $$ = end_template_parm_list ($4); } - ; - -template_spec_header: - TEMPLATE '<' '>' - { begin_specialization(); - $$ = NULL_TREE; } - ; - -template_header: - template_parm_header - | template_spec_header - ; - -template_parm_list: - template_parm - { $$ = process_template_parm (NULL_TREE, $1); } - | template_parm_list ',' template_parm - { $$ = process_template_parm ($1, $3); } - ; - -maybe_identifier: - identifier - { $$ = $1; } - | /* empty */ - { $$ = NULL_TREE; } - ; - -template_type_parm: - aggr maybe_identifier - { $$ = finish_template_type_parm ($1, $2); } - | TYPENAME_KEYWORD maybe_identifier - { $$ = finish_template_type_parm (class_type_node, $2); } - ; - -template_template_parm: - template_parm_header aggr maybe_identifier - { $$ = finish_template_template_parm ($2, $3); } - ; - -template_parm: - /* The following rules introduce a new reduce/reduce - conflict on the ',' and '>' input tokens: they are valid - prefixes for a `structsp', which means they could match a - nameless parameter. See 14.6, paragraph 3. - By putting them before the `parm' rule, we get - their match before considering them nameless parameter - declarations. */ - template_type_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_type_parm '=' type_id - { $$ = build_tree_list (groktypename ($3.t), $1); } - | parm - { $$ = build_tree_list (NULL_TREE, $1.t); } - | parm '=' expr_no_comma_rangle - { $$ = build_tree_list ($3, $1.t); } - | template_template_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_template_parm '=' template_arg - { - $3 = check_template_template_default_arg ($3); - $$ = build_tree_list ($3, $1); - } - ; - -template_def: - template_header template_extdef - { finish_template_decl ($1); } - | template_header error %prec EMPTY - { finish_template_decl ($1); } - ; - -template_extdef: - fndef eat_saved_input - { do_pending_inlines (); } - | template_datadef - { do_pending_inlines (); } - | template_def - { do_pending_inlines (); } - | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { do_pending_inlines (); - pop_lang_context (); } - | extern_lang_string .hush_warning template_datadef .warning_ok - { do_pending_inlines (); - pop_lang_context (); } - | extension template_extdef - { pedantic = $1; } - ; - -template_datadef: - nomods_initdecls ';' - | declmods notype_initdecls ';' - {} - | typed_declspecs initdecls ';' - { note_list_got_semicolon ($1.t); } - | structsp ';' - { - if ($1.t != error_mark_node) - { - maybe_process_partial_specialization ($1.t); - note_got_semicolon ($1.t); - } - } - ; - -datadef: - nomods_initdecls ';' - | declmods notype_initdecls ';' - {} - | typed_declspecs initdecls ';' - { note_list_got_semicolon ($1.t); } - | declmods ';' - { pedwarn ("empty declaration"); } - | explicit_instantiation ';' - | typed_declspecs ';' - { - tree t, attrs; - split_specs_attrs ($1.t, &t, &attrs); - shadow_tag (t); - note_list_got_semicolon ($1.t); - } - | error ';' - | error '}' - | error END_OF_SAVED_INPUT - { end_input (); } - | ';' - | bad_decl - ; - -ctor_initializer_opt: - nodecls - | base_init - ; - -maybe_return_init: - /* empty */ - | return_init - | return_init ';' - ; - -eat_saved_input: - /* empty */ - | END_OF_SAVED_INPUT - ; - -/* The outermost block of a function really begins before the - mem-initializer-list, so we open one there and suppress the one that - actually corresponds to the curly braces. */ -function_body: - begin_function_body_ ctor_initializer_opt save_lineno '{' - { $<ttype>$ = begin_compound_stmt (/*has_no_scope=*/1); } - compstmtend - { - STMT_LINENO ($<ttype>5) = $3; - finish_compound_stmt (/*has_no_scope=*/1, $<ttype>5); - finish_function_body ($1); - } - ; - -fndef: - fn.def1 maybe_return_init function_body - { expand_body (finish_function (0)); } - | fn.def1 maybe_return_init function_try_block - { expand_body (finish_function (0)); } - | fn.def1 maybe_return_init error - { } - ; - -constructor_declarator: - nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - | nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - ; - -fn.def1: - typed_declspecs declarator - { check_for_new_type ("return type", $1); - if (!parse_begin_function_definition ($1.t, $2)) - YYERROR1; } - | declmods notype_declarator - { if (!parse_begin_function_definition ($1.t, $2)) - YYERROR1; } - | notype_declarator - { if (!parse_begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - | declmods constructor_declarator - { if (!parse_begin_function_definition ($1.t, $2)) - YYERROR1; } - | constructor_declarator - { if (!parse_begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - ; - -/* ANSI allows optional parentheses around constructor class names. - See ISO/IEC 14882:1998(E) 12.1. */ - -component_constructor_declarator: - SELFNAME '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | '(' SELFNAME ')' '(' parmlist ')' cv_qualifiers - exception_specification_opt - { $$ = make_call_declarator ($2, $5, $7, $8); } - | SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - | '(' SELFNAME ')' LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($2, empty_parms (), $5, $6); } - | self_template_type '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - ; - -/* more C++ complexity. See component_decl for a comment on the - reduce/reduce conflict introduced by these rules. */ -fn_def2: - declmods component_constructor_declarator - { $$ = parse_method ($2, $1.t, $1.lookups); - rest_of_mdef: - if (! $$) - YYERROR1; - if (yychar == YYEMPTY) - yychar = YYLEX; - snarf_method ($$); } - | component_constructor_declarator - { $$ = parse_method ($1, NULL_TREE, NULL_TREE); - goto rest_of_mdef; } - | typed_declspecs declarator - { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} - | declmods notype_declarator - { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} - | notype_declarator - { $$ = parse_method ($1, NULL_TREE, NULL_TREE); - goto rest_of_mdef; } - | declmods constructor_declarator - { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} - | constructor_declarator - { $$ = parse_method ($1, NULL_TREE, NULL_TREE); - goto rest_of_mdef; } - ; - -return_id: - RETURN_KEYWORD IDENTIFIER - { - $$ = $2; - } - ; - -return_init: - return_id maybe_init - { finish_named_return_value ($<ttype>$, $2); } - | return_id '(' nonnull_exprlist ')' - { finish_named_return_value ($<ttype>$, $3); } - | return_id LEFT_RIGHT - { finish_named_return_value ($<ttype>$, NULL_TREE); } - ; - -base_init: - ':' { begin_mem_initializers (); } member_init_list - { - if ($3.new_type_flag == 0) - error ("no base or member initializers given following ':'"); - finish_mem_initializers ($3.t); - } - ; - -begin_function_body_: - /* empty */ - { - $$ = begin_function_body (); - } - ; - -member_init_list: - /* empty */ - { - $$.new_type_flag = 0; - $$.t = NULL_TREE; - } - | member_init - { - $$.new_type_flag = 1; - $$.t = $1; - } - | member_init_list ',' member_init - { - if ($3) - { - $$.new_type_flag = 1; - TREE_CHAIN ($3) = $1.t; - $$.t = $3; - } - else - $$ = $1; - } - | member_init_list error - ; - -begin_member_init: - /* empty */ - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - $$ = expand_member_init (NULL_TREE); - in_base_initializer = $$ && !DECL_P ($$); - } - | notype_identifier - { $$ = expand_member_init ($1); - in_base_initializer = $$ && !DECL_P ($$); } - | nonnested_type - { $$ = expand_member_init ($1); - in_base_initializer = $$ && !DECL_P ($$); } - | typename_sub - { $$ = expand_member_init ($1); - in_base_initializer = $$ && !DECL_P ($$); } - ; - -member_init: - begin_member_init '(' nonnull_exprlist ')' - { in_base_initializer = 0; - $$ = $1 ? build_tree_list ($1, $3) : NULL_TREE; } - | begin_member_init LEFT_RIGHT - { in_base_initializer = 0; - $$ = $1 ? build_tree_list ($1, void_type_node) : NULL_TREE; } - | error - { in_base_initializer = 0; - $$ = NULL_TREE; } - ; - -identifier: - IDENTIFIER - | tTYPENAME - | SELFNAME - | PTYPENAME - | NSNAME - ; - -notype_identifier: - IDENTIFIER - | PTYPENAME - | NSNAME %prec EMPTY - ; - -identifier_defn: - IDENTIFIER_DEFN - | TYPENAME_DEFN - | PTYPENAME_DEFN - ; - -explicit_instantiation: - TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($3.t, NULL_TREE, 1); - yyungetc (';', 1); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation typed_declspecs declarator - { tree specs = strip_attrs ($3.t); - parse_decl_instantiation (specs, $4, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation notype_declarator - { parse_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation constructor_declarator - { parse_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($4.t, $1, 1); - yyungetc (';', 1); } - end_explicit_instantiation - {} - | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs - declarator - { tree specs = strip_attrs ($4.t); - parse_decl_instantiation (specs, $5, $1); } - end_explicit_instantiation - {} - | SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator - { parse_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - {} - | SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator - { parse_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - {} - ; - -begin_explicit_instantiation: - { begin_explicit_instantiation(); } - ; - -end_explicit_instantiation: - { end_explicit_instantiation(); } - ; - -/* The TYPENAME expansions are to deal with use of a template class name as - a template within the class itself, where the template decl is hidden by - a type decl. Got all that? */ - -template_type: - PTYPENAME '<' template_arg_list_opt template_close_bracket - finish_template_type_ - { $$ = $5; } - | tTYPENAME '<' template_arg_list_opt template_close_bracket - finish_template_type_ - { $$ = $5; } - | self_template_type - ; - -apparent_template_type: - template_type - | identifier '<' template_arg_list_opt '>' - finish_template_type_ - { $$ = $5; } - ; - -self_template_type: - SELFNAME '<' template_arg_list_opt template_close_bracket - finish_template_type_ - { $$ = $5; } - ; - -finish_template_type_: - { - if (yychar == YYEMPTY) - yychar = YYLEX; - - $$ = finish_template_type ($<ttype>-3, $<ttype>-1, - yychar == SCOPE); - } - ; - -template_close_bracket: - '>' - | RSHIFT - { - /* Handle `Class<Class<Type>>' without space in the `>>' */ - pedwarn ("`>>' should be `> >' in template class name"); - yyungetc ('>', 1); - } - ; - -template_arg_list_opt: - /* empty */ - { $$ = NULL_TREE; } - | template_arg_list - ; - -template_arg_list: - template_arg - { $$ = build_tree_list (NULL_TREE, $$); } - | template_arg_list ',' template_arg - { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } - ; - -template_arg: - { ++class_template_ok_as_expr; } - template_arg_1 - { - --class_template_ok_as_expr; - $$ = $2; - } - ; - -template_arg_1: - type_id - { $$ = groktypename ($1.t); } - | PTYPENAME - { - $$ = lastiddecl; - if (DECL_TEMPLATE_TEMPLATE_PARM_P ($$)) - $$ = TREE_TYPE ($$); - } - | global_scope PTYPENAME - { - $$ = lastiddecl; - if (DECL_TEMPLATE_TEMPLATE_PARM_P ($$)) - $$ = TREE_TYPE ($$); - } - | expr_no_comma_rangle - | nested_name_specifier TEMPLATE identifier - { - if (!processing_template_decl) - { - error ("use of template qualifier outside template"); - $$ = error_mark_node; - } - else - $$ = make_unbound_class_template ($1, $3, tf_error | tf_parsing); - } - ; - -unop: - '-' - { $$ = NEGATE_EXPR; } - | '+' - { $$ = CONVERT_EXPR; } - | PLUSPLUS - { $$ = PREINCREMENT_EXPR; } - | MINUSMINUS - { $$ = PREDECREMENT_EXPR; } - | '!' - { $$ = TRUTH_NOT_EXPR; } - ; - -expr: - nontrivial_exprlist - { $$ = build_x_compound_expr ($$); } - | expr_no_commas - ; - -paren_expr_or_null: - LEFT_RIGHT - { error ("ISO C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' expr ')' - { $$ = $2; } - ; - -paren_cond_or_null: - LEFT_RIGHT - { error ("ISO C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' condition ')' - { $$ = $2; } - ; - -xcond: - /* empty */ - { $$ = NULL_TREE; } - | condition - | error - { $$ = NULL_TREE; } - ; - -condition: - type_specifier_seq declarator maybeasm maybe_attribute '=' - { { - tree d; - for (d = getdecls (); d; d = TREE_CHAIN (d)) - if (TREE_CODE (d) == TYPE_DECL) { - tree s = TREE_TYPE (d); - if (TREE_CODE (s) == RECORD_TYPE) - error ("definition of class `%T' in condition", s); - else if (TREE_CODE (s) == ENUMERAL_TYPE) - error ("definition of enum `%T' in condition", s); - } - } - current_declspecs = $1.t; - $<ttype>$ = parse_decl ($<ttype>2, $4, 1); - } - init - { - parse_end_decl ($<ttype>6, $7, $4); - $$ = convert_from_reference ($<ttype>6); - if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) - error ("definition of array `%#D' in condition", $$); - } - | expr - ; - -compstmtend: - '}' - | maybe_label_decls stmts '}' - | maybe_label_decls stmts error '}' - | maybe_label_decls error '}' - ; - -nontrivial_exprlist: - expr_no_commas ',' expr_no_commas - { $$ = tree_cons (NULL_TREE, $$, - build_tree_list (NULL_TREE, $3)); } - | expr_no_commas ',' error - { $$ = tree_cons (NULL_TREE, $$, - build_tree_list (NULL_TREE, error_mark_node)); } - | nontrivial_exprlist ',' expr_no_commas - { chainon ($$, build_tree_list (NULL_TREE, $3)); } - | nontrivial_exprlist ',' error - { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); } - ; - -nonnull_exprlist: - expr_no_commas - { $$ = build_tree_list (NULL_TREE, $$); } - | nontrivial_exprlist - ; - -unary_expr: - primary %prec UNARY - { $$ = $1; } - /* __extension__ turns off -pedantic for following primary. */ - | extension cast_expr %prec UNARY - { $$ = $2; - pedantic = $1; } - | '*' cast_expr %prec UNARY - { $$ = build_x_indirect_ref ($2, "unary *"); } - | '&' cast_expr %prec UNARY - { $$ = build_x_unary_op (ADDR_EXPR, $2); } - | '~' cast_expr - { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } - | unop cast_expr %prec UNARY - { $$ = finish_unary_op_expr ($1, $2); } - /* Refer to the address of a label as a pointer. */ - | ANDAND identifier - { $$ = finish_label_address_expr ($2); } - | sizeof unary_expr %prec UNARY - { $$ = finish_sizeof ($2); - skip_evaluation--; } - | sizeof '(' type_id ')' %prec HYPERUNARY - { $$ = finish_sizeof (groktypename ($3.t)); - check_for_new_type ("sizeof", $3); - skip_evaluation--; } - | alignof unary_expr %prec UNARY - { $$ = finish_alignof ($2); - skip_evaluation--; } - | alignof '(' type_id ')' %prec HYPERUNARY - { $$ = finish_alignof (groktypename ($3.t)); - check_for_new_type ("alignof", $3); - skip_evaluation--; } - - /* The %prec EMPTY's here are required by the = init initializer - syntax extension; see below. */ - | new new_type_id %prec EMPTY - { $$ = build_new (NULL_TREE, $2.t, NULL_TREE, $1); - check_for_new_type ("new", $2); } - | new new_type_id new_initializer - { $$ = build_new (NULL_TREE, $2.t, $3, $1); - check_for_new_type ("new", $2); } - | new new_placement new_type_id %prec EMPTY - { $$ = build_new ($2, $3.t, NULL_TREE, $1); - check_for_new_type ("new", $3); } - | new new_placement new_type_id new_initializer - { $$ = build_new ($2, $3.t, $4, $1); - check_for_new_type ("new", $3); } - | new '(' type_id ')' - %prec EMPTY - { $$ = build_new (NULL_TREE, groktypename($3.t), - NULL_TREE, $1); - check_for_new_type ("new", $3); } - | new '(' type_id ')' new_initializer - { $$ = build_new (NULL_TREE, groktypename($3.t), $5, $1); - check_for_new_type ("new", $3); } - | new new_placement '(' type_id ')' %prec EMPTY - { $$ = build_new ($2, groktypename($4.t), NULL_TREE, $1); - check_for_new_type ("new", $4); } - | new new_placement '(' type_id ')' new_initializer - { $$ = build_new ($2, groktypename($4.t), $6, $1); - check_for_new_type ("new", $4); } - - | delete cast_expr %prec UNARY - { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } - | delete '[' ']' cast_expr %prec UNARY - { $$ = delete_sanity ($4, NULL_TREE, 1, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | delete '[' expr ']' cast_expr %prec UNARY - { $$ = delete_sanity ($5, $3, 2, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | REALPART cast_expr %prec UNARY - { $$ = build_x_unary_op (REALPART_EXPR, $2); } - | IMAGPART cast_expr %prec UNARY - { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } - ; - -new_placement: - '(' nonnull_exprlist ')' - { $$ = $2; } - | '{' nonnull_exprlist '}' - { pedwarn ("old style placement syntax, use () instead"); - $$ = $2; } - ; - -new_initializer: - '(' nonnull_exprlist ')' - { $$ = $2; } - | LEFT_RIGHT - { $$ = void_zero_node; } - | '(' typespec ')' - { - error ("`%T' is not a valid expression", $2.t); - $$ = error_mark_node; - } - | '=' init - { - /* This was previously allowed as an extension, but - was removed in G++ 3.3. */ - error ("initialization of new expression with `='"); - $$ = error_mark_node; - } - ; - -/* This is necessary to postpone reduction of `int ((int)(int)(int))'. */ -regcast_or_absdcl: - '(' type_id ')' %prec EMPTY - { $2.t = finish_parmlist (build_tree_list (NULL_TREE, $2.t), 0); - $$ = make_call_declarator (NULL_TREE, $2.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $2); } - | regcast_or_absdcl '(' type_id ')' %prec EMPTY - { $3.t = finish_parmlist (build_tree_list (NULL_TREE, $3.t), 0); - $$ = make_call_declarator ($$, $3.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $3); } - ; - -cast_expr: - unary_expr - | regcast_or_absdcl unary_expr %prec UNARY - { $$ = reparse_absdcl_as_casts ($$, $2); } - | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY - { - tree init = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse ($3)); - if (pedantic) - pedwarn ("ISO C++ forbids compound literals"); - /* Indicate that this was a C99 compound literal. */ - TREE_HAS_CONSTRUCTOR (init) = 1; - - $$ = reparse_absdcl_as_casts ($$, init); - } - ; - -expr_no_commas: - cast_expr - /* Handle general members. */ - | expr_no_commas POINTSAT_STAR expr_no_commas - { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } - | expr_no_commas DOT_STAR expr_no_commas - { $$ = build_m_component_ref ($$, $3); } - | expr_no_commas '+' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '-' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '*' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '/' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '%' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas LSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas RSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ARITHCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '<' expr_no_commas - { $$ = build_x_binary_op (LT_EXPR, $$, $3); } - | expr_no_commas '>' expr_no_commas - { $$ = build_x_binary_op (GT_EXPR, $$, $3); } - | expr_no_commas EQCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas MIN_MAX expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '&' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '|' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '^' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ANDAND expr_no_commas - { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } - | expr_no_commas OROR expr_no_commas - { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } - | expr_no_commas '?' xexpr ':' expr_no_commas - { $$ = build_x_conditional_expr ($$, $3, $5); } - | expr_no_commas '=' expr_no_commas - { $$ = build_x_modify_expr ($$, NOP_EXPR, $3); - if ($$ != error_mark_node) - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } - | expr_no_commas ASSIGN expr_no_commas - { $$ = build_x_modify_expr ($$, $2, $3); } - | THROW - { $$ = build_throw (NULL_TREE); } - | THROW expr_no_commas - { $$ = build_throw ($2); } - ; - -expr_no_comma_rangle: - cast_expr - /* Handle general members. */ - | expr_no_comma_rangle POINTSAT_STAR expr_no_comma_rangle - { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } - | expr_no_comma_rangle DOT_STAR expr_no_comma_rangle - { $$ = build_m_component_ref ($$, $3); } - | expr_no_comma_rangle '+' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '-' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '*' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '/' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '%' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle LSHIFT expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle RSHIFT expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle ARITHCOMPARE expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '<' expr_no_comma_rangle - { $$ = build_x_binary_op (LT_EXPR, $$, $3); } - | expr_no_comma_rangle EQCOMPARE expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle MIN_MAX expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '&' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '|' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle '^' expr_no_comma_rangle - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_comma_rangle ANDAND expr_no_comma_rangle - { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } - | expr_no_comma_rangle OROR expr_no_comma_rangle - { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } - | expr_no_comma_rangle '?' xexpr ':' expr_no_comma_rangle - { $$ = build_x_conditional_expr ($$, $3, $5); } - | expr_no_comma_rangle '=' expr_no_comma_rangle - { $$ = build_x_modify_expr ($$, NOP_EXPR, $3); - if ($$ != error_mark_node) - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } - | expr_no_comma_rangle ASSIGN expr_no_comma_rangle - { $$ = build_x_modify_expr ($$, $2, $3); } - | THROW - { $$ = build_throw (NULL_TREE); } - | THROW expr_no_comma_rangle - { $$ = build_throw ($2); } - ; - -notype_unqualified_id: - '~' see_typename identifier - { $$ = build_nt (BIT_NOT_EXPR, $3); } - | '~' see_typename template_type - { $$ = build_nt (BIT_NOT_EXPR, $3); } - | template_id - | operator_name - | IDENTIFIER - | PTYPENAME - | NSNAME %prec EMPTY - ; - -do_id: - { - /* If lastiddecl is a BASELINK we're in an - expression like S::f<int>, so don't - do_identifier; we only do that for unqualified - identifiers. */ - if (!lastiddecl || !BASELINK_P (lastiddecl)) - $$ = do_identifier ($<ttype>-1, 3, NULL_TREE); - else - $$ = $<ttype>-1; - } - ; - -template_id: - PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket - { - tree template_name = $3; - if (TREE_CODE (template_name) == COMPONENT_REF) - template_name = TREE_OPERAND (template_name, 1); - $$ = lookup_template_function (template_name, $4); - } - | operator_name '<' do_id template_arg_list_opt template_close_bracket - { - tree template_name = $3; - if (TREE_CODE (template_name) == COMPONENT_REF) - template_name = TREE_OPERAND (template_name, 1); - $$ = lookup_template_function (template_name, $4); - } - ; - -object_template_id: - TEMPLATE identifier '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE PFUNCNAME '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE operator_name '<' template_arg_list_opt - template_close_bracket - { $$ = lookup_template_function ($2, $4); } - ; - -unqualified_id: - notype_unqualified_id - | tTYPENAME - | SELFNAME - ; - -expr_or_declarator_intern: - expr_or_declarator - | attributes expr_or_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = tree_cons ($1, $2, NULL_TREE); - } - ; - -expr_or_declarator: - notype_unqualified_id - | '*' expr_or_declarator_intern %prec UNARY - { $$ = build_nt (INDIRECT_REF, $2); } - | '&' expr_or_declarator_intern %prec UNARY - { $$ = build_nt (ADDR_EXPR, $2); } - | '(' expr_or_declarator_intern ')' - { $$ = $2; } - ; - -notype_template_declarator: - IDENTIFIER '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($1, $3); } - | NSNAME '<' template_arg_list template_close_bracket - { $$ = lookup_template_function ($1, $3); } - ; - -direct_notype_declarator: - complex_direct_notype_declarator - /* This precedence declaration is to prefer this reduce - to the Koenig lookup shift in primary, below. I hate yacc. */ - | notype_unqualified_id %prec '(' - | notype_template_declarator - | '(' expr_or_declarator_intern ')' - { $$ = finish_decl_parsing ($2); } - ; - -primary: - notype_unqualified_id - { - if (TREE_CODE ($1) == BIT_NOT_EXPR) - $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($1, 0)); - else - $$ = finish_id_expr ($1); - } - | CONSTANT - | boolean_literal - | STRING - { - $$ = fix_string_type ($$); - /* fix_string_type doesn't set up TYPE_MAIN_VARIANT of - a const array the way we want, so fix it. */ - if (flag_const_strings) - TREE_TYPE ($$) = build_cplus_array_type - (TREE_TYPE (TREE_TYPE ($$)), - TYPE_DOMAIN (TREE_TYPE ($$))); - } - | VAR_FUNC_NAME - { $$ = finish_fname ($1); } - | '(' expr ')' - { $$ = finish_parenthesized_expr ($2); } - | '(' expr_or_declarator_intern ')' - { $2 = reparse_decl_as_expr (NULL_TREE, $2); - $$ = finish_parenthesized_expr ($2); } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { if (!at_function_scope_p ()) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - if (pedantic) - pedwarn ("ISO C++ forbids braced-groups within expressions"); - $<ttype>$ = begin_stmt_expr (); - } - compstmt_or_stmtexpr ')' - { $$ = finish_stmt_expr ($<ttype>2); } - /* Koenig lookup support - We could store lastiddecl in $1 to avoid another lookup, - but that would result in many additional reduce/reduce conflicts. */ - | notype_unqualified_id '(' nonnull_exprlist ')' - { $$ = parse_finish_call_expr ($1, $3, 1); } - | notype_unqualified_id LEFT_RIGHT - { $$ = parse_finish_call_expr ($1, NULL_TREE, 1); } - | primary '(' nonnull_exprlist ')' - { $$ = parse_finish_call_expr ($1, $3, 0); } - | primary LEFT_RIGHT - { $$ = parse_finish_call_expr ($1, NULL_TREE, 0); } - | VA_ARG '(' expr_no_commas ',' type_id ')' - { $$ = build_x_va_arg ($3, groktypename ($5.t)); - check_for_new_type ("__builtin_va_arg", $5); } - | primary '[' expr ']' - { $$ = grok_array_decl ($$, $3); } - | primary PLUSPLUS - { $$ = finish_increment_expr ($1, POSTINCREMENT_EXPR); } - | primary MINUSMINUS - { $$ = finish_increment_expr ($1, POSTDECREMENT_EXPR); } - /* C++ extensions */ - | THIS - { $$ = finish_this_expr (); } - | CV_QUALIFIER '(' nonnull_exprlist ')' - { - /* This is a C cast in C++'s `functional' notation - using the "implicit int" extension so that: - `const (3)' is equivalent to `const int (3)'. */ - tree type; - - type = hash_tree_cons (NULL_TREE, $1, NULL_TREE); - type = groktypename (build_tree_list (type, NULL_TREE)); - $$ = build_functional_cast (type, $3); - } - | functional_cast - | DYNAMIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("dynamic_cast", $3); - $$ = build_dynamic_cast (type, $6); } - | STATIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("static_cast", $3); - $$ = build_static_cast (type, $6); } - | REINTERPRET_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("reinterpret_cast", $3); - $$ = build_reinterpret_cast (type, $6); } - | CONST_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("const_cast", $3); - $$ = build_const_cast (type, $6); } - | TYPEID '(' expr ')' - { $$ = build_typeid ($3); } - | TYPEID '(' type_id ')' - { tree type = groktypename ($3.t); - check_for_new_type ("typeid", $3); - $$ = get_typeid (type); } - | global_scope IDENTIFIER - { $$ = parse_scoped_id ($2); } - | global_scope template_id - { $$ = $2; } - | global_scope operator_name - { - got_scope = NULL_TREE; - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = parse_scoped_id ($2); - else - $$ = $2; - } - | overqualified_id %prec HYPERUNARY - { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); - if (!class_template_ok_as_expr - && DECL_CLASS_TEMPLATE_P ($$)) - { - error ("invalid use of template `%D'", $$); - $$ = error_mark_node; - } - } - | overqualified_id '(' nonnull_exprlist ')' - { $$ = parse_finish_call_expr ($1, $3, 0); } - | overqualified_id LEFT_RIGHT - { $$ = parse_finish_call_expr ($1, NULL_TREE, 0); } - | object object_template_id %prec UNARY - { $$ = finish_class_member_access_expr ($$, $2); } - | object object_template_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object object_template_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object unqualified_id %prec UNARY - { $$ = finish_class_member_access_expr ($$, $2); } - | object overqualified_id %prec UNARY - { $$ = finish_class_member_access_expr ($1, $2); } - | object unqualified_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object unqualified_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_qualified_object_call_expr ($2, $1, $4); } - | object overqualified_id LEFT_RIGHT - { $$ = finish_qualified_object_call_expr ($2, $1, NULL_TREE); } - /* p->int::~int() is valid -- 12.4 */ - | object '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, NULL_TREE, $3); } - | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, $2, $5); } - | object error - { - $$ = error_mark_node; - } - ; - -/* Not needed for now. - -primary_no_id: - '(' expr ')' - { $$ = $2; } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - $<ttype>$ = expand_start_stmt_expr (); } - compstmt_or_stmtexpr ')' - { if (pedantic) - pedwarn ("ISO C++ forbids braced-groups within expressions"); - $$ = expand_end_stmt_expr ($<ttype>2); } - | primary_no_id '(' nonnull_exprlist ')' - { $$ = build_x_function_call ($$, $3, current_class_ref); } - | primary_no_id LEFT_RIGHT - { $$ = build_x_function_call ($$, NULL_TREE, current_class_ref); } - | primary_no_id '[' expr ']' - { goto do_array; } - | primary_no_id PLUSPLUS - { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } - | primary_no_id MINUSMINUS - { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } - | SCOPE IDENTIFIER - { goto do_scoped_id; } - | SCOPE operator_name - { if (TREE_CODE ($2) == IDENTIFIER_NODE) - goto do_scoped_id; - goto do_scoped_operator; - } - ; -*/ - -new: - NEW - { $$ = 0; } - | global_scope NEW - { got_scope = NULL_TREE; $$ = 1; } - ; - -delete: - DELETE - { $$ = 0; } - | global_scope delete - { got_scope = NULL_TREE; $$ = 1; } - ; - -boolean_literal: - CXX_TRUE - { $$ = boolean_true_node; } - | CXX_FALSE - { $$ = boolean_false_node; } - ; - -nodecls: - /* empty */ - { - if (DECL_CONSTRUCTOR_P (current_function_decl)) - finish_mem_initializers (NULL_TREE); - } - ; - -object: - primary '.' - { got_object = TREE_TYPE ($$); } - | primary POINTSAT - { - $$ = build_x_arrow ($$); - got_object = TREE_TYPE ($$); - } - ; - -decl: - typespec initdecls ';' - { - if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t))) - note_got_semicolon ($1.t); - } - | typed_declspecs initdecls ';' - { - note_list_got_semicolon ($1.t); - } - | declmods notype_initdecls ';' - {} - | typed_declspecs ';' - { - shadow_tag ($1.t); - note_list_got_semicolon ($1.t); - } - | declmods ';' - { warning ("empty declaration"); } - | extension decl - { pedantic = $1; } - ; - -/* Any kind of declarator (thus, all declarators allowed - after an explicit typespec). */ - -declarator: - after_type_declarator %prec EMPTY - | notype_declarator %prec EMPTY - ; - -/* This is necessary to postpone reduction of `int()()()()'. */ -fcast_or_absdcl: - LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator (NULL_TREE, empty_parms (), - NULL_TREE, NULL_TREE); } - | fcast_or_absdcl LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator ($$, empty_parms (), NULL_TREE, - NULL_TREE); } - ; - -/* ISO type-id (8.1) */ -type_id: - typed_typespecs absdcl - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers absdcl - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec absdcl - { $$.t = build_tree_list (build_tree_list (NULL_TREE, $1.t), - $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_typespecs %prec EMPTY - { $$.t = build_tree_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers %prec EMPTY - { $$.t = build_tree_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* Declspecs which contain at least one type specifier or typedef name. - (Just `const' or `volatile' is not enough.) - A typedef'd name following these is taken as a name to be declared. - In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ - -typed_declspecs: - typed_typespecs %prec EMPTY - { $$.lookups = type_lookups; } - | typed_declspecs1 - { $$.lookups = type_lookups; } - ; - -typed_declspecs1: - declmods typespec - { $$.t = tree_cons (NULL_TREE, $2.t, $1.t); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_declspecs %prec HYPERUNARY - { $$.t = tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec reserved_typespecquals reserved_declspecs - { $$.t = tree_cons (NULL_TREE, $1.t, chainon ($2, $3)); - $$.new_type_flag = $1.new_type_flag; } - | declmods typespec reserved_declspecs - { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals - { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals reserved_declspecs - { $$.t = tree_cons (NULL_TREE, $2.t, - chainon ($3, chainon ($4, $1.t))); - $$.new_type_flag = $2.new_type_flag; } - ; - -reserved_declspecs: - SCSPEC - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (NULL_TREE, $$); } - | reserved_declspecs typespecqual_reserved - { $$ = tree_cons (NULL_TREE, $2.t, $$); } - | reserved_declspecs SCSPEC - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $$); } - ; - -/* List of just storage classes and type modifiers. - A declaration can start with just this, but then it cannot be used - to redeclare a typedef-name. - In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ - -/* We use hash_tree_cons for lists of typeless declspecs so that they end - up on a persistent obstack. Otherwise, they could appear at the - beginning of something like - - static const struct { int foo () { } } b; - - and would be discarded after we finish compiling foo. We don't need to - worry once we see a type. */ - -declmods: - nonempty_cv_qualifiers %prec EMPTY - { $$.lookups = NULL_TREE; TREE_STATIC ($$.t) = 1; } - | SCSPEC - { - $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); - $$.new_type_flag = 0; $$.lookups = NULL_TREE; - } - | declmods CV_QUALIFIER - { - $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); - TREE_STATIC ($$.t) = 1; - } - | declmods SCSPEC - { - if (extra_warnings && TREE_STATIC ($$.t)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); - TREE_STATIC ($$.t) = TREE_STATIC ($1.t); - } - | declmods attributes - { $$.t = hash_tree_cons ($2, NULL_TREE, $1.t); } - ; - -/* Used instead of declspecs where storage classes are not allowed - (that is, for typenames and structure components). - - C++ can takes storage classes for structure components. - Don't accept a typedef-name if anything but a modifier precedes it. */ - -typed_typespecs: - typespec %prec EMPTY - { $$.t = build_tree_list (NULL_TREE, $1.t); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers typespec - { $$.t = tree_cons (NULL_TREE, $2.t, $1.t); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_typespecquals - { $$.t = tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers typespec reserved_typespecquals - { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $2.new_type_flag; } - ; - -reserved_typespecquals: - typespecqual_reserved - { $$ = build_tree_list (NULL_TREE, $1.t); } - | reserved_typespecquals typespecqual_reserved - { $$ = tree_cons (NULL_TREE, $2.t, $1); } - | reserved_typespecquals attributes - { $$ = tree_cons ($2, NULL_TREE, $1); } - | attributes %prec EMPTY - { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); } - ; - -sizeof: - SIZEOF { skip_evaluation++; } - ; - -alignof: - ALIGNOF { skip_evaluation++; } - ; - -typeof: - TYPEOF { skip_evaluation++; } - ; - -/* A typespec (but not a type qualifier). - Once we have seen one of these in a declaration, - if a typedef name appears then it is being redeclared. */ - -typespec: - structsp - { $$.lookups = NULL_TREE; } - | TYPESPEC %prec EMPTY - { $$.t = $1; $$.new_type_flag = 0; $$.lookups = NULL_TREE; } - | complete_type_name - { $$.t = $1; $$.new_type_flag = 0; $$.lookups = NULL_TREE; } - | typeof '(' expr ')' - { $$.t = finish_typeof ($3); - $$.new_type_flag = 0; $$.lookups = NULL_TREE; - skip_evaluation--; } - | typeof '(' type_id ')' - { $$.t = groktypename ($3.t); - $$.new_type_flag = 0; $$.lookups = NULL_TREE; - skip_evaluation--; } - | SIGOF '(' expr ')' - { tree type = TREE_TYPE ($3); - - $$.new_type_flag = 0; $$.lookups = NULL_TREE; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$.t = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { tree type = groktypename ($3.t); - - $$.new_type_flag = 0; $$.lookups = NULL_TREE; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error("`sigof' applied to non-aggregate type"); - $$.t = error_mark_node; - } - } - ; - -/* A typespec that is a reserved word, or a type qualifier. */ - -typespecqual_reserved: - TYPESPEC - { $$.t = $1; $$.new_type_flag = 0; } - | CV_QUALIFIER - { $$.t = $1; $$.new_type_flag = 0; } - | structsp - ; - -initdecls: - initdcl0 - | initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -notype_initdecls: - notype_initdcl0 - | notype_initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -nomods_initdecls: - nomods_initdcl0 - | nomods_initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -maybeasm: - /* empty */ - { $$ = NULL_TREE; } - | asm_keyword '(' STRING ')' - { $$ = $3; } - ; - -initdcl: - declarator maybeasm maybe_attribute '=' - { $<ttype>$ = parse_decl ($<ttype>1, $3, 1); } - init -/* Note how the declaration of the variable is in effect while its init is parsed! */ - { parse_end_decl ($<ttype>5, $6, $2); } - | declarator maybeasm maybe_attribute - { - $<ttype>$ = parse_decl ($<ttype>1, $3, 0); - parse_end_decl ($<ttype>$, NULL_TREE, $2); - } - ; - - /* This rule assumes a certain configuration of the parser stack. - In particular, $0, the element directly before the beginning of - this rule on the stack, must be a maybeasm. $-1 must be a - declarator or notype_declarator. And $-2 must be some declmods - or declspecs. We can't move the maybeasm into this rule because - we need that reduce so we prefer fn.def1 when appropriate. */ -initdcl0_innards: - maybe_attribute '=' - { $<ttype>$ = parse_decl0 ($<ttype>-1, $<ftype>-2.t, - $<ftype>-2.lookups, $1, 1); } - /* Note how the declaration of the variable is in effect - while its init is parsed! */ - init - { parse_end_decl ($<ttype>3, $4, $<ttype>0); } - | maybe_attribute - { tree d = parse_decl0 ($<ttype>-1, $<ftype>-2.t, - $<ftype>-2.lookups, $1, 0); - parse_end_decl (d, NULL_TREE, $<ttype>0); } - ; - -initdcl0: - declarator maybeasm initdcl0_innards - {} - ; - -notype_initdcl0: - notype_declarator maybeasm initdcl0_innards - {} - ; - -nomods_initdcl0: - notype_declarator maybeasm - { /* Set things up as initdcl0_innards expects. */ - $<ttype>$ = $2; - $2 = $1; - $<ftype>1.t = NULL_TREE; - $<ftype>1.lookups = NULL_TREE; } - initdcl0_innards - {} - | constructor_declarator maybeasm maybe_attribute - { tree d = parse_decl0 ($1, NULL_TREE, NULL_TREE, $3, 0); - parse_end_decl (d, NULL_TREE, $2); } - ; - -/* the * rules are dummies to accept the Apollo extended syntax - so that the header files compile. */ -maybe_attribute: - /* empty */ - { $$ = NULL_TREE; } - | attributes - { $$ = $1; } - ; - -attributes: - attribute - { $$ = $1; } - | attributes attribute - { $$ = chainon ($1, $2); } - ; - -attribute: - ATTRIBUTE '(' '(' attribute_list ')' ')' - { $$ = $4; } - ; - -attribute_list: - attrib - { $$ = $1; } - | attribute_list ',' attrib - { $$ = chainon ($1, $3); } - ; - -attrib: - /* empty */ - { $$ = NULL_TREE; } - | any_word - { $$ = build_tree_list ($1, NULL_TREE); } - | any_word '(' IDENTIFIER ')' - { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } - | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' - { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } - | any_word '(' nonnull_exprlist ')' - { $$ = build_tree_list ($1, $3); } - ; - -/* This still leaves out most reserved keywords, - shouldn't we include them? */ - -any_word: - identifier - | SCSPEC - | TYPESPEC - | CV_QUALIFIER - ; - -/* A nonempty list of identifiers, including typenames. */ -identifiers_or_typenames: - identifier - { $$ = build_tree_list (NULL_TREE, $1); } - | identifiers_or_typenames ',' identifier - { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } - ; - -maybe_init: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '=' init - { $$ = $2; } - ; - -/* If we are processing a template, we don't want to expand this - initializer yet. */ - -init: - expr_no_commas %prec '=' - | '{' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist ',' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | error - { $$ = NULL_TREE; } - ; - -/* This chain is built in reverse order, - and put in forward order where initlist is used. */ -initlist: - init - { $$ = build_tree_list (NULL_TREE, $$); } - | initlist ',' init - { $$ = tree_cons (NULL_TREE, $3, $$); } - /* These are for labeled elements. */ - | '[' expr_no_commas ']' init - { $$ = build_tree_list ($2, $4); } - | identifier ':' init - { $$ = build_tree_list ($$, $3); } - | initlist ',' identifier ':' init - { $$ = tree_cons ($3, $5, $$); } - ; - -pending_inline: - PRE_PARSED_FUNCTION_DECL maybe_return_init function_body - { - expand_body (finish_function (2)); - process_next_inline ($1); - } - | PRE_PARSED_FUNCTION_DECL maybe_return_init function_try_block - { - expand_body (finish_function (2)); - process_next_inline ($1); - } - | PRE_PARSED_FUNCTION_DECL maybe_return_init error - { - finish_function (2); - process_next_inline ($1); } - ; - -pending_inlines: - /* empty */ - | pending_inlines pending_inline eat_saved_input - ; - -/* A regurgitated default argument. The value of DEFARG_MARKER will be - the TREE_LIST node for the parameter in question. */ -defarg_again: - DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT - { replace_defarg ($1, $2); } - | DEFARG_MARKER error END_OF_SAVED_INPUT - { replace_defarg ($1, error_mark_node); } - ; - -pending_defargs: - /* empty */ %prec EMPTY - | pending_defargs defarg_again - { do_pending_defargs (); } - | pending_defargs error - { do_pending_defargs (); } - ; - -structsp: - ENUM identifier '{' - { $<ttype>$ = current_enum_type; - current_enum_type = start_enum ($2); } - enumlist_opt '}' - { $$.t = current_enum_type; - finish_enum (current_enum_type); - $$.new_type_flag = 1; - current_enum_type = $<ttype>4; - check_for_missing_semicolon ($$.t); } - | ENUM '{' - { $<ttype>$ = current_enum_type; - current_enum_type = start_enum (make_anon_name ()); } - enumlist_opt '}' - { $$.t = current_enum_type; - finish_enum (current_enum_type); - $$.new_type_flag = 1; - current_enum_type = $<ttype>3; - check_for_missing_semicolon ($$.t); } - | ENUM identifier - { $$.t = parse_xref_tag (enum_type_node, $2, 1); - $$.new_type_flag = 0; } - | ENUM complex_type_name - { $$.t = parse_xref_tag (enum_type_node, $2, 1); - $$.new_type_flag = 0; } - | TYPENAME_KEYWORD typename_sub - { $$.t = $2; - $$.new_type_flag = 0; - if (!processing_template_decl) - pedwarn ("using `typename' outside of template"); } - /* C++ extensions, merged with C to avoid shift/reduce conflicts */ - | class_head_defn maybe_base_class_list '{' - { - if ($2 && $1.t != error_mark_node) - { - tree type = TREE_TYPE ($1.t); - - if (TREE_CODE (type) == TYPENAME_TYPE) - { - if (IMPLICIT_TYPENAME_P (type)) - /* In a definition of a member class template, - we will get here with an implicit typename, - a TYPENAME_TYPE with a type. */ - type = TREE_TYPE (type); - else - { - error ("qualified name does not name a class"); - type = error_mark_node; - } - } - maybe_process_partial_specialization (type); - xref_basetypes (type, $2); - } - $1.t = begin_class_definition (TREE_TYPE ($1.t)); - check_class_key (current_aggr, $1.t); - current_aggr = NULL_TREE; } - opt.component_decl_list '}' maybe_attribute - { - int semi; - tree t; - - if (yychar == YYEMPTY) - yychar = YYLEX; - semi = yychar == ';'; - - t = finish_class_definition ($1.t, $7, semi, $1.new_type_flag); - $<ttype>$ = t; - - /* restore current_aggr */ - current_aggr = TREE_CODE (t) != RECORD_TYPE - ? union_type_node - : CLASSTYPE_DECLARED_CLASS (t) - ? class_type_node : record_type_node; - } - pending_defargs - { - done_pending_defargs (); - begin_inline_definitions (); - } - pending_inlines - { - $$.t = $<ttype>8; - $$.new_type_flag = 1; - } - | class_head_decl - { - $$.t = TREE_TYPE ($1.t); - $$.new_type_flag = $1.new_type_flag; - check_class_key (current_aggr, $$.t); - } - ; - -maybecomma: - /* empty */ - | ',' - ; - -maybecomma_warn: - /* empty */ - | ',' - { if (pedantic && !in_system_header) - pedwarn ("comma at end of enumerator list"); } - ; - -aggr: - AGGR - | aggr SCSPEC - { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr TYPESPEC - { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr CV_QUALIFIER - { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr AGGR - { error ("no body nor ';' separates two class, struct or union declarations"); } - | aggr attributes - { $$ = build_tree_list ($2, $1); } - ; - -class_head: - aggr identifier - { - current_aggr = $1; - $$ = build_tree_list (NULL_TREE, $2); - } - | aggr nested_name_specifier identifier - { - current_aggr = $1; - $$ = build_tree_list ($2, $3); - } - | aggr global_scope nested_name_specifier identifier - { - current_aggr = $1; - $$ = build_tree_list ($3, $4); - } - | aggr global_scope identifier - { - current_aggr = $1; - $$ = build_tree_list (global_namespace, $3); - } - ; - -class_head_apparent_template: - aggr apparent_template_type - { - current_aggr = $1; - $$ = $2; - } - | aggr nested_name_specifier apparent_template_type - { - current_aggr = $1; - $$ = $3; - } - | aggr global_scope nested_name_specifier apparent_template_type - { - current_aggr = $1; - $$ = $4; - } - ; - -class_head_decl: - class_head %prec EMPTY - { - $$.t = parse_handle_class_head (current_aggr, - TREE_PURPOSE ($1), - TREE_VALUE ($1), - 0, &$$.new_type_flag); - } - | aggr identifier_defn %prec EMPTY - { - current_aggr = $1; - $$.t = TYPE_MAIN_DECL (parse_xref_tag (current_aggr, $2, 0)); - $$.new_type_flag = 1; - } - | class_head_apparent_template %prec EMPTY - { - $$.t = $1; - $$.new_type_flag = 0; - } - ; - -class_head_defn: - class_head '{' - { - yyungetc ('{', 1); - $$.t = parse_handle_class_head (current_aggr, - TREE_PURPOSE ($1), - TREE_VALUE ($1), - 1, - &$$.new_type_flag); - } - | class_head ':' - { - yyungetc (':', 1); - $$.t = parse_handle_class_head (current_aggr, - TREE_PURPOSE ($1), - TREE_VALUE ($1), - 1, &$$.new_type_flag); - } - | class_head_apparent_template '{' - { - yyungetc ('{', 1); - $$.t = handle_class_head_apparent_template - ($1, &$$.new_type_flag); - } - | class_head_apparent_template ':' - { - yyungetc (':', 1); - $$.t = handle_class_head_apparent_template - ($1, &$$.new_type_flag); - } - | aggr identifier_defn '{' - { - yyungetc ('{', 1); - current_aggr = $1; - $$.t = parse_handle_class_head (current_aggr, - NULL_TREE, $2, - 1, &$$.new_type_flag); - } - | aggr identifier_defn ':' - { - yyungetc (':', 1); - current_aggr = $1; - $$.t = parse_handle_class_head (current_aggr, - NULL_TREE, $2, - 1, &$$.new_type_flag); - } - | aggr '{' - { - current_aggr = $1; - $$.t = TYPE_MAIN_DECL (parse_xref_tag ($1, - make_anon_name (), - 0)); - $$.new_type_flag = 0; - CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($$.t)) - = $1 == class_type_node; - yyungetc ('{', 1); - } - ; - -maybe_base_class_list: - /* empty */ - { $$ = NULL_TREE; } - | ':' see_typename - { error ("no bases given following `:'"); - $$ = NULL_TREE; } - | ':' see_typename base_class_list - { $$ = $3; } - ; - -base_class_list: - base_class - | base_class_list ',' see_typename base_class - { $$ = chainon ($$, $4); } - ; - -base_class: - base_class_1 - { $$ = finish_base_specifier (access_default_node, $1); } - | base_class_access_list see_typename base_class_1 - { $$ = finish_base_specifier ($1, $3); } - ; - -base_class_1: - typename_sub - { if (!TYPE_P ($$)) - $$ = error_mark_node; } - | nonnested_type - { $$ = TREE_TYPE ($$); } - ; - -base_class_access_list: - VISSPEC see_typename - | SCSPEC see_typename - { if ($1 != ridpointers[(int)RID_VIRTUAL]) - error ("`%D' access", $1); - $$ = access_default_virtual_node; } - | base_class_access_list VISSPEC see_typename - { - if ($1 != access_default_virtual_node) - error ("multiple access specifiers"); - else if ($2 == access_public_node) - $$ = access_public_virtual_node; - else if ($2 == access_protected_node) - $$ = access_protected_virtual_node; - else /* $2 == access_private_node */ - $$ = access_private_virtual_node; - } - | base_class_access_list SCSPEC see_typename - { if ($2 != ridpointers[(int)RID_VIRTUAL]) - error ("`%D' access", $2); - else if ($$ == access_public_node) - $$ = access_public_virtual_node; - else if ($$ == access_protected_node) - $$ = access_protected_virtual_node; - else if ($$ == access_private_node) - $$ = access_private_virtual_node; - else - error ("multiple `virtual' specifiers"); - } - ; - -opt.component_decl_list: - | component_decl_list - | opt.component_decl_list access_specifier component_decl_list - | opt.component_decl_list access_specifier - ; - -access_specifier: - VISSPEC ':' - { - current_access_specifier = $1; - } - ; - -/* Note: we no longer warn about the semicolon after a component_decl_list. - ARM $9.2 says that the semicolon is optional, and therefore allowed. */ -component_decl_list: - component_decl - { - finish_member_declaration ($1); - current_aggr = NULL_TREE; - reset_type_access_control (); - } - | component_decl_list component_decl - { - finish_member_declaration ($2); - current_aggr = NULL_TREE; - reset_type_access_control (); - } - ; - -component_decl: - component_decl_1 ';' - | component_decl_1 '}' - { error ("missing ';' before right brace"); - yyungetc ('}', 0); } - /* C++: handle constructors, destructors and inline functions */ - /* note that INLINE is like a TYPESPEC */ - | fn_def2 ':' /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn_def2 TRY /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn_def2 RETURN_KEYWORD /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn_def2 '{' /* nodecls compstmt */ - { $$ = finish_method ($$); } - | ';' - { $$ = NULL_TREE; } - | extension component_decl - { $$ = $2; - pedantic = $1; } - | template_header component_decl - { - if ($2) - $$ = finish_member_template_decl ($2); - else - /* The component was already processed. */ - $$ = NULL_TREE; - - finish_template_decl ($1); - } - | template_header typed_declspecs ';' - { - $$ = finish_member_class_template ($2.t); - finish_template_decl ($1); - } - | bad_decl - { $$ = NULL_TREE; } - ; - -component_decl_1: - /* Do not add a "typed_declspecs declarator" rule here for - speed; we need to call grok_x_components for enums, so the - speedup would be insignificant. */ - typed_declspecs components - { - /* Most of the productions for component_decl only - allow the creation of one new member, so we call - finish_member_declaration in component_decl_list. - For this rule and the next, however, there can be - more than one member, e.g.: - - int i, j; - - and we need the first member to be fully - registered before the second is processed. - Therefore, the rules for components take care of - this processing. To avoid registering the - components more than once, we send NULL_TREE up - here; that lets finish_member_declaration know - that there is nothing to do. */ - if (!$2) - grok_x_components ($1.t); - $$ = NULL_TREE; - } - | declmods notype_components - { - if (!$2) - grok_x_components ($1.t); - $$ = NULL_TREE; - } - | notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } - | ':' expr_no_commas - { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } - | error - { $$ = NULL_TREE; } - - /* These rules introduce a reduce/reduce conflict; in - typedef int foo, bar; - class A { - foo (bar); - }; - should "A::foo" be declared as a function or "A::bar" as a data - member? In other words, is "bar" an after_type_declarator or a - parmlist? */ - | declmods component_constructor_declarator maybeasm maybe_attribute maybe_init - { tree specs, attrs; - split_specs_attrs ($1.t, &specs, &attrs); - $$ = grokfield ($2, specs, $5, $3, - chainon ($4, attrs)); } - | component_constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } - | using_decl - { $$ = do_class_using_decl ($1); } - ; - -/* The case of exactly one component is handled directly by component_decl. */ -/* ??? Huh? ^^^ */ -components: - /* empty: possibly anonymous */ - { $$ = 0; } - | component_declarator0 - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $1 = finish_member_template_decl ($1); - finish_member_declaration ($1); - $$ = 1; - } - | components ',' component_declarator - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $3 = finish_member_template_decl ($3); - finish_member_declaration ($3); - $$ = 2; - } - ; - -notype_components: - /* empty: possibly anonymous */ - { $$ = 0; } - | notype_component_declarator0 - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $1 = finish_member_template_decl ($1); - finish_member_declaration ($1); - $$ = 1; - } - | notype_components ',' notype_component_declarator - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $3 = finish_member_template_decl ($3); - finish_member_declaration ($3); - $$ = 2; - } - ; - -component_declarator0: - after_type_component_declarator0 - | notype_component_declarator0 - ; - -component_declarator: - after_type_component_declarator - | notype_component_declarator - ; - -after_type_component_declarator0: - after_type_declarator maybeasm maybe_attribute maybe_init - { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups, - $3, $2, $4); } - | tTYPENAME ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups, - $4, $3); } - ; - -notype_component_declarator0: - notype_declarator maybeasm maybe_attribute maybe_init - { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups, - $3, $2, $4); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups, - $3, $2, $4); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups, - $4, $3); } - | ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield0 (NULL_TREE, $<ftype>0.t, - $<ftype>0.lookups, $3, $2); } - ; - -after_type_component_declarator: - after_type_declarator maybeasm maybe_attribute maybe_init - { $$ = parse_field ($1, $3, $2, $4); } - | tTYPENAME ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield ($1, $4, $3); } - ; - -notype_component_declarator: - notype_declarator maybeasm maybe_attribute maybe_init - { $$ = parse_field ($1, $3, $2, $4); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield ($1, $4, $3); } - | ':' expr_no_commas maybe_attribute - { $$ = parse_bitfield (NULL_TREE, $3, $2); } - ; - -enumlist_opt: - enumlist maybecomma_warn - | maybecomma_warn - ; - -/* We chain the enumerators in reverse order. - Because of the way enums are built, the order is - insignificant. Take advantage of this fact. */ - -enumlist: - enumerator - | enumlist ',' enumerator - ; - -enumerator: - identifier - { build_enumerator ($1, NULL_TREE, current_enum_type); } - | identifier '=' expr_no_commas - { build_enumerator ($1, $3, current_enum_type); } - ; - -/* ISO new-type-id (5.3.4) */ -new_type_id: - type_specifier_seq new_declarator - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | type_specifier_seq %prec EMPTY - { $$.t = build_tree_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - /* GNU extension to allow arrays of arbitrary types with - non-constant dimension. */ - | '(' type_id ')' '[' expr ']' - { - if (pedantic) - pedwarn ("ISO C++ forbids array dimensions with parenthesized type in new"); - $$.t = build_nt (ARRAY_REF, TREE_VALUE ($2.t), $5); - $$.t = build_tree_list (TREE_PURPOSE ($2.t), $$.t); - $$.new_type_flag = $2.new_type_flag; - } - ; - -cv_qualifiers: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | cv_qualifiers CV_QUALIFIER - { $$ = tree_cons (NULL_TREE, $2, $$); } - ; - -nonempty_cv_qualifiers: - CV_QUALIFIER - { $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); - $$.new_type_flag = 0; } - | nonempty_cv_qualifiers CV_QUALIFIER - { $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - | attributes %prec EMPTY - { $$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE); - $$.new_type_flag = 0; } - | nonempty_cv_qualifiers attributes %prec EMPTY - { $$.t = hash_tree_cons ($2, NULL_TREE, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* These rules must follow the rules for function declarations - and component declarations. That way, longer rules are preferred. */ - -/* An expression which will not live on the momentary obstack. */ -maybe_parmlist: - '(' nonnull_exprlist ')' - { $$ = $2; } - | '(' parmlist ')' - { $$ = $2; } - | LEFT_RIGHT - { $$ = empty_parms (); } - | '(' error ')' - { $$ = NULL_TREE; } - ; - -/* A declarator that is allowed only after an explicit typespec. */ - -after_type_declarator_intern: - after_type_declarator - | attributes after_type_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = tree_cons ($1, $2, NULL_TREE); - } - ; - -/* may all be followed by prec '.' */ -after_type_declarator: - '*' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' after_type_declarator_intern %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' after_type_declarator_intern %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers after_type_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | direct_after_type_declarator - ; - -direct_after_type_declarator: - direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | direct_after_type_declarator '[' expr ']' - { $$ = build_nt (ARRAY_REF, $$, $3); } - | direct_after_type_declarator '[' ']' - { $$ = build_nt (ARRAY_REF, $$, NULL_TREE); } - | '(' after_type_declarator_intern ')' - { $$ = $2; } - | nested_name_specifier type_name %prec EMPTY - { push_nested_class ($1, 3); - $$ = build_nt (SCOPE_REF, $$, $2); - TREE_COMPLEXITY ($$) = current_class_depth; } - | type_name %prec EMPTY - ; - -nonnested_type: - type_name %prec EMPTY - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - { - $$ = lookup_name ($1, 1); - maybe_note_name_used_in_class ($1, $$); - } - else - $$ = $1; - } - | global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - ; - -complete_type_name: - nonnested_type - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -nested_type: - nested_name_specifier type_name %prec EMPTY - { $$ = get_type_decl ($2); } - ; - -/* A declarator allowed whether or not there has been - an explicit typespec. These cannot redeclare a typedef-name. */ - -notype_declarator_intern: - notype_declarator - | attributes notype_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = tree_cons ($1, $2, NULL_TREE); - } - ; - -notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | direct_notype_declarator - ; - -complex_notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' complex_notype_declarator %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' complex_notype_declarator %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | complex_direct_notype_declarator - ; - -complex_direct_notype_declarator: - direct_notype_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | '(' complex_notype_declarator ')' - { $$ = $2; } - | direct_notype_declarator '[' expr ']' - { $$ = build_nt (ARRAY_REF, $$, $3); } - | direct_notype_declarator '[' ']' - { $$ = build_nt (ARRAY_REF, $$, NULL_TREE); } - | notype_qualified_id - { enter_scope_of ($1); } - | global_scope notype_qualified_id - { enter_scope_of ($2); $$ = $2;} - | global_scope notype_unqualified_id - { $$ = build_nt (SCOPE_REF, global_namespace, $2); - enter_scope_of ($$); - } - | nested_name_specifier notype_template_declarator - { got_scope = NULL_TREE; - $$ = build_nt (SCOPE_REF, $1, $2); - enter_scope_of ($$); - } - ; - -qualified_id: - nested_name_specifier unqualified_id - { got_scope = NULL_TREE; - $$ = build_nt (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_nt (SCOPE_REF, $1, $2); } - ; - -notype_qualified_id: - nested_name_specifier notype_unqualified_id - { got_scope = NULL_TREE; - $$ = build_nt (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_nt (SCOPE_REF, $1, $2); } - ; - -overqualified_id: - notype_qualified_id - | global_scope notype_qualified_id - { $$ = $2; } - ; - -functional_cast: - typespec '(' nonnull_exprlist ')' - { $$ = build_functional_cast ($1.t, $3); } - | typespec '(' expr_or_declarator_intern ')' - { $$ = reparse_decl_as_expr ($1.t, $3); } - | typespec fcast_or_absdcl %prec EMPTY - { $$ = reparse_absdcl_as_expr ($1.t, $2); } - ; - -type_name: - tTYPENAME - | SELFNAME - | template_type %prec EMPTY - ; - -nested_name_specifier: - nested_name_specifier_1 - | nested_name_specifier nested_name_specifier_1 - { $$ = $2; } - | nested_name_specifier TEMPLATE explicit_template_type SCOPE - { got_scope = $$ - = make_typename_type ($1, $3, tf_error | tf_parsing); } - /* Error handling per Core 125. */ - | nested_name_specifier IDENTIFIER SCOPE - { got_scope = $$ - = make_typename_type ($1, $2, tf_error | tf_parsing); } - | nested_name_specifier PTYPENAME SCOPE - { got_scope = $$ - = make_typename_type ($1, $2, tf_error | tf_parsing); } - ; - -/* Why the @#$%^& do type_name and notype_identifier need to be expanded - inline here?!? (jason) */ -nested_name_specifier_1: - tTYPENAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - { - $$ = lastiddecl; - maybe_note_name_used_in_class ($1, $$); - } - got_scope = $$ = - complete_type (TYPE_MAIN_VARIANT (TREE_TYPE ($$))); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$ = TREE_TYPE ($$); - } - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($1)); } - ; - -typename_sub: - typename_sub0 - | global_scope typename_sub0 - { $$ = $2; } - ; - -typename_sub0: - typename_sub1 identifier %prec EMPTY - { - if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, tf_error | tf_parsing); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 template_type %prec EMPTY - { $$ = TREE_TYPE ($2); } - | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2, tf_error | tf_parsing); } - | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3, tf_error | tf_parsing); } - ; - -typename_sub1: - typename_sub2 - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - error ("`%T' is not a class or namespace", $1); - else if (TREE_CODE ($1) == TYPE_DECL) - $$ = TREE_TYPE ($1); - } - | typename_sub1 typename_sub2 - { - if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, tf_error | tf_parsing); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 explicit_template_type SCOPE - { got_scope = $$ - = make_typename_type ($1, $2, tf_error | tf_parsing); } - | typename_sub1 TEMPLATE explicit_template_type SCOPE - { got_scope = $$ - = make_typename_type ($1, $3, tf_error | tf_parsing); } - ; - -/* This needs to return a TYPE_DECL for simple names so that we don't - forget what name was used. */ -typename_sub2: - tTYPENAME SCOPE - { - if (TREE_CODE ($1) != TYPE_DECL) - $$ = lastiddecl; - - /* Retrieve the type for the identifier, which might involve - some computation. */ - got_scope = complete_type (TREE_TYPE ($$)); - - if ($$ == error_mark_node) - error ("`%T' is not a class or namespace", $1); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) != TYPE_DECL) - $$ = lastiddecl; - got_scope = complete_type (TREE_TYPE ($$)); - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($$)); } - | PTYPENAME SCOPE - | IDENTIFIER SCOPE - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - ; - -explicit_template_type: - identifier '<' template_arg_list_opt template_close_bracket - { $$ = build_min_nt (TEMPLATE_ID_EXPR, $1, $3); } - ; - -complex_type_name: - global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -ptr_to_mem: - nested_name_specifier '*' - { got_scope = NULL_TREE; } - | global_scope nested_name_specifier '*' - { $$ = $2; got_scope = NULL_TREE; } - ; - -/* All uses of explicit global scope must go through this nonterminal so - that got_scope will be set before yylex is called to get the next token. */ -global_scope: - SCOPE - { got_scope = void_type_node; } - ; - -/* ISO new-declarator (5.3.4) */ -new_declarator: - '*' cv_qualifiers new_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '*' cv_qualifiers %prec EMPTY - { $$ = make_pointer_declarator ($2, NULL_TREE); } - | '&' cv_qualifiers new_declarator %prec EMPTY - { $$ = make_reference_declarator ($2, $3); } - | '&' cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers new_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | direct_new_declarator %prec EMPTY - ; - -/* ISO direct-new-declarator (5.3.4) */ -direct_new_declarator: - '[' expr ']' - { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); } - | direct_new_declarator '[' expr ']' - { $$ = build_nt (ARRAY_REF, $$, $3); } - ; - -absdcl_intern: - absdcl - | attributes absdcl - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = tree_cons ($1, $2, NULL_TREE); - } - ; - -/* ISO abstract-declarator (8.1) */ -absdcl: - '*' nonempty_cv_qualifiers absdcl_intern - { $$ = make_pointer_declarator ($2.t, $3); } - | '*' absdcl_intern - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '*' nonempty_cv_qualifiers %prec EMPTY - { $$ = make_pointer_declarator ($2.t, NULL_TREE); } - | '*' %prec EMPTY - { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); } - | '&' nonempty_cv_qualifiers absdcl_intern - { $$ = make_reference_declarator ($2.t, $3); } - | '&' absdcl_intern - { $$ = make_reference_declarator (NULL_TREE, $2); } - | '&' nonempty_cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2.t, NULL_TREE); } - | '&' %prec EMPTY - { $$ = make_reference_declarator (NULL_TREE, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers absdcl_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - | direct_abstract_declarator %prec EMPTY - ; - -/* ISO direct-abstract-declarator (8.1) */ -direct_abstract_declarator: - '(' absdcl_intern ')' - { $$ = $2; } - /* `(typedef)1' is `int'. */ - | direct_abstract_declarator '(' parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $3, $5, $6); } - | direct_abstract_declarator LEFT_RIGHT cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, empty_parms (), $3, $4); } - | direct_abstract_declarator '[' expr ']' %prec '.' - { $$ = build_nt (ARRAY_REF, $$, $3); } - | direct_abstract_declarator '[' ']' %prec '.' - { $$ = build_nt (ARRAY_REF, $$, NULL_TREE); } - | '(' complex_parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator (NULL_TREE, $2, $4, $5); } - | regcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | fcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | '[' expr ']' %prec '.' - { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); } - | '[' ']' %prec '.' - { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); } - ; - -/* For C++, decls and stmts can be intermixed, so we don't need to - have a special rule that won't start parsing the stmt section - until we have a stmt that parses without errors. */ - -stmts: - stmt - | errstmt - | stmts stmt - | stmts errstmt - ; - -errstmt: - error ';' - ; - -/* Read zero or more forward-declarations for labels - that nested functions can jump to. */ -maybe_label_decls: - /* empty */ - | label_decls - { if (pedantic) - pedwarn ("ISO C++ forbids label declarations"); } - ; - -label_decls: - label_decl - | label_decls label_decl - ; - -label_decl: - LABEL identifiers_or_typenames ';' - { - while ($2) - { - finish_label_decl (TREE_VALUE ($2)); - $2 = TREE_CHAIN ($2); - } - } - ; - -compstmt_or_stmtexpr: - save_lineno '{' - { $<ttype>$ = begin_compound_stmt (0); } - compstmtend - { STMT_LINENO ($<ttype>3) = $1; - finish_compound_stmt (0, $<ttype>3); } - ; - -compstmt: - compstmt_or_stmtexpr - { last_expr_type = NULL_TREE; } - ; - -simple_if: - IF - { $<ttype>$ = begin_if_stmt (); - cond_stmt_keyword = "if"; } - paren_cond_or_null - { finish_if_stmt_cond ($3, $<ttype>2); } - implicitly_scoped_stmt - { $$ = $<ttype>2; - finish_then_clause ($<ttype>2); } - ; - -implicitly_scoped_stmt: - compstmt - | - { $<ttype>$ = begin_compound_stmt (0); } - save_lineno simple_stmt - { STMT_LINENO ($<ttype>1) = $2; - if ($3) STMT_LINENO ($3) = $2; - finish_compound_stmt (0, $<ttype>1); } - ; - -stmt: - compstmt - | save_lineno simple_stmt - { if ($2) STMT_LINENO ($2) = $1; } - ; - -simple_stmt: - decl - { finish_stmt (); - $$ = NULL_TREE; } - | expr ';' - { $$ = finish_expr_stmt ($1); } - | simple_if ELSE - { begin_else_clause (); } - implicitly_scoped_stmt - { - $$ = $1; - finish_else_clause ($1); - finish_if_stmt (); - } - | simple_if %prec IF - { $$ = $1; - finish_if_stmt (); } - | WHILE - { - $<ttype>$ = begin_while_stmt (); - cond_stmt_keyword = "while"; - } - paren_cond_or_null - { finish_while_stmt_cond ($3, $<ttype>2); } - implicitly_scoped_stmt - { $$ = $<ttype>2; - finish_while_stmt ($<ttype>2); } - | DO - { $<ttype>$ = begin_do_stmt (); } - implicitly_scoped_stmt WHILE - { - finish_do_body ($<ttype>2); - cond_stmt_keyword = "do"; - } - paren_expr_or_null ';' - { $$ = $<ttype>2; - finish_do_stmt ($6, $<ttype>2); } - | FOR - { $<ttype>$ = begin_for_stmt (); } - '(' for.init.statement - { finish_for_init_stmt ($<ttype>2); } - xcond ';' - { finish_for_cond ($6, $<ttype>2); } - xexpr ')' - { finish_for_expr ($9, $<ttype>2); } - implicitly_scoped_stmt - { $$ = $<ttype>2; - finish_for_stmt ($<ttype>2); } - | SWITCH - { $<ttype>$ = begin_switch_stmt (); } - '(' condition ')' - { finish_switch_cond ($4, $<ttype>2); } - implicitly_scoped_stmt - { $$ = $<ttype>2; - finish_switch_stmt ($<ttype>2); } - | CASE expr_no_commas ':' - { $<ttype>$ = finish_case_label ($2, NULL_TREE); } - stmt - { $$ = $<ttype>4; } - | CASE expr_no_commas ELLIPSIS expr_no_commas ':' - { $<ttype>$ = finish_case_label ($2, $4); } - stmt - { $$ = $<ttype>6; } - | DEFAULT ':' - { $<ttype>$ = finish_case_label (NULL_TREE, NULL_TREE); } - stmt - { $$ = $<ttype>3; } - | BREAK ';' - { $$ = finish_break_stmt (); } - | CONTINUE ';' - { $$ = finish_continue_stmt (); } - | RETURN_KEYWORD ';' - { $$ = finish_return_stmt (NULL_TREE); } - | RETURN_KEYWORD expr ';' - { $$ = finish_return_stmt ($2); } - | asm_keyword maybe_cv_qualifier '(' STRING ')' ';' - { $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE, - NULL_TREE); - ASM_INPUT_P ($$) = 1; } - /* This is the case with just output operands. */ - | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ')' ';' - { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); } - /* This is the case with input operands as well. */ - | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':' - asm_operands ')' ';' - { $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); } - | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ')' ';' - { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); } - /* This is the case with clobbered registers as well. */ - | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':' - asm_operands ':' asm_clobbers ')' ';' - { $$ = finish_asm_stmt ($2, $4, $6, $8, $10); } - | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ':' - asm_clobbers ')' ';' - { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); } - | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands SCOPE - asm_clobbers ')' ';' - { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); } - | GOTO '*' expr ';' - { - if (pedantic) - pedwarn ("ISO C++ forbids computed gotos"); - $$ = finish_goto_stmt ($3); - } - | GOTO identifier ';' - { $$ = finish_goto_stmt ($2); } - | label_colon stmt - { $$ = NULL_TREE; } - | label_colon '}' - { error ("label must be followed by statement"); - yyungetc ('}', 0); - $$ = NULL_TREE; } - | ';' - { finish_stmt (); - $$ = NULL_TREE; } - | try_block - { $$ = NULL_TREE; } - | using_directive - { $$ = NULL_TREE; } - | namespace_using_decl - { do_local_using_decl ($1); - $$ = NULL_TREE; } - | namespace_alias - { $$ = NULL_TREE; } - ; - -function_try_block: - TRY - { $<ttype>$ = begin_function_try_block (); } - function_body - { finish_function_try_block ($<ttype>2); } - handler_seq - { finish_function_handler_sequence ($<ttype>2); } - ; - -try_block: - TRY - { $<ttype>$ = begin_try_block (); } - compstmt - { finish_try_block ($<ttype>2); } - handler_seq - { finish_handler_sequence ($<ttype>2); } - ; - -handler_seq: - handler - | handler_seq handler - | /* empty */ - { /* Generate a fake handler block to avoid later aborts. */ - tree fake_handler = begin_handler (); - finish_handler_parms (NULL_TREE, fake_handler); - finish_handler (fake_handler); - $<ttype>$ = fake_handler; - - error ("must have at least one catch per try block"); - } - ; - -handler: - CATCH - { $<ttype>$ = begin_handler (); } - handler_args - { finish_handler_parms ($3, $<ttype>2); } - compstmt - { finish_handler ($<ttype>2); } - ; - -type_specifier_seq: - typed_typespecs %prec EMPTY - | nonempty_cv_qualifiers %prec EMPTY - ; - -handler_args: - '(' ELLIPSIS ')' - { $$ = NULL_TREE; } - /* This doesn't allow reference parameters, the below does. - | '(' type_specifier_seq absdcl ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' type_specifier_seq ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, NULL_TREE); } - | '(' type_specifier_seq notype_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' typed_typespecs after_type_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - This allows reference parameters... */ - | '(' parm ')' - { - check_for_new_type ("inside exception declarations", $2); - $$ = start_handler_parms (TREE_PURPOSE ($2.t), - TREE_VALUE ($2.t)); - } - ; - -label_colon: - IDENTIFIER ':' - { finish_label_stmt ($1); } - | PTYPENAME ':' - { finish_label_stmt ($1); } - | tTYPENAME ':' - { finish_label_stmt ($1); } - | SELFNAME ':' - { finish_label_stmt ($1); } - ; - -for.init.statement: - xexpr ';' - { finish_expr_stmt ($1); } - | decl - | '{' compstmtend - { if (pedantic) - pedwarn ("ISO C++ forbids compound statements inside for initializations"); - } - ; - -/* Either a type-qualifier or nothing. First thing in an `asm' statement. */ - -maybe_cv_qualifier: - /* empty */ - { $$ = NULL_TREE; } - | CV_QUALIFIER - ; - -xexpr: - /* empty */ - { $$ = NULL_TREE; } - | expr - | error - { $$ = NULL_TREE; } - ; - -/* These are the operands other than the first string and colon - in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ -asm_operands: - /* empty */ - { $$ = NULL_TREE; } - | nonnull_asm_operands - ; - -nonnull_asm_operands: - asm_operand - | nonnull_asm_operands ',' asm_operand - { $$ = chainon ($$, $3); } - ; - -asm_operand: - STRING '(' expr ')' - { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $3); } - | '[' identifier ']' STRING '(' expr ')' - { $2 = build_string (IDENTIFIER_LENGTH ($2), - IDENTIFIER_POINTER ($2)); - $$ = build_tree_list (build_tree_list ($2, $4), $6); } - ; - -asm_clobbers: - STRING - { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);} - | asm_clobbers ',' STRING - { $$ = tree_cons (NULL_TREE, $3, $1); } - ; - -/* This is what appears inside the parens in a function declarator. - Its value is represented in the format that grokdeclarator expects. - - In C++, declaring a function with no parameters - means that that function takes *no* parameters. */ - -parmlist: - /* empty */ - { - $$ = empty_parms(); - } - | complex_parmlist - | type_id - { $$ = finish_parmlist (build_tree_list (NULL_TREE, $1.t), 0); - check_for_new_type ("inside parameter list", $1); } - ; - -/* This nonterminal does not include the common sequence '(' type_id ')', - as it is ambiguous and must be disambiguated elsewhere. */ -complex_parmlist: - parms - { $$ = finish_parmlist ($$, 0); } - | parms_comma ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - /* C++ allows an ellipsis without a separating ',' */ - | parms ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - | type_id ELLIPSIS - { $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 1); } - | ELLIPSIS - { $$ = finish_parmlist (NULL_TREE, 1); } - | parms ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist ($1, 0); - yyungetc (':', 0); - yychar = ')'; - } - | type_id ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 0); - yyungetc (':', 0); - yychar = ')'; - } - ; - -/* A default argument to a */ -defarg: - '=' - { maybe_snarf_defarg (); } - defarg1 - { $$ = $3; } - ; - -defarg1: - DEFARG - | init - ; - -/* A nonempty list of parameter declarations or type names. */ -parms: - named_parm - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - | parm defarg - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list ($2, $1.t); } - | parms_comma full_parm - { check_for_new_type ("in a parameter list", $2); - $$ = chainon ($$, $2.t); } - | parms_comma bad_parm - { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); } - | parms_comma bad_parm '=' init - { $$ = chainon ($$, build_tree_list ($4, $2)); } - ; - -parms_comma: - parms ',' - | type_id ',' - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - ; - -/* A single parameter declaration or parameter type name, - as found in a parmlist. */ -named_parm: - /* Here we expand typed_declspecs inline to avoid mis-parsing of - TYPESPEC IDENTIFIER. */ - typed_declspecs1 declarator - { $$.new_type_flag = $1.new_type_flag; - $$.t = build_tree_list ($1.t, $2); } - | typed_typespecs declarator - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec declarator - { $$.t = build_tree_list (build_tree_list (NULL_TREE, $1.t), - $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_declspecs1 absdcl - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_declspecs1 %prec EMPTY - { $$.t = build_tree_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - | declmods notype_declarator - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = 0; } - ; - -full_parm: - parm - { $$.t = build_tree_list (NULL_TREE, $1.t); - $$.new_type_flag = $1.new_type_flag; } - | parm defarg - { $$.t = build_tree_list ($2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -parm: - named_parm - | type_id - ; - -see_typename: - /* empty */ %prec EMPTY - { see_typename (); } - ; - -bad_parm: - /* empty */ %prec EMPTY - { - error ("type specifier omitted for parameter"); - $$ = build_tree_list (integer_type_node, NULL_TREE); - } - | notype_declarator - { - if (TREE_CODE ($$) == SCOPE_REF) - { - if (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_OPERAND ($$, 0)) == BOUND_TEMPLATE_TEMPLATE_PARM) - error ("`%E' is not a type, use `typename %E' to make it one", $$, $$); - else - error ("no type `%D' in `%T'", TREE_OPERAND ($$, 1), TREE_OPERAND ($$, 0)); - } - else - error ("type specifier omitted for parameter `%E'", $$); - $$ = build_tree_list (integer_type_node, $$); - } - ; - -bad_decl: - IDENTIFIER template_arg_list_ignore IDENTIFIER arg_list_ignore ';' - { - error("'%D' is used as a type, but is not defined as a type.", $1); - $3 = error_mark_node; - } - ; - -template_arg_list_ignore: - '<' template_arg_list_opt template_close_bracket - { } - | /* empty */ - ; - -arg_list_ignore: - '(' nonnull_exprlist ')' - { } - | /* empty */ - ; - -exception_specification_opt: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | THROW '(' ansi_raise_identifiers ')' %prec EMPTY - { $$ = $3; } - | THROW LEFT_RIGHT %prec EMPTY - { $$ = empty_except_spec; } - ; - -ansi_raise_identifier: - type_id - { - check_for_new_type ("exception specifier", $1); - $$ = groktypename ($1.t); - } - | error - { $$ = error_mark_node; } - ; - -ansi_raise_identifiers: - ansi_raise_identifier - { $$ = add_exception_specifier (NULL_TREE, $1, 1); } - | ansi_raise_identifiers ',' ansi_raise_identifier - { $$ = add_exception_specifier ($1, $3, 1); } - ; - -conversion_declarator: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '*' cv_qualifiers conversion_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '&' cv_qualifiers conversion_declarator - { $$ = make_reference_declarator ($2, $3); } - | ptr_to_mem cv_qualifiers conversion_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_nt (SCOPE_REF, $1, arg); - } - ; - -operator: - OPERATOR - { - saved_scopes = tree_cons (got_scope, got_object, saved_scopes); - TREE_LANG_FLAG_0 (saved_scopes) = looking_for_typename; - /* We look for conversion-type-id's in both the class and current - scopes, just as for ID in 'ptr->ID::'. */ - looking_for_typename = 1; - got_object = got_scope; - got_scope = NULL_TREE; - } - ; - -unoperator: - { got_scope = TREE_PURPOSE (saved_scopes); - got_object = TREE_VALUE (saved_scopes); - looking_for_typename = TREE_LANG_FLAG_0 (saved_scopes); - saved_scopes = TREE_CHAIN (saved_scopes); - $$ = got_scope; - } - ; - -operator_name: - operator '*' unoperator - { $$ = frob_opname (ansi_opname (MULT_EXPR)); } - | operator '/' unoperator - { $$ = frob_opname (ansi_opname (TRUNC_DIV_EXPR)); } - | operator '%' unoperator - { $$ = frob_opname (ansi_opname (TRUNC_MOD_EXPR)); } - | operator '+' unoperator - { $$ = frob_opname (ansi_opname (PLUS_EXPR)); } - | operator '-' unoperator - { $$ = frob_opname (ansi_opname (MINUS_EXPR)); } - | operator '&' unoperator - { $$ = frob_opname (ansi_opname (BIT_AND_EXPR)); } - | operator '|' unoperator - { $$ = frob_opname (ansi_opname (BIT_IOR_EXPR)); } - | operator '^' unoperator - { $$ = frob_opname (ansi_opname (BIT_XOR_EXPR)); } - | operator '~' unoperator - { $$ = frob_opname (ansi_opname (BIT_NOT_EXPR)); } - | operator ',' unoperator - { $$ = frob_opname (ansi_opname (COMPOUND_EXPR)); } - | operator ARITHCOMPARE unoperator - { $$ = frob_opname (ansi_opname ($2)); } - | operator '<' unoperator - { $$ = frob_opname (ansi_opname (LT_EXPR)); } - | operator '>' unoperator - { $$ = frob_opname (ansi_opname (GT_EXPR)); } - | operator EQCOMPARE unoperator - { $$ = frob_opname (ansi_opname ($2)); } - | operator ASSIGN unoperator - { $$ = frob_opname (ansi_assopname ($2)); } - | operator '=' unoperator - { $$ = frob_opname (ansi_assopname (NOP_EXPR)); } - | operator LSHIFT unoperator - { $$ = frob_opname (ansi_opname ($2)); } - | operator RSHIFT unoperator - { $$ = frob_opname (ansi_opname ($2)); } - | operator PLUSPLUS unoperator - { $$ = frob_opname (ansi_opname (POSTINCREMENT_EXPR)); } - | operator MINUSMINUS unoperator - { $$ = frob_opname (ansi_opname (PREDECREMENT_EXPR)); } - | operator ANDAND unoperator - { $$ = frob_opname (ansi_opname (TRUTH_ANDIF_EXPR)); } - | operator OROR unoperator - { $$ = frob_opname (ansi_opname (TRUTH_ORIF_EXPR)); } - | operator '!' unoperator - { $$ = frob_opname (ansi_opname (TRUTH_NOT_EXPR)); } - | operator '?' ':' unoperator - { $$ = frob_opname (ansi_opname (COND_EXPR)); } - | operator MIN_MAX unoperator - { $$ = frob_opname (ansi_opname ($2)); } - | operator POINTSAT unoperator %prec EMPTY - { $$ = frob_opname (ansi_opname (COMPONENT_REF)); } - | operator POINTSAT_STAR unoperator %prec EMPTY - { $$ = frob_opname (ansi_opname (MEMBER_REF)); } - | operator LEFT_RIGHT unoperator - { $$ = frob_opname (ansi_opname (CALL_EXPR)); } - | operator '[' ']' unoperator - { $$ = frob_opname (ansi_opname (ARRAY_REF)); } - | operator NEW unoperator %prec EMPTY - { $$ = frob_opname (ansi_opname (NEW_EXPR)); } - | operator DELETE unoperator %prec EMPTY - { $$ = frob_opname (ansi_opname (DELETE_EXPR)); } - | operator NEW '[' ']' unoperator - { $$ = frob_opname (ansi_opname (VEC_NEW_EXPR)); } - | operator DELETE '[' ']' unoperator - { $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); } - | operator type_specifier_seq conversion_declarator unoperator - { $$ = frob_opname (grokoptypename ($2.t, $3, $4)); } - | operator error unoperator - { $$ = frob_opname (ansi_opname (ERROR_MARK)); } - ; - -/* The forced readahead in here is because we might be at the end of a - line, and lineno won't be bumped until yylex absorbs the first token - on the next line. */ -save_lineno: - { if (yychar == YYEMPTY) - yychar = YYLEX; - $$ = lineno; } - ; -%% - -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} -#endif - -/* Free malloced parser stacks if necessary. */ - -void -free_parser_stacks () -{ - if (malloced_yyss) - { - free (malloced_yyss); - free (malloced_yyvs); - } -} - -/* Return the value corresponding to TOKEN in the global scope. */ - -static tree -parse_scoped_id (token) - tree token; -{ - cxx_binding binding; - - cxx_binding_clear (&binding); - if (!qualified_lookup_using_namespace (token, global_namespace, &binding, 0)) - binding.value = NULL; - if (yychar == YYEMPTY) - yychar = yylex(); - - return do_scoped_id (token, binding.value); -} - -/* AGGR may be either a type node (like class_type_node) or a - TREE_LIST whose TREE_PURPOSE is a list of attributes and whose - TREE_VALUE is a type node. Set *TAG_KIND and *ATTRIBUTES to - represent the information encoded. */ - -static void -parse_split_aggr (tree aggr, enum tag_types *tag_kind, tree *attributes) -{ - if (TREE_CODE (aggr) == TREE_LIST) - { - *attributes = TREE_PURPOSE (aggr); - aggr = TREE_VALUE (aggr); - } - else - *attributes = NULL_TREE; - *tag_kind = (enum tag_types) tree_low_cst (aggr, 1); -} - -/* Like xref_tag, except that the AGGR may be either a type node (like - class_type_node) or a TREE_LIST whose TREE_PURPOSE is a list of - attributes and whose TREE_VALUE is a type node. */ - -static tree -parse_xref_tag (tree aggr, tree name, int globalize) -{ - tree attributes; - enum tag_types tag_kind; - parse_split_aggr (aggr, &tag_kind, &attributes); - return xref_tag (tag_kind, name, attributes, globalize); -} - -/* Like handle_class_head, but AGGR may be as for parse_xref_tag. */ - -static tree -parse_handle_class_head (tree aggr, tree scope, tree id, - int defn_p, int *new_type_p) -{ - tree attributes; - enum tag_types tag_kind; - parse_split_aggr (aggr, &tag_kind, &attributes); - return handle_class_head (tag_kind, scope, id, attributes, - defn_p, new_type_p); -} - -/* Like do_decl_instantiation, but the declarator has not yet been - parsed. */ - -static void -parse_decl_instantiation (tree declspecs, tree declarator, tree storage) -{ - tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL); - do_decl_instantiation (decl, storage); -} - -/* Like begin_function_definition, but SPECS_ATTRS is a combined list - containing both a decl-specifier-seq and attributes. */ - -static int -parse_begin_function_definition (tree specs_attrs, tree declarator) -{ - tree specs; - tree attrs; - - split_specs_attrs (specs_attrs, &specs, &attrs); - return begin_function_definition (specs, attrs, declarator); -} - -/* Like finish_call_expr, but the name for FN has not yet been - resolved. */ - -static tree -parse_finish_call_expr (tree fn, tree args, int koenig) -{ - bool disallow_virtual; - - if (TREE_CODE (fn) == OFFSET_REF) - return build_offset_ref_call_from_tree (fn, args); - - if (TREE_CODE (fn) == SCOPE_REF) - { - tree scope = TREE_OPERAND (fn, 0); - tree name = TREE_OPERAND (fn, 1); - - if (scope == error_mark_node || name == error_mark_node) - return error_mark_node; - if (!processing_template_decl) - fn = resolve_scoped_fn_name (scope, name); - disallow_virtual = true; - } - else - disallow_virtual = false; - - if (koenig && TREE_CODE (fn) == IDENTIFIER_NODE) - { - tree f; - - /* Do the Koenig lookup. */ - fn = do_identifier (fn, 2, args); - /* If name lookup didn't find any matching declarations, we've - got an unbound identifier. */ - if (TREE_CODE (fn) == IDENTIFIER_NODE) - { - /* For some reason, do_identifier does not resolve - conversion operator names if the only matches would be - template conversion operators. So, we do it here. */ - if (IDENTIFIER_TYPENAME_P (fn) && current_class_type) - { - f = lookup_member (current_class_type, fn, - /*protect=*/1, /*want_type=*/0); - if (f) - return finish_call_expr (f, args, - /*disallow_virtual=*/false); - } - /* If the name still could not be resolved, then the program - is ill-formed. */ - if (TREE_CODE (fn) == IDENTIFIER_NODE) - { - unqualified_name_lookup_error (fn); - return error_mark_node; - } - } - else if (TREE_CODE (fn) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (fn) - || TREE_CODE (fn) == OVERLOAD) - { - tree scope = DECL_CONTEXT (get_first_fn (fn)); - if (scope && TYPE_P (scope)) - { - tree access_scope; - - if (DERIVED_FROM_P (scope, current_class_type) - && current_class_ref) - { - fn = build_baselink (lookup_base (current_class_type, - scope, - ba_any, - NULL), - TYPE_BINFO (current_class_type), - fn, - /*optype=*/NULL_TREE); - return finish_object_call_expr (fn, - current_class_ref, - args); - } - - - access_scope = current_class_type; - while (!DERIVED_FROM_P (scope, access_scope)) - { - access_scope = TYPE_CONTEXT (access_scope); - while (DECL_P (access_scope)) - access_scope = DECL_CONTEXT (access_scope); - } - - fn = build_baselink (NULL_TREE, - TYPE_BINFO (access_scope), - fn, - /*optype=*/NULL_TREE); - } - } - } - - if (TREE_CODE (fn) == COMPONENT_REF) - /* If the parser sees `(x->y)(bar)' we get here because the - parentheses confuse the parser. Treat this like - `x->y(bar)'. */ - return finish_object_call_expr (TREE_OPERAND (fn, 1), - TREE_OPERAND (fn, 0), - args); - - if (processing_template_decl) - return build_nt (CALL_EXPR, fn, args, NULL_TREE); - - return build_call_from_tree (fn, args, disallow_virtual); -} - -#include "gt-cp-parse.h" diff --git a/contrib/gcc/cp/reno.texi b/contrib/gcc/cp/reno.texi deleted file mode 100644 index 59c3448..0000000 --- a/contrib/gcc/cp/reno.texi +++ /dev/null @@ -1,752 +0,0 @@ -\input texinfo @c -*- Texinfo -*- -@setfilename reno-1.info - -@ifinfo -@format -START-INFO-DIR-ENTRY -* Reno 1: (reno-1). The GNU C++ Renovation Project, Phase 1. -END-INFO-DIR-ENTRY -@end format -@end ifinfo - -@ifinfo -Copyright @copyright{} 1992, 1993, 1994 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries a copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo - -@setchapternewpage odd -@settitle GNU C++ Renovation Project -@c @smallbook - -@titlepage -@finalout -@title GNU C++ Renovation Project -@subtitle Phase 1.3 -@author Brendan Kehoe, Jason Merrill, -@author Mike Stump, Michael Tiemann -@page - -Edited March, 1994 by Roland Pesch (@code{pesch@@cygnus.com}) -@vskip 0pt plus 1filll -Copyright @copyright{} 1992, 1993, 1994 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). -@end ignore - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that -the entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end titlepage - -@ifinfo -@node Top -@top @sc{gnu} C++ Renovation Project - -This file describes the goals of the @sc{gnu} C++ Renovation Project, -and its accomplishments to date (as of Phase 1.3). - -It also discusses the remaining divergences from @sc{gnu} C++, and how the -name encoding in @sc{gnu} C++ differs from the sample encoding in -@cite{The Annotated C++ Reference Manual}. -@c This is not a good place to introduce the acronym ARM because it's -@c info-only. - -@menu -* Introduction:: What is the GNU C++ Renovation Project? -* Changes:: Summary of changes since previous GNU C++ releases. -* Plans:: Plans for Reno-2. -* Templates:: The template implementation. -* ANSI:: GNU C++ conformance to ANSI C++. -* Encoding:: Name encoding in GNU C++. -@end menu - -@end ifinfo - -@node Introduction -@chapter Introduction - -As you may remember, @sc{gnu} C++ was the first native-code C++ -compiler available under Unix (December 1987). In November 1988, it was -judged superior to the AT&T compiler in a Unix World review. In 1990 it -won a Sun Observer ``Best-Of'' award. But now, with new requirements -coming out of the @sc{ansi} C++ committee and a growing backlog of bugs, it's -clear that @sc{gnu} C++ needs an overhaul. - -The C++ language has been under development since 1982. It has -evolved significantly since its original incarnation (C with Classes), -addressing many commercial needs and incorporating many lessons -learned as more and more people started using ``object-oriented'' -programming techniques. In 1989, the first X3J16 committee meeting -was held in Washington DC; in the interest of users, C++ was going to -be standardized. - -As C++ has become more popular, more demands have been placed on its -compilers. Some compilers are up to the demands, others are not. -@sc{gnu} C++ was used to prototype several features which have since -been incorporated into the standard, most notably exception handling. -While @sc{gnu} C++ has been an excellent experimental vehicle, it did -not have the resources that AT&T, Borland, or Microsoft have at their -disposal. - -We believe that @sc{gnu} C++ is an important compiler, providing users with -many of the features that have made @sc{gnu} C so popular: fast compilation, -good error messages, innovative features, and full sources that may be -freely redistributed. The purpose of this overhaul, dubbed the @var{@sc{gnu} -C++ Renovation Project}, is to take advantage of the functionality that -@sc{gnu} C++ offers today, to strengthen its base technology, and put it in a -position to remain---as other @sc{gnu} software currently is---the technical -leader in the field. - -This release represents the latest phase of work in strengthening the -compiler on a variety of points. It includes many months of -work concentrated on fixing many of the more egregious bugs that -presented themselves in the compiler recently. -@ignore -@c FIXME-- update? -Nearly 85% of all bugs reported in the period of February to September -of 1992 were fixed as part of the work in the first phase. -@end ignore -In the coming months, we hope to continue expanding and enhancing the -quality and dependability of the industry's only freely redistributable -C++ compiler. - -@node Changes -@chapter Changes in Behavior in @sc{gnu} C++ - -The @sc{gnu} C++ compiler continues to improve and change. A major goal -of our work has been to continue to bring the compiler into compliance -with the draft @sc{ansi} C++ standard, and with @cite{The Annotated C++ -Reference Manual} (the @sc{arm}). This section outlines most of the -user-noticeable changes that might be encountered during the normal -course of use. - -@menu -* Summary of Phase 1.3:: -* Major changes:: -* New features:: -* Enhancements and bug fixes:: -* Problems with debugging:: -@end menu - -@node Summary of Phase 1.3 -@section Summary of Changes in Phase 1.3 - -The bulk of this note discusses the cumulative effects of the @sc{gnu} C++ -Renovation Project to date. The work during its most recent phase (1.3) -had these major effects: - -@itemize @bullet -@item The standard compiler driver @code{g++} is now the faster compiled -version, rather than a shell script. - -@item Nested types work much better; notably, nesting is no longer -restricted to nine levels. - -@item Better @sc{arm} conformance on member access control. - -@item The compiler now always generates default assignment operators -(@samp{operator =}), copy constructors (@samp{X::X(X&)}), and default -constructors (@samp{X::X()}) whenever they are required. - -@item The new draft @sc{ansi} standard keyword @code{mutable} is supported. - -@item @samp{-fansi-overloading} is the default, to comply better with -the @sc{arm} (at some cost in compatibility to earlier versions of @sc{gnu} C++). - -@item More informative error messages. - -@item System include files are automatically treated as if they were -wrapped in @samp{extern "C" @{ @}}. - -@item The new option @samp{-falt-external-templates} provides alternate -template instantiation semantics. - -@item Operator declarations are now checked more strictly. - -@item You can now use template type arguments in the template parameter list. - -@item You can call the destructor for any type. - -@item The compiler source code is better organized. - -@item You can specify where to instantiate template definitions explicitly. -@end itemize - -Much of the work in Phase 1.3 went to elimination of known bugs, as well -as the major items above. - -During the span of Phase 1.3, there were also two changes associated -with the compiler that, while not specifically part of the C++ -Renovation project, may be of interest: - -@itemize @bullet -@item @code{gcov}, a code coverage tool for @sc{gnu cc}, is now available -from Cygnus Support. (@code{gcov} is free software, but the @sc{fsf} has not -yet accepted it.) @xref{Gcov,, @code{gcov}: a Test Coverage Program, -gcc.info, Using GNU CC}, for more information (in Cygnus releases of -that manual). - -@item @sc{gnu} C++ now supports @dfn{signatures}, a language extension to -provide more flexibility in abstract type definitions. @xref{C++ -Signatures,, Type Abstraction using Signatures, gcc.info, Using GNU CC}. -@end itemize - -@node Major changes -@section Major Changes - -This release includes four wholesale rewrites of certain areas of -compiler functionality: - -@enumerate 1 -@item Argument matching. @sc{gnu} C++ is more compliant with the rules -described in Chapter 13, ``Overloading'', of the @sc{arm}. This behavior is -the default, though you can specify it explicitly with -@samp{-fansi-overloading}. For compatibility with earlier releases of -@sc{gnu} C++, specify @samp{-fno-ansi-overloading}; this makes the compiler -behave as it used to with respect to argument matching and name overloading. - -@item Default constructors/destructors. Section 12.8 of the @sc{arm}, ``Copying -Class Objects'', and Section 12.1, ``Constructors'', state that a -compiler must declare such default functions if the user does not -specify them. @sc{gnu} C++ now declares, and generates when necessary, -the defaults for constructors and destructors you might omit. In -particular, assignment operators (@samp{operator =}) behave the same way -whether you define them, or whether the compiler generates them by -default; taking the address of the default @samp{operator =} is now -guaranteed to work. Default copy constructors (@samp{X::X(X&)}) now -function correctly, rather than calling the copy assignment operator for -the base class. Finally, constructors (@samp{X::X()}), as well as -assignment operators and copy constructors, are now available whenever -they are required. - -@c XXX This may be taken out eventually... -@item Binary incompatibility. There are no new binary incompatibilities -in Phase 1.3, but Phase 1.2 introduced two binary incompatibilities with -earlier releases. First, the functionality of @samp{operator -new} and @samp{operator delete} changed. Name encoding -(``mangling'') of virtual table names changed as well. Libraries -built with versions of the compiler earlier than Phase 1.2 must be -compiled with the new compiler. (This includes the Cygnus Q2 -progressive release and the FSF 2.4.5 release.) - -@item New @code{g++} driver. -A new binary @code{g++} compiler driver replaces the shell script. -The new driver executes faster. -@end enumerate - -@node New features -@section New features - -@itemize @bullet -@item -The compiler warns when a class contains only private constructors -or destructors, and has no friends. At the request of some of our -customers, we have added a new option, @samp{-Wctor-dtor-privacy} (on by -default), and its negation, @samp{-Wno-ctor-dtor-privacy}, to control -the emission of this warning. If, for example, you are working towards -making your code compile warning-free, you can use @w{@samp{-Wall --Wno-ctor-dtor-privacy}} to find the most common warnings. - -@item -There is now a mechanism which controls exactly when templates are -expanded, so that you can reduce memory usage and program size and also -instantiate them exactly once. You can control this mechanism with the -option @samp{-fexternal-templates} and its corresponding negation -@samp{-fno-external-templates}. Without this feature, space consumed by -template instantiations can grow unacceptably in large-scale projects -with many different source files. The default is -@samp{-fno-external-templates}. - -You do not need to use the @samp{-fexternal-templates} option when -compiling a file that does not define and instantiate templates used in -other files, even if those files @emph{are} compiled with -@samp{-fexternal-templates}. The only side effect is an increase in -object size for each file that was compiled without -@samp{-fexternal-templates}. - -When your code is compiled with @samp{-fexternal-templates}, all -template instantiations are external; this requires that the templates -be under the control of @samp{#pragma interface} and @samp{#pragma -implementation}. All instantiations that will be needed should be in -the implementation file; you can do this with a @code{typedef} that -references the instantiation needed. Conversely, when you compile using -the option @samp{-fno-external-templates}, all template instantiations are -explicitly internal. - -@samp{-fexternal-templates} also allows you to finally separate class -template function definitions from their declarations, thus speeding up -compilation times for every file that includes the template declaration. -Now you can have tens or even hundreds of lines in template -declarations, and thousands or tens of thousands of lines in template -definitions, with the definitions only going through the compiler once -instead of once for each source file. It is important to note that you -must remember to externally instantiate @emph{all} templates that are -used from template declarations in interface files. If you forget to do -this, unresolved externals will occur. - -In the example below, the object file generated (@file{example.o}) will -contain the global instantiation for @samp{Stack<int>}. If other types -of @samp{Stack} are needed, they can be added to @file{example.cc} or -placed in a new file, in the same spirit as @file{example.cc}. - -@code{foo.h}: -@smallexample -@group -#pragma interface "foo.h" -template<class T> -class Stack @{ - static int statc; - static T statc2; - Stack() @{ @} - virtual ~Stack() @{ @} - int bar(); -@}; -@end group -@end smallexample - -@code{example.cc}: -@smallexample -@group -#pragma implementation "foo.h" -#include "foo.h" - -typedef Stack<int> t; -int Stack<int>::statc; -int Stack<int>::statc2; -int Stack<int>::bar() @{ @} -@end group -@end smallexample - -Note that using @samp{-fexternal-templates} does not reduce memory usage -from completely different instantiations (@samp{Stack<Name>} vs. -@samp{Stack<Net_Connection>}), but only collapses different occurrences -of @samp{Stack<Name>} so that only one @samp{Stack<Name>} is generated. - -@samp{-falt-external-templates} selects a slight variation in the -semantics described above (incidentally, you need not specify both -options; @samp{-falt-external-templates} implies -@samp{-fexternal-templates}). - -With @samp{-fexternal-templates}, the compiler emits a definition in the -implementation file that includes the header definition, @emph{even if} -instantiation is triggered from a @emph{different} implementation file -(e.g. with a template that uses another template). - -With @samp{-falt-external-templates}, the definition always goes in the -implementation file that triggers instantiation. - -For instance, with these two header files--- - -@example -@exdent @file{a.h}: -#pragma interface -template <class T> class A @{ @dots{} @}; - -@exdent @file{b.h}: -#pragma interface -class B @{ @dots{} @}; -void f (A<B>); -@end example - -Under @samp{-fexternal-templates}, the definition of @samp{A<B>} ends up -in the implementation file that includes @file{a.h}. Under -@samp{-falt-external-templates}, the same definition ends up in the -implementation file that includes @file{b.h}. - -@item -You can control explicitly where a template is instantiated, without -having to @emph{use} the template to get an instantiation. - -To instantiate a class template explicitly, write @samp{template -class @var{name}<paramvals>}, where @var{paramvals} is a list of values -for the template parameters. For example, you might write - -@example -template class A<int> -@end example - -Similarly, to instantiate a function template explicitly, write -@samp{template @var{fnsign}} where @var{fnsign} is the particular -function signature you need. For example, you might write - -@example -template void foo (int, int) -@end example - -This syntax for explicit template instantiation agrees with recent -extensions to the draft @sc{ansi} standard. - -@item -The compiler's actions on @sc{ansi}-related warnings and errors have -been further enhanced. The @samp{-pedantic-errors} option produces -error messages in a number of new situations: using @code{return} in a -non-@code{void} function (one returning a value); declaring a local -variable that shadows a parameter (e.g., the function takes an argument -@samp{a}, and has a local variable @samp{a}); and use of the @samp{asm} -keyword. Finally, the compiler by default now issues a warning when -converting from an @code{int} to an enumerated type. This is likely to -cause many new warnings in code that hadn't triggered them before. For -example, when you compile this code, - -@smallexample -@group -enum boolean @{ false, true @}; -void -f () -@{ - boolean x; - - x = 1; //@i{assigning an @code{int} to an @code{enum} now triggers a warning} -@} -@end group -@end smallexample - -@noindent -you should see the warning ``@code{anachronistic conversion from integer -type to enumeral type `boolean'}''. Instead of assigning the value 1, -assign the original enumerated value @samp{true}. -@end itemize - -@node Enhancements and bug fixes -@section Enhancements and bug fixes - -@itemize @bullet -@cindex nested types in template parameters -@item -You can now use nested types in a template parameter list, even if the nested -type is defined within the same class that attempts to use the template. -For example, given a template @code{list}, the following now works: - -@smallexample -struct glyph @{ - @dots{} - struct stroke @{ @dots{} @}; - list<stroke> l; - @dots{} -@} -@end smallexample - -@cindex function pointers vs template parameters -@item -Function pointers now work in template parameter lists. For -example, you might want to instantiate a parameterized @code{list} class -in terms of a pointer to a function like this: - -@smallexample -list<int (*)(int, void *)> fnlist; -@end smallexample - -@item -@c FIXME! Really no limit? Jason said "deeper than 9" now OK... -Nested types are now handled correctly. In particular, there is no -longer a limit to how deeply you can nest type definitions. - -@item -@sc{gnu} C++ now conforms to the specifications in Chapter 11 of the -@sc{arm}, ``Member Access Control''. - -@item -The @sc{ansi} C++ committee has introduced a new keyword @code{mutable}. -@sc{gnu} C++ supports it. Use @code{mutable} to specify that some -particular members of a @code{const} class are @emph{not} constant. For -example, you can use this to include a cache in a data structure that -otherwise represents a read-only database. - -@item -Error messages now explicitly specify the declaration, type, or -expression that contains an error. - -@item -To avoid copying and editing all system include files during @sc{gnu} -C++ installation, the compiler now automatically recognizes system -include files as C language definitions, as if they were wrapped in -@samp{extern "C" @{ @dots{} @}}. - -@item -The compiler checks operator declarations more strictly. For example, -you may no longer declare an @samp{operator +} with three arguments. - -@item -You can now use template type arguments in the same template -parameter list where the type argument is specified (as well as in the -template body). For example, you may write - -@example -template <class T, T t> class A @{ @dots{} @}; -@end example - -@item -Destructors are now available for all types, even built-in ones; for -example, you can call @samp{int::~int}. (Destructors for types like -@code{int} do not actually do anything, but their existence provides a -level of generality that permits smooth template expansion in more -cases.) - -@item -Enumerated types declared inside a class are now handled correctly. - -@item -An argument list for a function may not use an initializer list for its default -value. For example, @w{@samp{void foo ( T x = @{ 1, 2 @} )}} is not permitted. - -@item -A significant amount of work went into improving the ability of the -compiler to act accurately on multiple inheritance and virtual -functions. Virtual function dispatch has been enhanced as well. - -@item -The warning concerning a virtual inheritance environment with a -non-virtual destructor has been disabled, since it is not clear that -such a warning is warranted. - -@item -Until exception handling is fully implemented in the Reno-2 release, use -of the identifiers @samp{catch}, @samp{throw}, or @samp{try} results -in the warning: - -@smallexample -t.C:1: warning: `catch', `throw', and `try' - are all C++ reserved words -@end smallexample - -@item -When giving a warning or error concerning initialization of a member in a -class, the compiler gives the name of the member if it has one. - -@item -Detecting friendship between classes is more accurately checked. - -@item -The syntaxes of @w{@samp{#pragma implementation "file.h"}} and -@samp{#pragma interface} are now more strictly controlled. The compiler -notices (and warns) when any text follows @file{file.h} in the -implementation pragma, or follows the word @samp{interface}. Any such -text is otherwise ignored. - -@item -Trying to declare a template on a variable or type is now considered an -error, not an unimplemented feature. - -@item -When an error occurs involving a template, the compiler attempts to -tell you at which point of instantiation the error occurred, in -addition to noting the line in the template declaration which had the -actual error. - -@item -The symbol names for function templates in the resulting assembly file -are now encoded according to the arguments, rather than just being -emitted as, for example, two definitions of a function @samp{foo}. - -@item -Template member functions that are declared @code{static} no longer -receive a @code{this} pointer. - -@item -Case labels are no longer allowed to have commas to make up their -expressions. - -@item -Warnings concerning the shift count of a left or right shift now tell -you if it was a @samp{left} or @samp{right} shift. - -@item -The compiler now warns when a decimal constant is so large that it -becomes @code{unsigned}. - -@item -Union initializers which are raw constructors are now handled properly. - -@item -The compiler no longer gives incorrect errors when initializing a -union with an empty initializer list. - -@item -Anonymous unions are now correctly used when nested inside a class. - -@item -Anonymous unions declared as static class members are now handled -properly. - -@item -The compiler now notices when a field in a class is declared both as -a type and a non-type. - -@item -The compiler now warns when a user-defined function shadows a -built-in function, rather than emitting an error. - -@item -A conflict between two function declarations now produces an error -regardless of their language context. - -@item -Duplicate definitions of variables with @samp{extern "C"} linkage are no -longer considered in error. (Note in C++ linkage---the default---you may -not have more than one definition of a variable.) - -@item -Referencing a label that is not defined in any function is now an error. - -@item -The syntax for pointers to methods has been improved; there are still -some minor bugs, but a number of cases should now be accepted by the -compiler. - -@item -In error messages, arguments are now numbered starting at 1, instead of -0. Therefore, in the function @samp{void foo (int a, int b)}, the -argument @samp{a} is argument 1, and @samp{b} is argument 2. There is -no longer an argument 0. - -@item -The tag for an enumerator, rather than its value, used as a default -argument is now shown in all error messages. For example, @w{@samp{void -foo (enum x (= true))}} is shown instead of @w{@samp{void foo (enum x (= -1))}}. - -@item -The @samp{__asm__} keyword is now accepted by the C++ front-end. - -@item -Expressions of the form @samp{foo->~Class()} are now handled properly. - -@item -The compiler now gives better warnings for situations which result in -integer overflows (e.g., in storage sizes, enumerators, unary -expressions, etc). - -@item -@code{unsigned} bitfields are now promoted to @code{signed int} if the -field isn't as wide as an @code{int}. - -@item -Declaration and usage of prefix and postfix @samp{operator ++} and -@samp{operator --} are now handled correctly. For example, - -@smallexample -@group -class foo -@{ -public: - operator ++ (); - operator ++ (int); - operator -- (); - operator -- (int); -@}; - -void -f (foo *f) -@{ - f++; // @i{call @code{f->operator++(int)}} - ++f; // @i{call @code{f->operator++()}} - f--; // @i{call @code{f->operator++(int)}} - --f; // @i{call @code{f->operator++()}} -@} -@end group -@end smallexample - -@item -In accordance with @sc{arm} section 10.1.1, ambiguities and dominance are now -handled properly. The rules described in section 10.1.1 are now fully -implemented. - -@end itemize - -@node Problems with debugging -@section Problems with debugging - -Two problems remain with regard to debugging: - -@itemize @bullet -@item -Debugging of anonymous structures on the IBM RS/6000 host is incorrect. - -@item -Symbol table size is overly large due to redundant symbol information; -this can make @code{gdb} coredump under certain circumstances. This -problem is not host-specific. -@end itemize - -@node Plans -@chapter Plans for Reno-2 - -The overall goal for the second phase of the @sc{gnu} C++ Renovation -Project is to bring @sc{gnu} C++ to a new level of reliability, quality, -and competitiveness. As particular elements of this strategy, we intend -to: - -@enumerate 0 -@item -Fully implement @sc{ansi} exception handling. - -@item -With the exception handling, add Runtime Type Identification -(@sc{rtti}), if the @sc{ansi} committee adopts it into the standard. - -@item -Bring the compiler into closer compliance with the @sc{arm} and the draft -@sc{ansi} standard, and document what points in the @sc{arm} we do not yet comply, -or agree, with. - -@item -Add further support for the @sc{dwarf} debugging format. - -@item -Finish the work to make the compiler compliant with @sc{arm} Section 12.6.2, -initializing base classes in declaration order, rather than in the order -that you specify them in a @var{mem-initializer} list. - -@item -Perform a full coverage analysis on the compiler, and weed out unused -code, for a gain in performance and a reduction in the size of the compiler. - -@item -Further improve the multiple inheritance implementation in the -compiler to make it cleaner and more complete. -@end enumerate - -@noindent -As always, we encourage you to make suggestions and ask questions about -@sc{gnu} C++ as a whole, so we can be sure that the end of this project -will bring a compiler that everyone will find essential for C++ and will -meet the needs of the world's C++ community. - -@include templates.texi - -@include gpcompare.texi - -@contents - -@bye diff --git a/contrib/gcc/cp/spew.c b/contrib/gcc/cp/spew.c deleted file mode 100644 index 5bd3fdf..0000000 --- a/contrib/gcc/cp/spew.c +++ /dev/null @@ -1,1558 +0,0 @@ -/* Type Analyzer for GNU C++. - Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Hacked... nay, bludgeoned... by Mark Eichin (eichin@cygnus.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) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG - when compiling parse.c and spew.c. */ - -#include "config.h" -#include "system.h" -#include "input.h" -#include "tree.h" -#include "cp-tree.h" -#include "cpplib.h" -#include "c-pragma.h" -#include "lex.h" -#include "parse.h" -#include "flags.h" -#include "obstack.h" -#include "toplev.h" -#include "ggc.h" -#include "intl.h" -#include "timevar.h" - -#ifdef SPEW_DEBUG -#define SPEW_INLINE -#else -#define SPEW_INLINE inline -#endif - -/* This takes a token stream that hasn't decided much about types and - tries to figure out as much as it can, with excessive lookahead and - backtracking. */ - -/* fifo of tokens recognized and available to parser. */ -struct token GTY(()) -{ - /* The values for YYCHAR will fit in a short. */ - short yychar; - unsigned int lineno; - YYSTYPE GTY ((desc ("%1.yychar"))) yylval; -}; - -/* Since inline methods can refer to text which has not yet been seen, - we store the text of the method in a structure which is placed in the - DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. - After parsing the body of the class definition, the FUNCTION_DECL's are - scanned to see which ones have this field set. Those are then digested - one at a time. - - This function's FUNCTION_DECL will have a bit set in its common so - that we know to watch out for it. */ - -#define TOKEN_CHUNK_SIZE 20 -struct token_chunk GTY(()) -{ - struct token_chunk *next; - struct token toks[TOKEN_CHUNK_SIZE]; -}; - -struct unparsed_text GTY(()) -{ - struct unparsed_text *next; /* process this one next */ - tree decl; /* associated declaration */ - location_t locus; /* location we got the text from */ - int interface; /* remembering interface_unknown and interface_only */ - - struct token_chunk * tokens; /* Start of the token list. */ - - struct token_chunk *last_chunk; /* End of the token list. */ - short last_pos; /* Number of tokens used in the last chunk of - TOKENS. */ - - short cur_pos; /* Current token in 'cur_chunk', when rescanning. */ - struct token_chunk *cur_chunk; /* Current chunk, when rescanning. */ -}; - -/* Stack of state saved off when we return to an inline method or - default argument that has been stored for later parsing. */ -struct feed GTY(()) -{ - struct unparsed_text *input; - location_t locus; - int yychar; - YYSTYPE GTY ((desc ("%1.yychar"))) yylval; - int first_token; - struct obstack GTY ((skip (""))) token_obstack; - struct feed *next; -}; - -static GTY(()) struct feed *feed; - -static SPEW_INLINE void do_aggr PARAMS ((void)); -static SPEW_INLINE int identifier_type PARAMS ((tree)); -static void scan_tokens PARAMS ((int)); -static void feed_defarg PARAMS ((tree)); -static void finish_defarg PARAMS ((void)); -static void yylexstring PARAMS ((struct token *)); -static int read_token PARAMS ((struct token *)); - -static SPEW_INLINE int num_tokens PARAMS ((void)); -static SPEW_INLINE struct token *nth_token PARAMS ((int)); -static SPEW_INLINE int next_token PARAMS ((struct token *)); -static SPEW_INLINE int shift_token PARAMS ((void)); -static SPEW_INLINE void push_token PARAMS ((struct token *)); -static SPEW_INLINE void consume_token PARAMS ((void)); -static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *)); - -static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *)); -static SPEW_INLINE struct token * space_for_token - PARAMS ((struct unparsed_text *t)); -static SPEW_INLINE struct token * remove_last_token - PARAMS ((struct unparsed_text *t)); -static struct unparsed_text * alloc_unparsed_text - PARAMS ((const location_t *, tree decl, int interface)); - -static void snarf_block PARAMS ((struct unparsed_text *t)); -static tree snarf_defarg PARAMS ((void)); -static void snarf_parenthesized_expression (struct unparsed_text *); -static int frob_id PARAMS ((int, int, tree *)); - -/* The list of inline functions being held off until we reach the end of - the current class declaration. */ -static GTY(()) struct unparsed_text *pending_inlines; -static GTY(()) struct unparsed_text *pending_inlines_tail; - -/* The list of previously-deferred inline functions currently being parsed. - This exists solely to be a GC root. */ -static GTY(()) struct unparsed_text *processing_these_inlines; - -static void begin_parsing_inclass_inline PARAMS ((struct unparsed_text *)); - -#ifdef SPEW_DEBUG -int spew_debug = 0; -static unsigned int yylex_ctr = 0; - -static void debug_yychar PARAMS ((int)); - -/* In parse.y: */ -extern char *debug_yytranslate PARAMS ((int)); -#endif -static enum cpp_ttype last_token; -static tree last_token_id; - -/* From lex.c: */ -/* the declaration found for the last IDENTIFIER token read in. yylex - must look this up to detect typedefs, which get token type - tTYPENAME, so it is left around in case the identifier is not a - typedef but is used in a context which makes it a reference to a - variable. */ -extern tree lastiddecl; /* let our brains leak out here too */ -extern int yychar; /* the lookahead symbol */ -extern YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ -/* The token fifo lives in this obstack. */ -static struct obstack token_obstack; -static int first_token; - -/* When we see a default argument in a method declaration, we snarf it as - text using snarf_defarg. When we get up to namespace scope, we then go - through and parse all of them using do_pending_defargs. Since yacc - parsers are not reentrant, we retain defargs state in these two - variables so that subsequent calls to do_pending_defargs can resume - where the previous call left off. DEFARG_FNS is a tree_list where - the TREE_TYPE is the current_class_type, TREE_VALUE is the FUNCTION_DECL, - and TREE_PURPOSE is the list unprocessed dependent functions. */ - -/* list of functions with unprocessed defargs */ -static GTY(()) tree defarg_fns; -/* current default parameter */ -static GTY(()) tree defarg_parm; -/* list of unprocessed fns met during current fn. */ -static GTY(()) tree defarg_depfns; -/* list of fns with circular defargs */ -static GTY(()) tree defarg_fnsdone; - -/* Initialize obstacks. Called once, from cxx_init. */ - -void -init_spew () -{ - gcc_obstack_init (&token_obstack); -} - -/* Subroutine of read_token. */ -static SPEW_INLINE int -read_process_identifier (pyylval) - YYSTYPE *pyylval; -{ - tree id = pyylval->ttype; - - if (C_IS_RESERVED_WORD (id)) - { - pyylval->ttype = ridpointers[C_RID_CODE (id)]; - return C_RID_YYCODE (id); - } - - /* Make sure that user does not collide with our internal naming - scheme. This is not necessary if '.' is used to remove them from - the user's namespace, but is if '$' or double underscores are. */ - -#if !defined(JOINER) || JOINER == '$' - if (VPTR_NAME_P (id) - || VTABLE_NAME_P (id) - || TEMP_NAME_P (id) - || ANON_AGGRNAME_P (id)) - warning ( -"identifier name `%s' conflicts with GNU C++ internal naming strategy", - IDENTIFIER_POINTER (id)); -#endif - return IDENTIFIER; -} - -/* Concatenate strings before returning them to the parser. This isn't quite - as good as having it done in the lexer, but it's better than nothing. */ - -static void -yylexstring (t) - struct token *t; -{ - enum cpp_ttype next_type; - tree next; - - next_type = c_lex (&next); - if (next_type == CPP_STRING || next_type == CPP_WSTRING) - { - varray_type strings; - - VARRAY_TREE_INIT (strings, 32, "strings"); - VARRAY_PUSH_TREE (strings, t->yylval.ttype); - - do - { - VARRAY_PUSH_TREE (strings, next); - next_type = c_lex (&next); - } - while (next_type == CPP_STRING || next_type == CPP_WSTRING); - - t->yylval.ttype = combine_strings (strings); - last_token_id = t->yylval.ttype; - } - - /* We will have always read one token too many. */ - _cpp_backup_tokens (parse_in, 1); - - t->yychar = STRING; -} - -/* Read the next token from the input file. The token is written into - T, and its type number is returned. */ -static int -read_token (t) - struct token *t; -{ - retry: - - last_token = c_lex (&last_token_id); - t->yylval.ttype = last_token_id; - - switch (last_token) - { -#define YYCHAR(YY) t->yychar = (YY); break; -#define YYCODE(C) t->yylval.code = (C); - - case CPP_EQ: YYCHAR('='); - case CPP_NOT: YYCHAR('!'); - case CPP_GREATER: YYCODE(GT_EXPR); YYCHAR('>'); - case CPP_LESS: YYCODE(LT_EXPR); YYCHAR('<'); - case CPP_PLUS: YYCODE(PLUS_EXPR); YYCHAR('+'); - case CPP_MINUS: YYCODE(MINUS_EXPR); YYCHAR('-'); - case CPP_MULT: YYCODE(MULT_EXPR); YYCHAR('*'); - case CPP_DIV: YYCODE(TRUNC_DIV_EXPR); YYCHAR('/'); - case CPP_MOD: YYCODE(TRUNC_MOD_EXPR); YYCHAR('%'); - case CPP_AND: YYCODE(BIT_AND_EXPR); YYCHAR('&'); - case CPP_OR: YYCODE(BIT_IOR_EXPR); YYCHAR('|'); - case CPP_XOR: YYCODE(BIT_XOR_EXPR); YYCHAR('^'); - case CPP_RSHIFT: YYCODE(RSHIFT_EXPR); YYCHAR(RSHIFT); - case CPP_LSHIFT: YYCODE(LSHIFT_EXPR); YYCHAR(LSHIFT); - - case CPP_COMPL: YYCHAR('~'); - case CPP_AND_AND: YYCHAR(ANDAND); - case CPP_OR_OR: YYCHAR(OROR); - case CPP_QUERY: YYCHAR('?'); - case CPP_COLON: YYCHAR(':'); - case CPP_COMMA: YYCHAR(','); - case CPP_OPEN_PAREN: YYCHAR('('); - case CPP_CLOSE_PAREN: YYCHAR(')'); - case CPP_EQ_EQ: YYCODE(EQ_EXPR); YYCHAR(EQCOMPARE); - case CPP_NOT_EQ: YYCODE(NE_EXPR); YYCHAR(EQCOMPARE); - case CPP_GREATER_EQ:YYCODE(GE_EXPR); YYCHAR(ARITHCOMPARE); - case CPP_LESS_EQ: YYCODE(LE_EXPR); YYCHAR(ARITHCOMPARE); - - case CPP_PLUS_EQ: YYCODE(PLUS_EXPR); YYCHAR(ASSIGN); - case CPP_MINUS_EQ: YYCODE(MINUS_EXPR); YYCHAR(ASSIGN); - case CPP_MULT_EQ: YYCODE(MULT_EXPR); YYCHAR(ASSIGN); - case CPP_DIV_EQ: YYCODE(TRUNC_DIV_EXPR); YYCHAR(ASSIGN); - case CPP_MOD_EQ: YYCODE(TRUNC_MOD_EXPR); YYCHAR(ASSIGN); - case CPP_AND_EQ: YYCODE(BIT_AND_EXPR); YYCHAR(ASSIGN); - case CPP_OR_EQ: YYCODE(BIT_IOR_EXPR); YYCHAR(ASSIGN); - case CPP_XOR_EQ: YYCODE(BIT_XOR_EXPR); YYCHAR(ASSIGN); - case CPP_RSHIFT_EQ: YYCODE(RSHIFT_EXPR); YYCHAR(ASSIGN); - case CPP_LSHIFT_EQ: YYCODE(LSHIFT_EXPR); YYCHAR(ASSIGN); - - case CPP_OPEN_SQUARE: YYCHAR('['); - case CPP_CLOSE_SQUARE: YYCHAR(']'); - case CPP_OPEN_BRACE: YYCHAR('{'); - case CPP_CLOSE_BRACE: YYCHAR('}'); - case CPP_SEMICOLON: YYCHAR(';'); - case CPP_ELLIPSIS: YYCHAR(ELLIPSIS); - - case CPP_PLUS_PLUS: YYCHAR(PLUSPLUS); - case CPP_MINUS_MINUS: YYCHAR(MINUSMINUS); - case CPP_DEREF: YYCHAR(POINTSAT); - case CPP_DOT: YYCHAR('.'); - - /* These tokens are C++ specific. */ - case CPP_SCOPE: YYCHAR(SCOPE); - case CPP_DEREF_STAR: YYCHAR(POINTSAT_STAR); - case CPP_DOT_STAR: YYCHAR(DOT_STAR); - case CPP_MIN_EQ: YYCODE(MIN_EXPR); YYCHAR(ASSIGN); - case CPP_MAX_EQ: YYCODE(MAX_EXPR); YYCHAR(ASSIGN); - case CPP_MIN: YYCODE(MIN_EXPR); YYCHAR(MIN_MAX); - case CPP_MAX: YYCODE(MAX_EXPR); YYCHAR(MIN_MAX); -#undef YYCHAR -#undef YYCODE - - case CPP_EOF: - t->yychar = 0; - break; - - case CPP_NAME: - t->yychar = read_process_identifier (&t->yylval); - break; - - case CPP_NUMBER: - case CPP_CHAR: - case CPP_WCHAR: - t->yychar = CONSTANT; - break; - - case CPP_STRING: - case CPP_WSTRING: - yylexstring (t); - break; - - default: - yyerror ("parse error"); - goto retry; - } - - t->lineno = lineno; - return t->yychar; -} - -static void -feed_input (input) - struct unparsed_text *input; -{ - struct feed *f; -#if 0 - if (feed) - abort (); -#endif - - f = ggc_alloc (sizeof (struct feed)); - - input->cur_chunk = input->tokens; - input->cur_pos = 0; - -#ifdef SPEW_DEBUG - if (spew_debug) - fprintf (stderr, "\tfeeding %s:%d [%d tokens]\n", - input->locus.file, input->locus.line, input->limit - input->pos); -#endif - - f->input = input; - f->locus.file = input_filename; - f->locus.line = lineno; - f->yychar = yychar; - f->yylval = yylval; - f->first_token = first_token; - f->token_obstack = token_obstack; - f->next = feed; - - input_filename = input->locus.file; - lineno = input->locus.line; - yychar = YYEMPTY; - yylval.ttype = NULL_TREE; - first_token = 0; - gcc_obstack_init (&token_obstack); - feed = f; -} - -void -end_input () -{ - struct feed *f = feed; - - input_filename = f->locus.file; - lineno = f->locus.line; - yychar = f->yychar; - yylval = f->yylval; - first_token = f->first_token; - obstack_free (&token_obstack, 0); - token_obstack = f->token_obstack; - feed = f->next; - -#ifdef SPEW_DEBUG - if (spew_debug) - fprintf (stderr, "\treturning to %s:%d\n", input_filename, lineno); -#endif -} - -/* Token queue management. */ - -/* Return the number of tokens available on the fifo. */ -static SPEW_INLINE int -num_tokens () -{ - return (obstack_object_size (&token_obstack) / sizeof (struct token)) - - first_token; -} - -/* Fetch the token N down the line from the head of the fifo. */ - -static SPEW_INLINE struct token* -nth_token (n) - int n; -{ -#ifdef ENABLE_CHECKING - /* could just have this do slurp_ implicitly, but this way is easier - to debug... */ - my_friendly_assert (n >= 0 && n < num_tokens (), 298); -#endif - return ((struct token*)obstack_base (&token_obstack)) + n + first_token; -} - -static const struct token Teosi = { END_OF_SAVED_INPUT, 0 UNION_INIT_ZERO }; -static const struct token Tpad = { EMPTY, 0 UNION_INIT_ZERO }; - -/* Copy the next token into T and return its value. */ -static SPEW_INLINE int -next_token (t) - struct token *t; -{ - if (!feed) - return read_token (t); - - if (feed->input->cur_chunk != feed->input->last_chunk - || feed->input->cur_pos != feed->input->last_pos) - { - if (feed->input->cur_pos == TOKEN_CHUNK_SIZE) - { - feed->input->cur_chunk = feed->input->cur_chunk->next; - feed->input->cur_pos = 0; - } - memcpy (t, feed->input->cur_chunk->toks + feed->input->cur_pos, - sizeof (struct token)); - feed->input->cur_pos++; - return t->yychar; - } - - return 0; -} - -/* Shift the next token onto the fifo. */ -static SPEW_INLINE int -shift_token () -{ - size_t point = obstack_object_size (&token_obstack); - obstack_blank (&token_obstack, sizeof (struct token)); - return next_token ((struct token *) (obstack_base (&token_obstack) + point)); -} - -/* Consume the next token out of the fifo. */ - -static SPEW_INLINE void -consume_token () -{ - if (num_tokens () == 1) - { - obstack_free (&token_obstack, obstack_base (&token_obstack)); - first_token = 0; - } - else - first_token++; -} - -/* Push a token at the head of the queue; it will be the next token read. */ -static SPEW_INLINE void -push_token (t) - struct token *t; -{ - if (first_token == 0) /* We hope this doesn't happen often. */ - { - size_t active = obstack_object_size (&token_obstack); - obstack_blank (&token_obstack, sizeof (struct token)); - if (active) - memmove (obstack_base (&token_obstack) + sizeof (struct token), - obstack_base (&token_obstack), active); - first_token++; - } - first_token--; - memcpy (nth_token (0), t, sizeof (struct token)); -} - - -/* Pull in enough tokens that the queue is N long beyond the current - token. */ - -static void -scan_tokens (n) - int n; -{ - int i; - int num = num_tokens (); - int yychar; - - /* First, prune any empty tokens at the end. */ - i = num; - while (i > 0 && nth_token (i - 1)->yychar == EMPTY) - i--; - if (i < num) - { - obstack_blank (&token_obstack, -((num - i) * sizeof (struct token))); - num = i; - } - - /* Now, if we already have enough tokens, return. */ - if (num > n) - return; - - /* Never read past these characters: they might separate - the current input stream from one we save away later. */ - for (i = 0; i < num; i++) - { - yychar = nth_token (i)->yychar; - if (yychar == '{' || yychar == ':' || yychar == ';') - goto pad_tokens; - } - - while (num_tokens () <= n) - { - yychar = shift_token (); - if (yychar == '{' || yychar == ':' || yychar == ';') - goto pad_tokens; - } - return; - - pad_tokens: - while (num_tokens () <= n) - obstack_grow (&token_obstack, &Tpad, sizeof (struct token)); -} - -int looking_for_typename; -int looking_for_template; - -static int after_friend; -static int after_new; -static int do_snarf_defarg; - -tree got_scope; -tree got_object; - -static SPEW_INLINE int -identifier_type (decl) - tree decl; -{ - tree t; - - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL) - return PTYPENAME; - else if (looking_for_template) - return PFUNCNAME; - } - if (looking_for_template && really_overloaded_fn (decl)) - { - /* See through a baselink. */ - if (TREE_CODE (decl) == BASELINK) - decl = BASELINK_FUNCTIONS (decl); - - for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) - if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) - return PFUNCNAME; - } - if (TREE_CODE (decl) == NAMESPACE_DECL) - return NSNAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) - return SELFNAME; - - /* A constructor declarator for a template type will get here as an - implicit typename, a TYPENAME_TYPE with a type. */ - t = got_scope; - if (t && TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - decl = TREE_TYPE (decl); - if (TREE_CODE (decl) == TYPENAME_TYPE) - decl = TREE_TYPE (decl); - if (t && t == decl) - return SELFNAME; - - return tTYPENAME; -} - -/* token[0] == AGGR (struct/union/enum) - Thus, token[1] is either a tTYPENAME or a TYPENAME_DEFN. - If token[2] == '{' or ':' then it's TYPENAME_DEFN. - It's also a definition if it's a forward declaration (as in 'struct Foo;') - which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */ - -static SPEW_INLINE void -do_aggr () -{ - int yc1, yc2; - - scan_tokens (2); - yc1 = nth_token (1)->yychar; - if (yc1 != tTYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) - return; - yc2 = nth_token (2)->yychar; - if (yc2 == ';') - { - /* It's a forward declaration iff we were not preceded by - 'friend' or `new'. */ - if (after_friend || after_new) - return; - } - else if (yc2 != '{' && yc2 != ':') - return; - - switch (yc1) - { - case tTYPENAME: - nth_token (1)->yychar = TYPENAME_DEFN; - break; - case PTYPENAME: - nth_token (1)->yychar = PTYPENAME_DEFN; - break; - case IDENTIFIER: - nth_token (1)->yychar = IDENTIFIER_DEFN; - break; - default: - abort (); - } -} - -void -see_typename () -{ - /* Only types expected, not even namespaces. */ - looking_for_typename = 2; - if (yychar < 0) - if ((yychar = yylex ()) < 0) yychar = 0; - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -2); - if (lastiddecl) - yychar = identifier_type (lastiddecl); - } -} - -int -yylex () -{ - int yychr; - int old_looking_for_typename = 0; - int just_saw_new = 0; - int just_saw_friend = 0; - - timevar_push (TV_LEX); - - retry: -#ifdef SPEW_DEBUG - if (spew_debug) - { - yylex_ctr ++; - fprintf (stderr, "\t\t## %d @%d ", yylex_ctr, lineno); - } -#endif - - if (do_snarf_defarg) - { - do_snarf_defarg = 0; - yylval.ttype = snarf_defarg (); - yychar = DEFARG; - got_object = NULL_TREE; - timevar_pop (TV_LEX); - return DEFARG; - } - - /* if we've got tokens, send them */ - else if (num_tokens ()) - yychr = nth_token (0)->yychar; - else - yychr = shift_token (); - - /* many tokens just need to be returned. At first glance, all we - have to do is send them back up, but some of them are needed to - figure out local context. */ - switch (yychr) - { - case EMPTY: - /* This is a lexical no-op. */ -#ifdef SPEW_DEBUG - if (spew_debug) - debug_yychar (yychr); -#endif - consume_token (); - goto retry; - - case '(': - scan_tokens (1); - if (nth_token (1)->yychar == ')') - { - consume_token (); - yychr = LEFT_RIGHT; - } - break; - - case IDENTIFIER: - { - int peek; - - scan_tokens (1); - peek = nth_token (1)->yychar; - yychr = frob_id (yychr, peek, &nth_token (0)->yylval.ttype); - break; - } - case IDENTIFIER_DEFN: - case tTYPENAME: - case TYPENAME_DEFN: - case PTYPENAME: - case PTYPENAME_DEFN: - /* If we see a SCOPE next, restore the old value. - Otherwise, we got what we want. */ - looking_for_typename = old_looking_for_typename; - looking_for_template = 0; - break; - - case SCSPEC: - if (nth_token (0)->yylval.ttype == ridpointers[RID_EXTERN]) - { - scan_tokens (1); - if (nth_token (1)->yychar == STRING) - { - yychr = EXTERN_LANG_STRING; - nth_token (1)->yylval.ttype = get_identifier - (TREE_STRING_POINTER (nth_token (1)->yylval.ttype)); - consume_token (); - } - } - /* do_aggr needs to know if the previous token was `friend'. */ - else if (nth_token (0)->yylval.ttype == ridpointers[RID_FRIEND]) - just_saw_friend = 1; - - break; - - case NEW: - /* do_aggr needs to know if the previous token was `new'. */ - just_saw_new = 1; - break; - - case TYPESPEC: - case '{': - case ':': - case ';': - /* If this provides a type for us, then revert lexical - state to standard state. */ - looking_for_typename = 0; - break; - - case AGGR: - do_aggr (); - break; - - case ENUM: - /* Set this again, in case we are rescanning. */ - looking_for_typename = 2; - break; - - default: - break; - } - - after_friend = just_saw_friend; - after_new = just_saw_new; - - /* class member lookup only applies to the first token after the object - expression, except for explicit destructor calls. */ - if (yychr != '~') - got_object = NULL_TREE; - - yychar = yychr; - { - struct token *tok = nth_token (0); - - yylval = tok->yylval; - if (tok->lineno) - lineno = tok->lineno; - } - -#ifdef SPEW_DEBUG - if (spew_debug) - debug_yychar (yychr); -#endif - consume_token (); - - timevar_pop (TV_LEX); - return yychr; -} - -/* Unget character CH from the input stream. - If RESCAN is nonzero, then we want to `see' this - character as the next input token. */ - -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - struct token fake; - - fake.yychar = ch; - fake.yylval.ttype = 0; - fake.lineno = lineno; - - push_token (&fake); - } - else - { - yychar = ch; - } -} - -/* Lexer hackery to determine what *IDP really is. */ - -static int -frob_id (yyc, peek, idp) - int yyc; - int peek; - tree *idp; -{ - tree trrr; - int old_looking_for_typename = 0; - - if (peek == SCOPE) - { - /* Don't interfere with the setting from an 'aggr' prefix. */ - old_looking_for_typename = looking_for_typename; - looking_for_typename = 1; - } - else if (peek == '<') - looking_for_template = 1; - trrr = lookup_name (*idp, -2); - if (trrr) - { - yyc = identifier_type (trrr); - switch(yyc) - { - case tTYPENAME: - case SELFNAME: - case NSNAME: - case PTYPENAME: - /* If this got special lookup, remember it. In these - cases, we know it can't be a declarator-id. */ - if (got_scope || got_object) - *idp = trrr; - /* FALLTHROUGH */ - case PFUNCNAME: - case IDENTIFIER: - lastiddecl = trrr; - break; - default: - abort (); - } - } - else - lastiddecl = NULL_TREE; - got_scope = NULL_TREE; - looking_for_typename = old_looking_for_typename; - looking_for_template = 0; - return yyc; -} - -/* ID is an operator name. Duplicate the hackery in yylex to determine what - it really is. */ - -tree frob_opname (id) - tree id; -{ - scan_tokens (0); - frob_id (0, nth_token (0)->yychar, &id); - got_object = NULL_TREE; - return id; -} - -/* Set up the state required to correctly handle the definition of the - inline function whose preparsed state has been saved in PI. */ - -static void -begin_parsing_inclass_inline (pi) - struct unparsed_text *pi; -{ - tree context; - - /* Record that we are processing the chain of inlines starting at - PI for GC. */ - if (cfun) - cp_function_chain->unparsed_inlines = pi; - else - processing_these_inlines = pi; - - ggc_collect (); - - /* If this is an inline function in a local class, we must make sure - that we save all pertinent information about the function - surrounding the local class. */ - context = decl_function_context (pi->decl); - if (context) - push_function_context_to (context); - - feed_input (pi); - interface_unknown = pi->interface == 1; - interface_only = pi->interface == 0; - DECL_PENDING_INLINE_P (pi->decl) = 0; - DECL_PENDING_INLINE_INFO (pi->decl) = 0; - - /* Pass back a handle to the rest of the inline functions, so that they - can be processed later. */ - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.pi = pi; - - start_function (NULL_TREE, pi->decl, NULL_TREE, - (SF_DEFAULT | SF_PRE_PARSED | SF_INCLASS_INLINE)); -} - -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. This function sets up the first function - to be parsed; after it has been, the rule for fndef in parse.y will - call process_next_inline to start working on the next one. */ - -void -do_pending_inlines () -{ - /* Oops, we're still dealing with the last batch. */ - if (yychar == PRE_PARSED_FUNCTION_DECL) - return; - - if (pending_inlines) - { - /* Clear the chain, so that any inlines nested inside the batch - we're to process now don't refer to this batch. See e.g. - g++.other/lookup6.C. */ - struct unparsed_text *first = pending_inlines; - pending_inlines = pending_inlines_tail = 0; - - begin_parsing_inclass_inline (first); - } -} - -/* Called from the fndecl rule in the parser when the function just parsed - was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from - do_pending_inlines). */ - -void -process_next_inline (i) - struct unparsed_text *i; -{ - tree decl = i->decl; - tree context = decl_function_context (decl); - - if (context) - pop_function_context_from (context); - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - error ("parse error at end of saved function text"); - end_input (); - - i = i->next; - if (i) - begin_parsing_inclass_inline (i); - else - { - if (cfun) - cp_function_chain->unparsed_inlines = 0; - else - processing_these_inlines = 0; - extract_interface_info (); - } -} - -/* Create a new token at the end of the token list in T. */ -static SPEW_INLINE struct token * -space_for_token (t) - struct unparsed_text *t; -{ - if (t->last_pos != TOKEN_CHUNK_SIZE) - return t->last_chunk->toks + (t->last_pos++); - - t->last_chunk->next = ggc_alloc_cleared (sizeof (*t->last_chunk->next)); - t->last_chunk = t->last_chunk->next; - t->last_chunk->next = NULL; - - t->last_pos = 1; - return t->last_chunk->toks; -} - -/* Shrink the token list in T by one token. */ -static SPEW_INLINE struct token * -remove_last_token (t) - struct unparsed_text *t; -{ - struct token *result = t->last_chunk->toks + t->last_pos - 1; - if (t->last_pos == 0) - abort (); - t->last_pos--; - if (t->last_pos == 0 && t->last_chunk != t->tokens) - { - struct token_chunk *c; - c = t->tokens; - while (c->next != t->last_chunk) - c = c->next; - c->next = NULL; - t->last_chunk = c; - t->last_pos = ARRAY_SIZE (c->toks); - } - return result; -} - -/* Allocate an 'unparsed_text' structure, ready to use space_for_token. */ -static struct unparsed_text * -alloc_unparsed_text (locus, decl, interface) - const location_t *locus; - tree decl; - int interface; -{ - struct unparsed_text *r; - r = ggc_alloc_cleared (sizeof (*r)); - r->decl = decl; - r->locus = *locus; - r->interface = interface; - r->tokens = r->last_chunk = ggc_alloc_cleared (sizeof (*r->tokens)); - return r; -} - -/* Accumulate the tokens that make up a parenthesized expression in T, - having already read the opening parenthesis. */ - -static void -snarf_parenthesized_expression (struct unparsed_text *t) -{ - int yyc; - int level = 1; - - while (1) - { - yyc = next_token (space_for_token (t)); - if (yyc == '(') - ++level; - else if (yyc == ')' && --level == 0) - break; - else if (yyc == 0) - { - error ("%Hend of file read inside definition", &t->locus); - break; - } - } -} - -/* Subroutine of snarf_method, deals with actual absorption of the block. */ - -static void -snarf_block (t) - struct unparsed_text *t; -{ - int blev = 1; - int look_for_semicolon = 0; - int look_for_lbrac = 0; - int look_for_catch = 0; - int yyc; - struct token *current; - - if (yychar == '{') - ; - else if (yychar == '=') - look_for_semicolon = 1; - else if (yychar == ':' || yychar == RETURN_KEYWORD || yychar == TRY) - { - if (yychar == TRY) - look_for_catch = 1; - look_for_lbrac = 1; - blev = 0; - } - else - yyerror ("parse error in method specification"); - - /* The current token is the first one to be recorded. */ - current = space_for_token (t); - current->yychar = yychar; - current->yylval = yylval; - current->lineno = lineno; - - for (;;) - { - yyc = next_token (space_for_token (t)); - - if (yyc == '{') - { - look_for_lbrac = 0; - blev++; - } - else if (yyc == '}') - { - blev--; - if (blev == 0 && !look_for_semicolon) - { - if (!look_for_catch) - break; - - if (next_token (space_for_token (t)) != CATCH) - { - push_token (remove_last_token (t)); - break; - } - - look_for_lbrac = 1; - } - } - else if (yyc == ';') - { - if (look_for_lbrac) - { - struct token *fake; - - error ("function body for constructor missing"); - /* fake a { } to avoid further errors */ - fake = space_for_token (t); - fake->yylval.ttype = 0; - fake->yychar = '{'; - fake = space_for_token (t); - fake->yylval.ttype = 0; - fake->yychar = '}'; - break; - } - else if (look_for_semicolon && blev == 0) - break; - } - else if (yyc == '(' && blev == 0) - snarf_parenthesized_expression (t); - else if (yyc == 0) - { - error ("%Hend of file read inside definition", &t->locus); - break; - } - } -} - -/* This function stores away the text for an inline function that should - be processed later (by do_pending_inlines). */ -void -snarf_method (decl) - tree decl; -{ - struct unparsed_text *meth; - location_t starting; - starting.file = input_filename; - starting.line = lineno; - - meth = alloc_unparsed_text (&starting, decl, (interface_unknown ? 1 - : (interface_only ? 0 : 2))); - - snarf_block (meth); - /* Add three END_OF_SAVED_INPUT tokens. We used to provide an - infinite stream of END_OF_SAVED_INPUT tokens -- but that can - cause the compiler to get stuck in an infinite loop when - encountering invalid code. We need more than one because the - parser sometimes peeks ahead several tokens. */ - memcpy (space_for_token (meth), &Teosi, sizeof (struct token)); - memcpy (space_for_token (meth), &Teosi, sizeof (struct token)); - memcpy (space_for_token (meth), &Teosi, sizeof (struct token)); - - /* Happens when we get two declarations of the same function in the - same scope. */ - if (decl == void_type_node - || (current_class_type && TYPE_REDEFINED (current_class_type))) - return; - -#ifdef SPEW_DEBUG - if (spew_debug) - fprintf (stderr, "\tsaved method of %d tokens from %s:%d\n", - meth->limit, starting.file, starting.line); -#endif - - DECL_PENDING_INLINE_INFO (decl) = meth; - DECL_PENDING_INLINE_P (decl) = 1; - - /* We need to know that this was defined in the class, so that - friend templates are handled correctly. */ - DECL_INITIALIZED_IN_CLASS_P (decl) = 1; - - if (pending_inlines_tail) - pending_inlines_tail->next = meth; - else - pending_inlines = meth; - pending_inlines_tail = meth; -} - -/* Consume a no-commas expression - a default argument - and return - a DEFAULT_ARG tree node. */ - -static tree -snarf_defarg () -{ - int yyc; - int plev = 0; - struct unparsed_text *buf; - tree arg; - location_t starting; - starting.file = input_filename; - starting.line = lineno; - - buf = alloc_unparsed_text (&starting, 0, 0); - - for (;;) - { - yyc = next_token (space_for_token (buf)); - - if (plev <= 0 && (yyc == ')' || yyc == ',')) - break; - else if (yyc == '(' || yyc == '[') - ++plev; - else if (yyc == ']' || yyc == ')') - --plev; - else if (yyc == 0) - { - error ("%Hend of file read inside default argument", &starting); - goto done; - } - } - - /* Unget the last token. */ - push_token (remove_last_token (buf)); - /* Add three END_OF_SAVED_INPUT tokens. We used to provide an - infinite stream of END_OF_SAVED_INPUT tokens -- but that can - cause the compiler to get stuck in an infinite loop when - encountering invalid code. We need more than one because the - parser sometimes peeks ahead several tokens. */ - memcpy (space_for_token (buf), &Teosi, sizeof (struct token)); - memcpy (space_for_token (buf), &Teosi, sizeof (struct token)); - memcpy (space_for_token (buf), &Teosi, sizeof (struct token)); - - done: -#ifdef SPEW_DEBUG - if (spew_debug) - fprintf (stderr, "\tsaved defarg of %d tokens from %s:%d\n", - buf->limit, starting.file, starting.line); -#endif - - arg = make_node (DEFAULT_ARG); - DEFARG_POINTER (arg) = (char *)buf; - - return arg; -} - -/* Decide whether the default argument we are about to see should be - gobbled up as text for later parsing. */ - -void -maybe_snarf_defarg () -{ - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - do_snarf_defarg = 1; -} - -/* Called from grokfndecl to note a function decl with unparsed default - arguments for later processing. Also called from grokdeclarator - for function types with unparsed defargs; the call from grokfndecl - will always come second, so we can overwrite the entry from the type. */ - -void -add_defarg_fn (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - TREE_VALUE (defarg_fns) = decl; - else - { - defarg_fns = tree_cons (NULL_TREE, decl, defarg_fns); - TREE_TYPE (defarg_fns) = current_class_type; - } -} - -/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ - -static void -feed_defarg (p) - tree p; -{ - tree d = TREE_PURPOSE (p); - - feed_input ((struct unparsed_text *)DEFARG_POINTER (d)); - yychar = DEFARG_MARKER; - yylval.ttype = p; -} - -/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ - -static void -finish_defarg () -{ - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - error ("parse error at end of saved function text"); - - end_input (); -} - -/* Main function for deferred parsing of default arguments. Called from - the parser. */ - -void -do_pending_defargs () -{ - if (defarg_parm) - finish_defarg (); - - for (; defarg_fns;) - { - tree current = defarg_fns; - - tree defarg_fn = TREE_VALUE (defarg_fns); - if (defarg_parm == NULL_TREE) - { - push_nested_class (TREE_TYPE (defarg_fns), 1); - pushlevel (0); - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - maybe_begin_member_template_processing (defarg_fn); - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); - else - defarg_parm = TYPE_ARG_TYPES (defarg_fn); - } - else - defarg_parm = TREE_CHAIN (defarg_parm); - - for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm)) - if (!TREE_PURPOSE (defarg_parm) - || TREE_CODE (TREE_PURPOSE (defarg_parm)) != DEFAULT_ARG) - ;/* OK */ - else if (TREE_PURPOSE (current) == error_mark_node) - DEFARG_POINTER (TREE_PURPOSE (defarg_parm)) = NULL; - else - { - feed_defarg (defarg_parm); - - /* Return to the parser, which will process this defarg - and call us again. */ - return; - } - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { - maybe_end_member_template_processing (); - check_default_args (defarg_fn); - } - - poplevel (0, 0, 0); - pop_nested_class (); - - defarg_fns = TREE_CHAIN (defarg_fns); - if (defarg_depfns) - { - /* This function's default args depend on unprocessed default args - of defarg_fns. We will need to reprocess this function, and - check for circular dependencies. */ - tree a, b; - - for (a = defarg_depfns, b = TREE_PURPOSE (current); a && b; - a = TREE_CHAIN (a), b = TREE_CHAIN (b)) - if (TREE_VALUE (a) != TREE_VALUE (b)) - goto different; - if (a || b) - { - different:; - TREE_CHAIN (current) = NULL_TREE; - defarg_fns = chainon (defarg_fns, current); - TREE_PURPOSE (current) = defarg_depfns; - } - else - { - cp_warning_at ("circular dependency in default args of `%#D'", defarg_fn); - /* No need to say what else is dependent, as they will be - picked up in another pass. */ - - /* Immediately repeat, but marked so that we break the loop. */ - defarg_fns = current; - TREE_PURPOSE (current) = error_mark_node; - } - defarg_depfns = NULL_TREE; - } - else if (TREE_PURPOSE (current) == error_mark_node) - defarg_fnsdone = tree_cons (NULL_TREE, defarg_fn, defarg_fnsdone); - } -} - -/* After parsing all the default arguments, we must clear any that remain, - which will be part of a circular dependency. */ -void -done_pending_defargs () -{ - for (; defarg_fnsdone; defarg_fnsdone = TREE_CHAIN (defarg_fnsdone)) - { - tree fn = TREE_VALUE (defarg_fnsdone); - tree parms; - - if (TREE_CODE (fn) == FUNCTION_DECL) - parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); - else - parms = TYPE_ARG_TYPES (fn); - for (; parms; parms = TREE_CHAIN (parms)) - if (TREE_PURPOSE (parms) - && TREE_CODE (TREE_PURPOSE (parms)) == DEFAULT_ARG) - { - my_friendly_assert (!DEFARG_POINTER (TREE_PURPOSE (parms)), 20010107); - TREE_PURPOSE (parms) = NULL_TREE; - } - } -} - -/* In processing the current default arg, we called FN, but that call - required a default argument of FN, and that had not yet been processed. - Remember FN. */ - -void -unprocessed_defarg_fn (fn) - tree fn; -{ - defarg_depfns = tree_cons (NULL_TREE, fn, defarg_depfns); -} - -/* Called from the parser to update an element of TYPE_ARG_TYPES for some - FUNCTION_TYPE with the newly parsed version of its default argument, which - was previously digested as text. */ - -void -replace_defarg (arg, init) - tree arg, init; -{ - if (init == error_mark_node) - TREE_PURPOSE (arg) = error_mark_node; - else - { - if (! processing_template_decl - && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init)) - pedwarn ("invalid type `%T' for default argument to `%T'", - TREE_TYPE (init), TREE_VALUE (arg)); - if (!defarg_depfns) - TREE_PURPOSE (arg) = init; - } -} - -#ifdef SPEW_DEBUG -/* debug_yychar takes a yychar (token number) value and prints its name. */ - -static void -debug_yychar (yy) - int yy; -{ - if (yy<256) - fprintf (stderr, "->%d < %c >\n", lineno, yy); - else if (yy == IDENTIFIER || yy == tTYPENAME) - { - const char *id; - if (TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) - id = IDENTIFIER_POINTER (yylval.ttype); - else if (TREE_CODE_CLASS (TREE_CODE (yylval.ttype)) == 'd') - id = IDENTIFIER_POINTER (DECL_NAME (yylval.ttype)); - else - id = ""; - fprintf (stderr, "->%d <%s `%s'>\n", lineno, debug_yytranslate (yy), id); - } - else - fprintf (stderr, "->%d <%s>\n", lineno, debug_yytranslate (yy)); -} - -#endif - -#define NAME(TYPE) cpp_type2name (TYPE) - -void -yyerror (msgid) - const char *msgid; -{ - const char *string = _(msgid); - - if (last_token == CPP_EOF) - error ("%s at end of input", string); - else if (last_token == CPP_CHAR || last_token == CPP_WCHAR) - { - if (yylval.ttype && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - unsigned int val = TREE_INT_CST_LOW (yylval.ttype); - const char *const ell = (last_token == CPP_CHAR) ? "" : "L"; - if (val <= UCHAR_MAX && ISGRAPH (val)) - error ("%s before %s'%c'", string, ell, val); - else - error ("%s before %s'\\x%x'", string, ell, val); - } - else - error ("%s", string); - } - else if (last_token == CPP_STRING - || last_token == CPP_WSTRING) - error ("%s before string constant", string); - else if (last_token == CPP_NUMBER) - error ("%s before numeric constant", string); - else if (last_token == CPP_NAME) - { - if (TREE_CODE (last_token_id) == IDENTIFIER_NODE) - error ("%s before `%s'", string, IDENTIFIER_POINTER (last_token_id)); - else if (ISGRAPH (yychar)) - error ("%s before `%c'", string, yychar); - else - error ("%s before `\%o'", string, yychar); - } - else - error ("%s before `%s' token", string, NAME (last_token)); -} - -#include "gt-cp-spew.h" |