--- gcc/cp/lex.c 2018/04/24 18:20:22 1.1.1.1 +++ gcc/cp/lex.c 2018/04/24 18:43:28 1.1.1.4 @@ -1,5 +1,5 @@ /* Separate lexical analyzer for GNU C++. - Copyright (C) 1987, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -16,7 +16,8 @@ GNU General Public License for more deta 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* This file is the lexical analyzer for GNU C++. */ @@ -36,6 +37,7 @@ the Free Software Foundation, 675 Mass A #include "cp-tree.h" #include "flags.h" #include "obstack.h" +#include "c-pragma.h" #ifdef MULTIBYTE_CHARS #include @@ -362,6 +364,7 @@ lang_init () if (flag_cadillac) cadillac_start (); if (flag_gnu_xref) GNU_xref_begin (input_filename); + init_repo (input_filename); } void @@ -403,6 +406,8 @@ void init_lex () { extern char *(*decl_printable_name) (); + extern int flag_no_gnu_keywords; + extern int flag_operator_names; int i; @@ -660,6 +665,9 @@ init_lex () ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); + ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); + SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT], + build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT])); ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); @@ -681,11 +689,6 @@ init_lex () SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE])); - /* Exception handling extensions. */ - exception_type_node = build_int_2 (exception_type, 0); - TREE_TYPE (exception_type_node) = exception_type_node; - ridpointers[(int) RID_EXCEPTION] = exception_type_node; - /* Signature handling extensions. */ signature_type_node = build_int_2 (signature_type, 0); TREE_TYPE (signature_type_node) = signature_type_node; @@ -790,22 +793,37 @@ init_lex () } #endif - if (! (flag_gc || flag_dossier)) + if (! (flag_gc || flag_rtti) || flag_no_gnu_keywords) { UNSET_RESERVED_WORD ("classof"); UNSET_RESERVED_WORD ("headof"); } - if (! flag_handle_signatures) + if (! flag_handle_signatures || flag_no_gnu_keywords) { /* Easiest way to not recognize signature handling extensions... */ UNSET_RESERVED_WORD ("signature"); UNSET_RESERVED_WORD ("sigof"); } - if (flag_no_asm) - UNSET_RESERVED_WORD ("asm"); - if (flag_no_asm || flag_traditional) + if (flag_no_asm || flag_no_gnu_keywords) UNSET_RESERVED_WORD ("typeof"); + if (! flag_operator_names) + { + /* These are new ANSI keywords that may break code. */ + UNSET_RESERVED_WORD ("and"); + UNSET_RESERVED_WORD ("and_eq"); + UNSET_RESERVED_WORD ("bitand"); + UNSET_RESERVED_WORD ("bitor"); + UNSET_RESERVED_WORD ("compl"); + UNSET_RESERVED_WORD ("not"); + UNSET_RESERVED_WORD ("not_eq"); + UNSET_RESERVED_WORD ("or"); + UNSET_RESERVED_WORD ("or_eq"); + UNSET_RESERVED_WORD ("xor"); + UNSET_RESERVED_WORD ("xor_eq"); + } + if (! flag_traditional) + UNSET_RESERVED_WORD ("overload"); token_count = init_parse (); interface_unknown = 1; @@ -1125,19 +1143,7 @@ do_pending_inlines () DECL_PENDING_INLINE_INFO (f) = 0; interface_unknown = t->interface == 1; interface_only = t->interface == 0; - switch (- t->lineno) - { - case 0: case 1: - build_dtor (f); break; - case 2: - build_default_constructor (f); break; - case 3: case 4: - build_copy_constructor (f); break; - case 5: case 6: - build_assign_ref (f); break; - default: - ; - } + synthesize_method (f); if (tail) tail->next = t->next; else @@ -1449,7 +1455,7 @@ store_pending_inline (decl, t) punt them now, or output them now if we're doing implementations and we know no overrides will exist. Otherwise, we delay until end-of-file, to see if the definition is really required. */ - if (DECL_INLINE (decl)) + if (DECL_THIS_INLINE (decl)) /* delay_to_eof == 0 */; else if (current_class_type && !interface_unknown) { @@ -1540,7 +1546,7 @@ reinit_parse_for_method (yychar, decl) t->can_free = 1; t->deja_vu = 0; if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) - warn_if_unknown_interface (); + warn_if_unknown_interface (decl); t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); store_pending_inline (decl, t); } @@ -1553,8 +1559,8 @@ reinit_parse_for_method (yychar, decl) output if something goes wrong. This should really be cleaned up somehow, without loss of clarity. */ void -reinit_parse_for_block (yychar, obstackp, is_template) - int yychar; +reinit_parse_for_block (pyychar, obstackp, is_template) + int pyychar; struct obstack *obstackp; int is_template; { @@ -1566,23 +1572,35 @@ reinit_parse_for_block (yychar, obstackp int look_for_semicolon = 0; int look_for_lbrac = 0; - if (yychar == '{') + if (pyychar == '{') obstack_1grow (obstackp, '{'); - else if (yychar == '=') + else if (pyychar == '=') look_for_semicolon = 1; - else if (yychar != ':' && (yychar != RETURN || is_template)) + else if (pyychar == ':') { - yyerror (is_template - ? "parse error in template specification" - : "parse error in method specification"); - obstack_1grow (obstackp, '{'); + obstack_1grow (obstackp, pyychar); + look_for_lbrac = 1; + blev = 0; } - else + else if (pyychar == RETURN && !is_template) + { + obstack_grow (obstackp, "return", 6); + look_for_lbrac = 1; + blev = 0; + } + else if (pyychar == TRY && !is_template) { - obstack_1grow (obstackp, yychar); + obstack_grow (obstackp, "try", 3); look_for_lbrac = 1; blev = 0; } + else + { + yyerror (is_template + ? "parse error in template specification" + : "parse error in method specification"); + obstack_1grow (obstackp, '{'); + } if (nextchar != EOF) { @@ -1634,7 +1652,26 @@ reinit_parse_for_block (yychar, obstackp { blev--; if (blev == 0 && !look_for_semicolon) - goto done; + { + if (pyychar == TRY) + { + if (peekyylex () == CATCH) + { + yylex (); + obstack_grow (obstackp, " catch ", 7); + look_for_lbrac = 1; + } + else + { + yychar = '{'; + goto done; + } + } + else + { + goto done; + } + } } else if (c == '\\') { @@ -1701,8 +1738,8 @@ reinit_parse_for_block (yychar, obstackp When KIND == 6, build default operator = (X&). */ tree -cons_up_default_function (type, name, kind) - tree type, name; +cons_up_default_function (type, full_name, kind) + tree type, full_name; int kind; { extern tree void_list_node; @@ -1712,8 +1749,9 @@ cons_up_default_function (type, name, ki tree fn, args; tree argtype; int retref = 0; + int complex = 0; + tree name = constructor_name (full_name); - name = constructor_name (name); switch (kind) { /* Destructors. */ @@ -1722,10 +1760,13 @@ cons_up_default_function (type, name, ki /* Fall through... */ case 0: name = build_parse_node (BIT_NOT_EXPR, name); - /* Fall through... */ + args = void_list_node; + break; + case 2: /* Default constructor. */ args = void_list_node; + complex = TYPE_NEEDS_CONSTRUCTING (type); break; case 3: @@ -1739,6 +1780,7 @@ cons_up_default_function (type, name, ki build_tree_list (hash_tree_chain (argtype, NULL_TREE), get_identifier ("_ctor_arg")), void_list_node); + complex = TYPE_HAS_COMPLEX_INIT_REF (type); break; case 5: @@ -1746,7 +1788,7 @@ cons_up_default_function (type, name, ki /* Fall through... */ case 6: retref = 1; - declspecs = build_decl_list (NULL_TREE, name); + declspecs = build_decl_list (NULL_TREE, full_name); name = ansi_opname [(int) MODIFY_EXPR]; @@ -1755,6 +1797,7 @@ cons_up_default_function (type, name, ki build_tree_list (hash_tree_chain (argtype, NULL_TREE), get_identifier ("_ctor_arg")), void_list_node); + complex = TYPE_HAS_COMPLEX_ASSIGN_REF (type); break; default: @@ -1771,26 +1814,49 @@ cons_up_default_function (type, name, ki if (retref) declarator = build_parse_node (ADDR_EXPR, declarator); - fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE); + fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, + NULL_TREE, NULL_TREE); } if (fn == void_type_node) return fn; - if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - SET_DECL_IMPLICIT_INSTANTIATION (fn); + if (processing_template_defn) + { + SET_DECL_IMPLICIT_INSTANTIATION (fn); + repo_template_used (fn); + } - /* This kludge should go away when synthesized methods are handled - properly, i.e. only when needed. */ - { - struct pending_inline *t; - t = (struct pending_inline *) - obstack_alloc (&synth_obstack, sizeof (struct pending_inline)); - t->lineno = -kind; - t->can_free = 0; - t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); - store_pending_inline (fn, t); - } + if (CLASSTYPE_INTERFACE_KNOWN (type)) + { + DECL_INTERFACE_KNOWN (fn) = 1; + DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type) + && flag_implement_inlines); + } + else + DECL_NOT_REALLY_EXTERN (fn) = 1; + +#if 0 + /* When on-the-fly synthesis works properly, remove the second and third + conditions here. */ + if (flag_keep_inline_functions +#if 0 + || ! flag_no_inline + || complex +#endif + || ! DECL_EXTERNAL (fn)) + { + struct pending_inline *t; + t = (struct pending_inline *) + obstack_alloc (&synth_obstack, sizeof (struct pending_inline)); + t->lineno = -kind; + t->can_free = 0; + t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); + store_pending_inline (fn, t); + } + else +#endif + mark_inline_for_output (fn); #ifdef DEBUG_DEFAULT_FUNCTIONS { char *fn_type = NULL; @@ -1819,354 +1885,6 @@ cons_up_default_function (type, name, ki return fn; } -#if 0 -/* Used by default_copy_constructor_body. For the anonymous union - in TYPE, return the member that is at least as large as the rest - of the members, so we can copy it. */ -static tree -largest_union_member (type) - tree type; -{ - tree f, type_size = TYPE_SIZE (type); - - for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) - if (simple_cst_equal (DECL_SIZE (f), type_size)) - return f; - - /* We should always find one. */ - my_friendly_abort (323); - return NULL_TREE; -} - -/* Construct the body of a default assignment operator. - Mostly copied directly from default_copy_constructor_body. */ -static void -default_assign_ref_body (bufp, lenp, type, fields) - char **bufp; - int *lenp; - tree type, fields; -{ - static struct obstack body; - static int inited = FALSE; - int n_bases = CLASSTYPE_N_BASECLASSES (type); - char *tbuf; - int tgot, tneed; - - if (!inited) - { - obstack_init (&body); - inited = TRUE; - } - body.next_free = body.object_base; - - obstack_1grow (&body, '{'); - - /* Small buffer for sprintf(). */ - - tgot = 100; - tbuf = (char *) alloca (tgot); - - /* If we don't need a real op=, just do a bitwise copy. */ - if (! TYPE_HAS_COMPLEX_ASSIGN_REF (type)) - { - tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));return *this;}"; - *lenp = strlen (tbuf); - *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); - strcpy (*bufp, tbuf); - return; - } - - if (TREE_CODE (type) == UNION_TYPE) - { - if (fields) - { - tree main = fields; - char * s; - tree f; - - for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f)) - if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)), - TYPE_SIZE (TREE_TYPE (f)))) - main = f; - - s = IDENTIFIER_POINTER (DECL_NAME (main)); - - tneed = (2 * strlen (s)) + 28; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, "{%s=_ctor_arg.%s;return *this;}", s, s); - } - else - tbuf = "{}"; - - *lenp = strlen (tbuf); - *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); - strcpy (*bufp, tbuf); - return; - } - - /* Construct base classes... - FIXME: Does not deal with multiple inheritance and virtual bases - correctly. See g++.old-deja/g++.jason/opeq5.C for a testcase. - We need to do wacky things if everything between us and the virtual - base (by all paths) has a "complex" op=. */ - - if (n_bases) - { - tree bases = TYPE_BINFO_BASETYPES (type); - int i = 0; - - for (i = 0; i < n_bases; i++) - { - tree binfo = TREE_VEC_ELT (bases, i); - tree btype, name; - char *s; - - btype = BINFO_TYPE (binfo); - name = TYPE_NESTED_NAME (btype); - s = IDENTIFIER_POINTER (name); - - tneed = (2 * strlen (s)) + 42; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s, - TYPE_READONLY (type) ? "const " : "", - CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct", - s); - obstack_grow (&body, tbuf, strlen (tbuf)); - } - } - - /* Construct fields. */ - - if (fields) - { - tree f; - - for (f = fields; f; f = TREE_CHAIN (f)) - { - if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f)) - { - char *s; - tree x; - tree t = TREE_TYPE (f); - - if (DECL_NAME (f)) - x = f; - else if (t != NULL_TREE - && TREE_CODE (t) == UNION_TYPE - && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (TYPE_NAME (t))) - || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) - && TYPE_FIELDS (t) != NULL_TREE) - x = largest_union_member (t); - else - continue; - - s = IDENTIFIER_POINTER (DECL_NAME (x)); - tneed = (2 * strlen (s)) + 13; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, "%s=_ctor_arg.%s;", s, s); - obstack_grow (&body, tbuf, strlen (tbuf)); - } - } - } - - obstack_grow (&body, "return *this;}", 15); - - *lenp = obstack_object_size (&body) - 1; - *bufp = obstack_alloc (&inline_text_obstack, *lenp); - - strcpy (*bufp, body.object_base); -} - -/* Construct the body of a default copy constructor. */ -static void -default_copy_constructor_body (bufp, lenp, type, fields) - char **bufp; - int *lenp; - tree type, fields; -{ - static struct obstack prologue; - static int inited = FALSE; - int n_bases = CLASSTYPE_N_BASECLASSES (type); - char sep = ':'; - char *tbuf; - int tgot, tneed; - - /* Create a buffer to call base class constructors and construct members - (fields). */ - - if (!inited) - { - obstack_init (&prologue); - inited = TRUE; - } - prologue.next_free = prologue.object_base; - - /* If we don't need a real copy ctor, just do a bitwise copy. */ - if (! TYPE_HAS_COMPLEX_INIT_REF (type)) - { - tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));}"; - *lenp = strlen (tbuf); - *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); - strcpy (*bufp, tbuf); - return; - } - - /* Small buffer for sprintf(). */ - - tgot = 100; - tbuf = (char *) alloca (tgot); - - if (TREE_CODE (type) == UNION_TYPE) - { - if (fields) - { - tree main = fields; - char * s; - tree f; - - for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f)) - if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)), - TYPE_SIZE (TREE_TYPE (f)))) - main = f; - - s = IDENTIFIER_POINTER (DECL_NAME (main)); - tneed = (2 * strlen (s)) + 16; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, ":%s(_ctor_arg.%s){}", s, s); - } - else - tbuf = "{}"; - - *lenp = strlen (tbuf); - *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); - strcpy (*bufp, tbuf); - return; - } - - /* Construct base classes... */ - - if (n_bases) - { - /* Note that CLASSTYPE_VBASECLASSES isn't set yet... */ - tree v = get_vbase_types (type); - tree bases = TYPE_BINFO_BASETYPES (type); - int i = 0; - - for (;;) - { - tree binfo, btype, name; - char *s; - - if (v) - { - binfo = v; - v = TREE_CHAIN (v); - } - else if (i < n_bases) - { - binfo = TREE_VEC_ELT (bases, i++); - if (TREE_VIA_VIRTUAL (binfo)) - continue; - } - else - break; - - btype = BINFO_TYPE (binfo); - name = TYPE_NESTED_NAME (btype); - s = IDENTIFIER_POINTER (name); - - tneed = (2 * strlen (s)) + 39; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s, - TYPE_READONLY (type) ? "const " : "", - CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct", - s); - sep = ','; - obstack_grow (&prologue, tbuf, strlen (tbuf)); - } - } - - /* Construct fields. */ - - if (fields) - { - tree f; - - for (f = fields; f; f = TREE_CHAIN (f)) - { - if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f)) - { - char *s; - tree x; - tree t = TREE_TYPE (f); - - if (DECL_NAME (f)) - x = f; - else if (t != NULL_TREE - && TREE_CODE (t) == UNION_TYPE - && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (TYPE_NAME (t))) - || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) - && TYPE_FIELDS (t) != NULL_TREE) - x = largest_union_member (t); - else - continue; - - s = IDENTIFIER_POINTER (DECL_NAME (x)); - tneed = (2 * strlen (s)) + 30; - if (tgot < tneed) - { - tgot = tneed; - tbuf = (char *) alloca (tgot); - } - - sprintf (tbuf, "%c%s(_ctor_arg.%s)", sep, s, s); - sep = ','; - obstack_grow (&prologue, tbuf, strlen (tbuf)); - } - } - } - - /* Concatenate constructor body to prologue. */ - - *lenp = obstack_object_size (&prologue) + 2; - *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); - - obstack_1grow (&prologue, '\0'); - - strcpy (*bufp, prologue.object_base); - strcat (*bufp, "{}"); -} -#endif - /* Heuristic to tell whether the user is missing a semicolon after a struct or enum declaration. Emit an error message if we know the user has blown it. */ @@ -2300,6 +2018,8 @@ get_last_nonwhite_on_line () If the line is a #-directive, read the entire line and return a newline. Otherwise, return the line's first non-whitespace character. */ +int linemode; + int check_newline () { @@ -2321,6 +2041,9 @@ check_newline () return c; } + /* Don't read beyond this line. */ + linemode = 1; + /* Read first nonwhite char after the `#'. */ do @@ -2353,7 +2076,7 @@ check_newline () && getch () == 'b' && getch () == 'l' && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t')) { extern tree pending_vtables; @@ -2373,14 +2096,14 @@ check_newline () if (nextchar < 0) nextchar = getch (); c = nextchar; - if (c != '\n') + if (c != EOF) warning ("trailing characters ignored"); } else if (c == 'u' && getch () == 'n' && getch () == 'i' && getch () == 't' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t')) { /* More follows: it must be a string constant (unit name). */ token = real_yylex (); @@ -2394,7 +2117,7 @@ check_newline () if (nextchar < 0) nextchar = getch (); c = nextchar; - if (c != '\n') + if (c != EOF) warning ("trailing characters ignored"); } else if (c == 'i') @@ -2410,7 +2133,7 @@ check_newline () && getch () == 'a' && getch () == 'c' && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t' || c == EOF)) { int warned_already = 0; char *main_filename = input_filename; @@ -2418,7 +2141,7 @@ check_newline () main_filename = FILE_NAME_NONDIRECTORY (main_filename); while (c == ' ' || c == '\t') c = getch (); - if (c != '\n') + if (c != EOF) { put_back (c); token = real_yylex (); @@ -2436,10 +2159,10 @@ check_newline () while (c == ' ' || c == '\t') c = getch (); - while (c != '\n') + while (c != EOF) { if (!warned_already && extra_warnings - && c != ' ' && c != '\t' && c != '\n') + && c != ' ' && c != '\t') { warning ("garbage after `#pragma interface' ignored"); warned_already = 1; @@ -2487,7 +2210,7 @@ check_newline () && getch () == 'i' && getch () == 'o' && getch () == 'n' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t' || c == EOF)) { int warned_already = 0; char *main_filename = main_input_filename ? main_input_filename : input_filename; @@ -2495,7 +2218,7 @@ check_newline () main_filename = FILE_NAME_NONDIRECTORY (main_filename); while (c == ' ' || c == '\t') c = getch (); - if (c != '\n') + if (c != EOF) { put_back (c); token = real_yylex (); @@ -2513,10 +2236,10 @@ check_newline () while (c == ' ' || c == '\t') c = getch (); - while (c != '\n') + while (c != EOF) { if (!warned_already && extra_warnings - && c != ' ' && c != '\t' && c != '\n') + && c != ' ' && c != '\t') { warning ("garbage after `#pragma implementation' ignored"); warned_already = 1; @@ -2570,8 +2293,25 @@ check_newline () TREE_INT_CST_HIGH (fileinfo) = interface_unknown; } } +#ifdef HANDLE_SYSV_PRAGMA + else + { + put_back (c); + handle_sysv_pragma (); + } +#else +#ifdef HANDLE_PRAGMA + /* FIXME: This will break if we're doing any of the C++ input + tricks. */ + else + { + ungetc (c, finput); + HANDLE_PRAGMA (finput); + } +#endif +#endif + goto skipline; } - goto skipline; } else if (c == 'd') { @@ -2580,7 +2320,7 @@ check_newline () && getch () == 'i' && getch () == 'n' && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t')) { #ifdef DWARF_DEBUGGING_INFO if ((debug_info_level == DINFO_LEVEL_VERBOSE) @@ -2596,7 +2336,7 @@ check_newline () && getch () == 'd' && getch () == 'e' && getch () == 'f' - && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) + && ((c = getch ()) == ' ' || c == '\t')) { #ifdef DWARF_DEBUGGING_INFO if ((debug_info_level == DINFO_LEVEL_VERBOSE) @@ -2634,8 +2374,8 @@ check_newline () c = getch (); /* If no argument, ignore the line. */ - if (c == '\n') - return c; + if (c == EOF) + goto skipline; put_back (c); token = real_yylex (); @@ -2687,8 +2427,8 @@ linenum: /* If the # is the only nonwhite char on the line, just ignore it. Check the new newline. */ - if (c == '\n') - return c; + if (c == EOF) + goto skipline; /* Something follows the #; read a token. */ @@ -2708,11 +2448,11 @@ linenum: int l = TREE_INT_CST_LOW (yylval.ttype) - 1; c = get_last_nonwhite_on_line (); - if (c == '\n') + if (c == EOF) { /* No more: store the line number and check following line. */ lineno = l; - return c; + goto skipline; } put_back (c); @@ -2771,7 +2511,13 @@ linenum: extract_interface_info (); c = get_last_nonwhite_on_line (); - if (c != '\n') + if (c == EOF) + { + /* Update the name in the top element of input_file_stack. */ + if (input_file_stack) + input_file_stack->name = input_filename; + } + else { put_back (c); @@ -2791,7 +2537,7 @@ linenum: if (action) { c = get_last_nonwhite_on_line (); - if (c != '\n') + if (c != EOF) { put_back (c); token = real_yylex (); @@ -2808,7 +2554,7 @@ linenum: entering_system_header = 1; c = get_last_nonwhite_on_line (); - if (c != '\n') + if (c != EOF) { put_back (c); token = real_yylex (); @@ -2824,14 +2570,14 @@ linenum: entering_c_header = 1; c = get_last_nonwhite_on_line (); - if (c != '\n') + if (c != EOF) { put_back (c); token = real_yylex (); } } - /* Do the actions implied by the preceeding numbers. */ + /* Do the actions implied by the preceding numbers. */ if (action == act_push) { @@ -2899,16 +2645,16 @@ linenum: } /* If NEXTCHAR is not end of line, we don't care what it is. */ - if (nextchar == '\n') - return '\n'; + if (nextchar == EOF) + c = EOF; } else error ("invalid #-line"); /* skip the rest of this line. */ skipline: - if (c == '\n') - return c; + linemode = 0; + end_of_file = 0; while ((c = getch ()) != EOF && c != '\n'); return c; } @@ -3093,6 +2839,8 @@ identifier_type (decl) if (TREE_CODE (decl) == TEMPLATE_DECL && DECL_TEMPLATE_IS_CLASS (decl)) return PTYPENAME; + if (TREE_CODE (decl) == NAMESPACE_DECL) + return NSNAME; if (TREE_CODE (decl) != TYPE_DECL) return IDENTIFIER; return TYPENAME; @@ -3101,6 +2849,9 @@ identifier_type (decl) void see_typename () { + looking_for_typename = 1; + if (yychar < 0) + if ((yychar = yylex()) < 0) yychar = 0; looking_for_typename = 0; if (yychar == IDENTIFIER) { @@ -3200,6 +2951,41 @@ do_identifier (token) SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); } } + + if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) + { + tree shadowed = DECL_SHADOWED_FOR_VAR (id); + if (shadowed) + { + if (!DECL_ERROR_REPORTED (id)) + { + warning ("name lookup of `%s' changed", + IDENTIFIER_POINTER (token)); + cp_warning_at (" matches this `%D' under current ANSI rules", + shadowed); + cp_warning_at (" matches this `%D' under old rules", id); + DECL_ERROR_REPORTED (id) = 1; + } + id = shadowed; + } + else if (!DECL_ERROR_REPORTED (id)) + { + static char msg[] + = "name lookup of `%s' changed for new ANSI `for' scoping"; + DECL_ERROR_REPORTED (id) = 1; + if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id))) + { + error (msg, IDENTIFIER_POINTER (token)); + cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id); + id = error_mark_node; + } + else + { + pedwarn (msg, IDENTIFIER_POINTER (token)); + cp_pedwarn_at (" using obsolete binding at `%D'", id); + } + } + } /* TREE_USED is set in `hack_identifier'. */ if (TREE_CODE (id) == CONST_DECL) { @@ -3315,6 +3101,8 @@ real_yylex () end_of_file = 1; if (input_redirected ()) value = END_OF_SAVED_INPUT; + else if (linemode) + value = END_OF_LINE; else if (do_pending_expansions ()) /* this will set yychar for us */ return yychar; @@ -3388,6 +3176,12 @@ real_yylex () *p++ = c; c = getc (finput); } + + if (linemode && c == '\n') + { + put_back (c); + c = EOF; + } } else { @@ -3474,6 +3268,60 @@ real_yylex () else yylval.ttype = old_ttype; } + else if (ptr->token == EQCOMPARE) + { + yylval.code = NE_EXPR; + token_buffer[0] = '!'; + token_buffer[1] = '='; + token_buffer[2] = 0; + } + else if (ptr->token == ASSIGN) + { + if (strcmp ("and_eq", token_buffer) == 0) + { + yylval.code = BIT_AND_EXPR; + token_buffer[0] = '&'; + } + else if (strcmp ("or_eq", token_buffer) == 0) + { + yylval.code = BIT_IOR_EXPR; + token_buffer[0] = '|'; + } + else if (strcmp ("xor_eq", token_buffer) == 0) + { + yylval.code = BIT_XOR_EXPR; + token_buffer[0] = '^'; + } + token_buffer[1] = '='; + token_buffer[2] = 0; + } + else if (ptr->token == '&') + { + yylval.code = BIT_AND_EXPR; + token_buffer[0] = '&'; + token_buffer[1] = 0; + } + else if (ptr->token == '|') + { + yylval.code = BIT_IOR_EXPR; + token_buffer[0] = '|'; + token_buffer[1] = 0; + } + else if (ptr->token == '^') + { + yylval.code = BIT_XOR_EXPR; + token_buffer[0] = '^'; + token_buffer[1] = 0; + } + else if (ptr->token == NAMESPACE) + { + static int warned; + if (! warned) + warning ("namespaces are mostly broken in this version of g++"); + + warned = 1; + } + value = (int) ptr->token; } } @@ -3533,7 +3381,12 @@ real_yylex () && DECL_INITIAL (tmp) != NULL_TREE && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST) { - yylval.ttype = DECL_INITIAL (tmp); + tree stringval = DECL_INITIAL (tmp); + + /* Copy the string value so that we won't clobber anything + if we put something in the TREE_CHAIN of this one. */ + yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), + TREE_STRING_POINTER (stringval)); value = STRING; } } @@ -4139,7 +3992,7 @@ real_yylex () goto tryagain; if (width < HOST_BITS_PER_INT && (unsigned) c >= (1 << width)) - pedwarn ("escape sequence out of range for character"); + warning ("escape sequence out of range for character"); #ifdef MAP_CHARACTER if (isprint (c)) c = MAP_CHARACTER (c); @@ -4256,7 +4109,7 @@ real_yylex () if (!wide_flag && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node))) - pedwarn ("escape sequence out of range for character"); + warning ("escape sequence out of range for character"); } else if (c == '\n') { @@ -4411,7 +4264,7 @@ real_yylex () } else if ((c == '-') && (c1 == '>')) { - nextchar = skip_white_space (getch ()); + nextchar = getch (); if (nextchar == '*') { nextchar = -1; @@ -4438,11 +4291,20 @@ real_yylex () value = MIN_MAX; nextchar = c1; } - if (flag_ansi) + if (pedantic) pedwarn ("use of `operator %s' is not standard C++", token_buffer); goto done; } + /* digraphs */ + else if (c == '<' && c1 == '%') + { value = '{'; goto done; } + else if (c == '<' && c1 == ':') + { value = '['; goto done; } + else if (c == '%' && c1 == '>') + { value = '}'; goto done; } + else if (c == '%' && c1 == ':') + { value = '#'; goto done; } nextchar = c1; token_buffer[1] = 0; @@ -4460,6 +4322,11 @@ real_yylex () value = SCOPE; yylval.itype = 1; } + else if (c == '>') + { + value = ']'; + goto done; + } else { nextchar = c; @@ -4811,3 +4678,53 @@ yyerror (string) error (buf, token_buffer); } + +#ifdef HANDLE_SYSV_PRAGMA + +/* Handle a #pragma directive. INPUT is the current input stream, + and C is a character to reread. Processes the entire input line + and returns a character for the caller to reread: either \n or EOF. */ + +/* This function has to be in this file, in order to get at + the token types. */ + +handle_sysv_pragma () +{ + for (;;) + { + switch (yylex ()) + { + case IDENTIFIER: + case TYPENAME: + case STRING: + case CONSTANT: + handle_pragma_token ("ignored", yylval.ttype); + break; + case '(': + handle_pragma_token ("(", NULL_TREE); + break; + case ')': + handle_pragma_token (")", NULL_TREE); + break; + case ',': + handle_pragma_token (",", NULL_TREE); + break; + case '=': + handle_pragma_token ("=", NULL_TREE); + break; + case LEFT_RIGHT: + handle_pragma_token ("(", NULL_TREE); + handle_pragma_token (")", NULL_TREE); + break; + case END_OF_LINE: + handle_pragma_token (NULL_PTR, NULL_TREE); + return; + default: + handle_pragma_token (NULL_PTR, NULL_TREE); + while (yylex () != END_OF_LINE) + /* continue */; + return; + } + } +} +#endif /* HANDLE_SYSV_PRAGMA */