diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1996-04-19 00:48:03 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1996-04-19 00:48:03 +0000 |
commit | a80e41955ad1262ea9e923ca6ea3044fe005e8fa (patch) | |
tree | bdbf773e17cdf6ea25a65257bf8b7dd0bdf59bf7 /gcc | |
parent | ec497122f7dc8787f6db51c8ab30dc3532455255 (diff) | |
download | gcc-a80e41955ad1262ea9e923ca6ea3044fe005e8fa.zip gcc-a80e41955ad1262ea9e923ca6ea3044fe005e8fa.tar.gz gcc-a80e41955ad1262ea9e923ca6ea3044fe005e8fa.tar.bz2 |
86th Cygnus<->FSF quick merge
From-SVN: r11850
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 77 | ||||
-rw-r--r-- | gcc/cp/call.c | 25 | ||||
-rw-r--r-- | gcc/cp/class.c | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 125 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 15 | ||||
-rw-r--r-- | gcc/cp/expr.c | 8 | ||||
-rw-r--r-- | gcc/cp/init.c | 30 | ||||
-rw-r--r-- | gcc/cp/lex.c | 140 | ||||
-rw-r--r-- | gcc/cp/method.c | 24 | ||||
-rw-r--r-- | gcc/cp/parse.y | 135 | ||||
-rw-r--r-- | gcc/cp/pt.c | 1 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 29 | ||||
-rw-r--r-- | gcc/cp/spew.c | 1 | ||||
-rw-r--r-- | gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 10 |
18 files changed, 314 insertions, 340 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d31ef2f..44e3469 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,14 +1,83 @@ -Wed Apr 17 15:20:10 1996 Brendan Kehoe <brendan@lisa.cygnus.com> +Thu Apr 18 08:56:54 1996 Jason Merrill <jason@yorick.cygnus.com> + + * decl.c (make_typename_type): Handle getting a TYPE_DECL for a + name. + * parse.y (base_class.1): Allow 'typename foo::bar'. + + * lex.c (check_newline): Remove #pragma code that plays with the + input stream, since we now deal with tokens. Clear nextchar when + we're done. + (handle_cp_pragma): Use real_yylex. + (handle_sysv_pragma): Don't do skipline here. Only call real_yylex + in one place. + + * lex.c (check_for_missing_semicolon): Handle SELFNAME. + + * lex.c (handle_cp_pragma): Fix "#pragma implementation". + +Wed Apr 17 16:51:33 1996 Jason Merrill <jason@yorick.cygnus.com> + + * parse.y: New token SELFNAME for potential constructor. + * spew.c (yylex): Handle it. + * lex.c (identifier_type): Produce it. + + * parse.y (complete_type_name): In :: case, don't push class binding. + (complex_type_name): Ditto. + +Wed Apr 17 15:02:40 1996 Mike Stump <mrs@cygnus.com> + + * typeck.c (build_reinterpret_cast): Handle pointer to member + functions. + +Wed Apr 17 12:28:26 1996 Brendan Kehoe <brendan@lisa.cygnus.com> * lex.c (handle_cp_pragma): New function, with decl, doing the cc1plus - pragmas. + pragmas. (check_newline): Put the vtable/unit/implementation/interface pragma - code into handle_cp_pragma, replacing it with a call. + code into handle_cp_pragma, replacing it with a call. (handle_sysv_pragma): Give int return type, and take FINPUT and TOKEN - args. Get the next token after handling the pragma token. + args. Get the next token after handling the pragma token. + +Wed Apr 17 10:28:34 1996 Jason Merrill <jason@yorick.cygnus.com> + + * cvt.c (cp_convert_to_pointer): Avoid doing base analysis on pmfs. + (convert_to_pointer_force): Ditto. + + * init.c (build_new): Fix array new without -fcheck-new. + +Tue Apr 16 13:44:58 1996 Jason Merrill <jason@yorick.cygnus.com> + + * cp-tree.h, call.c, class.c, decl.c, parse.y, pt.c, rtti.c, + tree.c: Lose TYPE_NESTED_NAME. + + * parse.y (nested_name_specifier_1): Don't treat non-identifiers + as identifiers. + + * tree.def: Add VEC_INIT_EXPR. + * expr.c (cplus_expand_expr): Handle it. + * init.c (build_new): Use it instead of the RTL_EXPR nastiness and + the extra file-scope symbol nastiness. + +Mon Apr 15 16:21:29 1996 Jason Merrill <jason@yorick.cygnus.com> + + * method.c (make_thunk): Thunks are static. + (emit_thunk): Use ASM_OUTPUT_MI_THUNK if it's defined. + + * decl2.c (mark_vtable_entries): Emit thunks as needed. + (finish_file): Don't emit them here. + +Sun Apr 14 11:34:39 1996 Jason Merrill <jason@yorick.cygnus.com> + + * rtti.c (build_dynamic_cast): Handle null pointers. + (ifnonnull): New function. Fri Apr 12 09:08:27 1996 Bob Manson <manson@charmed.cygnus.com> + * call.c (build_method_call): Remember the original basetype we + were called with. Give an error message instead of trying + (incorrectly) to call a non-static member function through a + non-inherited class. + * search.c (expand_upcast_fixups): Mark the new fixup as DECL_ARTIFICIAL. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7afd319..29d264c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1296,7 +1296,7 @@ find_scoped_type (type, inner_name, inner_types) if (TREE_PURPOSE (tags) == inner_name) { if (inner_types == NULL_TREE) - return DECL_NESTED_TYPENAME (TYPE_NAME (TREE_VALUE (tags))); + return TYPE_NAME (TREE_VALUE (tags)); return resolve_scope_to_name (TREE_VALUE (tags), inner_types); } tags = TREE_CHAIN (tags); @@ -1308,7 +1308,7 @@ find_scoped_type (type, inner_name, inner_types) { /* Code by raeburn. */ if (inner_types == NULL_TREE) - return DECL_NESTED_TYPENAME (tags); + return tags; return resolve_scope_to_name (TREE_TYPE (tags), inner_types); } @@ -1569,6 +1569,7 @@ build_method_call (instance, name, parms, basetype_path, flags) tree last; int pass; tree access = access_public_node; + tree orig_basetype = basetype_path ? BINFO_TYPE (basetype_path) : NULL_TREE; /* Range of cases for vtable optimization. */ enum vtable_needs { not_needed, maybe_needed, unneeded, needed }; @@ -2416,21 +2417,23 @@ build_method_call (instance, name, parms, basetype_path, flags) if (TREE_CODE (fntype) == METHOD_TYPE && static_call_context && !DECL_CONSTRUCTOR_P (function)) { - /* Let's be nice to the user for now, and give reasonable - default behavior. */ + /* Let's be nasty to the user now, and give reasonable + error messages. */ instance_ptr = current_class_decl; if (instance_ptr) { if (basetype != current_class_type) { - tree binfo = get_binfo (basetype, current_class_type, 1); - if (binfo == NULL_TREE) - { - error_not_base_type (function, current_class_type); - return error_mark_node; - } - else if (basetype == error_mark_node) + if (basetype == error_mark_node) return error_mark_node; + else + { + if (orig_basetype != NULL_TREE) + error_not_base_type (orig_basetype, current_class_type); + else + error_not_base_type (function, current_class_type); + return error_mark_node; + } } } /* Only allow a static member function to call another static member diff --git a/gcc/cp/class.c b/gcc/cp/class.c index bbf259c..c458104 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4388,9 +4388,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon) || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM)) || TREE_CODE (d) == CONST_DECL) break; - /* Don't inject TYPE_NESTED_NAMEs. */ - else if (TREE_MANGLED (DECL_NAME (d)) - || IDENTIFIER_TEMPLATE (DECL_NAME (d))) + /* Don't inject cache decls. */ + else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) continue; DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) = tree_cons (NULL_TREE, d, diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 2a07e2e..0843336 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -69,6 +69,11 @@ DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3) else it is NULL_TREE. */ DEFTREECODE (THROW_EXPR, "throw_expr", "e", 1) +/* Initialization of a vector, used in build_new. Operand 0 is the target + of the initialization, operand 1 is the initializer, and operand 2 is + the number of elements. */ +DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", "e", 3) + /* Template definition. The following fields have the specified uses, although there are other macros in cp-tree.h that should be used for accessing this data. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c8c9fd1..684c9a1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1123,10 +1123,12 @@ struct lang_decl or virtual baseclasses. */ #define TYPE_USES_COMPLEX_INHERITANCE(NODE) (TREE_LANG_FLAG_1 (NODE)) +#if 0 /* UNUSED */ /* Nonzero in IDENTIFIER_NODE means that this name is not the name the user gave; it's a DECL_NESTED_TYPENAME. Someone may want to set this on mangled function names, too, but it isn't currently. */ #define TREE_MANGLED(NODE) (TREE_LANG_FLAG_0 (NODE)) +#endif #if 0 /* UNUSED */ /* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and @@ -1310,12 +1312,6 @@ extern int flag_new_for_scope; #define DECL_VPARENT(NODE) ((NODE)->decl.arguments) #endif -/* Make a slot so we can implement nested types. This slot holds - the IDENTIFIER_NODE that uniquely names the nested type. This - is for TYPE_DECLs only. */ -#define DECL_NESTED_TYPENAME(NODE) ((NODE)->decl.arguments) -#define TYPE_NESTED_NAME(NODE) (DECL_NESTED_TYPENAME (TYPE_NAME (NODE))) - #define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.was_anonymous) /* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index f9f3dfc..80f16e2 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -133,6 +133,8 @@ cp_convert_to_pointer (type, expr) if (TYPE_MAIN_VARIANT (type) != intype && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE + && IS_AGGR_TYPE (TREE_TYPE (type)) + && IS_AGGR_TYPE (TREE_TYPE (intype)) && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) { enum tree_code code = PLUS_EXPR; @@ -281,6 +283,8 @@ convert_to_pointer_force (type, expr) if (TYPE_MAIN_VARIANT (type) != intype && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE + && IS_AGGR_TYPE (TREE_TYPE (type)) + && IS_AGGR_TYPE (TREE_TYPE (intype)) && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) { enum tree_code code = PLUS_EXPR; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d32431b..da41eed 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1955,56 +1955,6 @@ set_identifier_type_value (id, type) set_identifier_type_value_with_scope (id, type, inner_binding_level); } -/* Subroutine "set_nested_typename" builds the nested-typename of - the type decl in question. (Argument CLASSNAME can actually be - a function as well, if that's the smallest containing scope.) */ - -void -set_nested_typename (decl, classname, name, type) - tree decl, classname, name, type; -{ - char *buf; - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 136); - - /* No need to do this for anonymous names, since they're unique. */ - if (ANON_AGGRNAME_P (name)) - { - DECL_NESTED_TYPENAME (decl) = name; - return; - } - - if (classname == NULL_TREE) - classname = get_identifier (""); - - my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 137); - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 138); - buf = (char *) alloca (4 + IDENTIFIER_LENGTH (classname) - + IDENTIFIER_LENGTH (name)); - sprintf (buf, "%s::%s", IDENTIFIER_POINTER (classname), - IDENTIFIER_POINTER (name)); - DECL_NESTED_TYPENAME (decl) = get_identifier (buf); - TREE_MANGLED (DECL_NESTED_TYPENAME (decl)) = 1; - - /* Create an extra decl so that the nested name will have a type value - where appropriate. */ - { - tree nested, type_decl; - nested = DECL_NESTED_TYPENAME (decl); - type_decl = build_decl (TYPE_DECL, nested, type); - DECL_NESTED_TYPENAME (type_decl) = nested; - SET_DECL_ARTIFICIAL (type_decl); - /* Mark the TYPE_DECL node created just above as a gratuitous one so that - dwarfout.c will know not to generate a TAG_typedef DIE for it, and - sdbout.c won't try to output a .def for "::foo". */ - DECL_IGNORED_P (type_decl) = 1; - - /* Remove this when local classes are fixed. */ - SET_IDENTIFIER_TYPE_VALUE (nested, type); - - pushdecl_nonclass_level (type_decl); - } -} - /* Pop off extraneous binding levels left over due to syntax errors. We don't pop past namespaces, as they might be valid. */ @@ -2138,19 +2088,6 @@ pushtag (name, type, globalize) } TYPE_CONTEXT (type) = DECL_CONTEXT (d); - - if (context == NULL_TREE) - /* Non-nested class. */ - set_nested_typename (d, NULL_TREE, name, type); - else if (context && TREE_CODE (context) == FUNCTION_DECL) - /* Function-nested class. */ - set_nested_typename (d, DECL_ASSEMBLER_NAME (c_decl), - name, type); - else /* if (context && IS_AGGR_TYPE (context)) */ - /* Class-nested class. */ - set_nested_typename (d, DECL_NESTED_TYPENAME (c_decl), - name, type); - DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); } @@ -2681,8 +2618,6 @@ duplicate_decls (newdecl, olddecl) register tree newtype = TREE_TYPE (newdecl); register tree oldtype = TREE_TYPE (olddecl); - DECL_NESTED_TYPENAME (newdecl) = DECL_NESTED_TYPENAME (olddecl); - if (newtype != error_mark_node && oldtype != error_mark_node && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) { @@ -3160,12 +3095,6 @@ pushdecl (x) } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); - /* Don't set nested_typename on template type parms, for instance. - Any artificial decls that need DECL_NESTED_TYPENAME will have it - set in pushtag. */ - if (! DECL_NESTED_TYPENAME (x) && ! DECL_ARTIFICIAL (x)) - set_nested_typename (x, current_class_type != NULL_TREE ? TYPE_NESTED_NAME (current_class_type) : current_class_name, DECL_NAME (x), type); - if (type != error_mark_node && TYPE_NAME (type) && TYPE_IDENTIFIER (type)) @@ -3486,12 +3415,6 @@ pushdecl_class_level (x) if (TREE_CODE (x) == TYPE_DECL) { set_identifier_type_value (name, TREE_TYPE (x)); - - /* Don't set nested_typename on template type parms, for instance. - Any artificial decls that need DECL_NESTED_TYPENAME will have it - set in pushtag. */ - if (! DECL_NESTED_TYPENAME (x) && ! DECL_ARTIFICIAL (x)) - set_nested_typename (x, current_class_type != NULL_TREE ? TYPE_NESTED_NAME (current_class_type) : current_class_name, name, TREE_TYPE (x)); } } return x; @@ -4105,8 +4028,7 @@ lookup_tag (form, name, binding_level, thislevel_only) else for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) { - if (TREE_PURPOSE (tail) == name - || TYPE_NESTED_NAME (TREE_VALUE (tail)) == name) + if (TREE_PURPOSE (tail) == name) { enum tree_code code = TREE_CODE (TREE_VALUE (tail)); /* Should tighten this up; it'll probably permit @@ -4327,7 +4249,12 @@ tree make_typename_type (context, name) tree context, name; { - tree t, d, i; + tree t, d; + + if (TREE_CODE (name) == TYPE_DECL) + name = DECL_NAME (name); + else if (TREE_CODE (name) != IDENTIFIER_NODE) + my_friendly_abort (2000); if (! current_template_parms || ! uses_template_parms (context)) @@ -4345,16 +4272,12 @@ make_typename_type (context, name) push_obstacks (&permanent_obstack, &permanent_obstack); t = make_lang_type (TYPENAME_TYPE); d = build_decl (TYPE_DECL, name, t); - i = make_anon_name (); if (current_template_parms) pop_obstacks (); TYPE_CONTEXT (t) = context; TYPE_MAIN_DECL (TREE_TYPE (d)) = d; DECL_CONTEXT (d) = context; - DECL_NESTED_TYPENAME (d) = i; - IDENTIFIER_LOCAL_VALUE (i) = d; - TREE_TYPE (i) = t; return t; } @@ -4396,6 +4319,8 @@ lookup_name_real (name, prefer_type, nonclass) { if (type == error_mark_node) return error_mark_node; + if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) + type = TREE_TYPE (type); type = complete_type (type); @@ -4437,6 +4362,18 @@ lookup_name_real (name, prefer_type, nonclass) else val = NULL_TREE; +#if 0 + if (got_scope && current_template_parms + && uses_template_parms (got_scope) + && val && TREE_CODE (val) == TYPE_DECL + && ! DECL_ARTIFICIAL (val)) + { + tree t = make_typename_type (got_scope, DECL_NAME (val)); + TREE_TYPE (t) = TREE_TYPE (val); + val = TYPE_MAIN_DECL (t); + } +#endif + if (got_scope) goto done; @@ -8992,14 +8929,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli { tree d = TYPE_NAME (type), c = DECL_CONTEXT (d); - if (!c) - set_nested_typename (d, NULL_TREE, declarator, type); - else if (TREE_CODE (c) == FUNCTION_DECL) - set_nested_typename (d, DECL_ASSEMBLER_NAME (c), - declarator, type); - else - set_nested_typename (d, TYPE_NESTED_NAME (c), declarator, type); - DECL_ASSEMBLER_NAME (d) = DECL_NAME (d); DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); @@ -10251,6 +10180,7 @@ xref_tag (code_type_node, name, binfo, globalize) int temp = 0; register tree ref, t; struct binding_level *b = inner_binding_level; + int got_type = 0; tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); switch (tag_code) @@ -10275,7 +10205,8 @@ xref_tag (code_type_node, name, binfo, globalize) if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') { t = name; - name = TYPE_NESTED_NAME (t); + name = TYPE_IDENTIFIER (t); + got_type = 1; } else t = IDENTIFIER_TYPE_VALUE (name); @@ -10289,11 +10220,11 @@ xref_tag (code_type_node, name, binfo, globalize) cp_pedwarn ("redeclaration of template type-parameter `%T'", name); cp_pedwarn_at (" previously declared here", t); } - /* If we know we are defining this tag, only look it up in this scope - * and don't try to find it as a type. */ - if (t && TYPE_CONTEXT (t) && TREE_MANGLED (name)) + if (t && TYPE_CONTEXT (t) && got_type) ref = t; else + /* If we know we are defining this tag, only look it up in this scope + * and don't try to find it as a type. */ ref = lookup_tag (code, name, b, 1); } else @@ -10478,6 +10409,7 @@ xref_basetypes (code_type_node, name, ref, binfo) basetype = TREE_TYPE (basetype); if (!basetype || (TREE_CODE (basetype) != RECORD_TYPE + && TREE_CODE (basetype) != TYPENAME_TYPE && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM)) { cp_error ("base type `%T' fails to be a struct or class type", @@ -10487,6 +10419,7 @@ xref_basetypes (code_type_node, name, ref, binfo) #if 1 /* This code replaces similar code in layout_basetypes. */ else if (TREE_CODE (basetype) != TEMPLATE_TYPE_PARM + && TREE_CODE (basetype) != TYPENAME_TYPE && TYPE_SIZE (complete_type (basetype)) == NULL_TREE) { cp_error ("base class `%T' has incomplete type", basetype); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 039b427..fe32649 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -150,7 +150,7 @@ int warn_implicit = 1; int warn_ctor_dtor_privacy = 1; -/* True if we want to implement vtbvales using "thunks". +/* True if we want to implement vtables using "thunks". The default is off now, but will be on later. */ int flag_vtable_thunks; @@ -2448,6 +2448,11 @@ mark_vtable_entries (decl) TREE_ADDRESSABLE (fn) = 1; if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn)) TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl; + if (TREE_CODE (fn) == THUNK_DECL && DECL_EXTERNAL (fn)) + { + DECL_EXTERNAL (fn) = 0; + emit_thunk (fn); + } mark_used (fn); } } @@ -3187,11 +3192,9 @@ finish_file () for (vars = getdecls (); vars; vars = TREE_CHAIN (vars)) { - if (TREE_CODE (vars) == THUNK_DECL) - emit_thunk (vars); - else if (TREE_CODE (vars) == FUNCTION_DECL - && ! DECL_INTERFACE_KNOWN (vars) - && DECL_C_STATIC (vars)) + if (TREE_CODE (vars) == FUNCTION_DECL + && ! DECL_INTERFACE_KNOWN (vars) + && DECL_C_STATIC (vars)) TREE_PUBLIC (vars) = 0; } diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 9986698..bda8400 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -234,6 +234,14 @@ cplus_expand_expr (exp, target, tmode, modifier) return temp; } + case VEC_INIT_EXPR: + return expand_expr + (expand_vec_init + (NULL_TREE, TREE_OPERAND (exp, 0), + build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2), + integer_one_node, 1), + TREE_OPERAND (exp, 1), 0), target, tmode, modifier); + default: break; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e5e186e..7486a54 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2823,17 +2823,7 @@ build_new (placement, decl, init, use_global_new) } if (flag_check_new && rval) - { - /* For array new, we need to make sure that the call to new is - not expanded as part of the RTL_EXPR for the initialization, - so we can't just use save_expr here. */ - - alloc_temp = build (VAR_DECL, TREE_TYPE (rval)); - layout_decl (alloc_temp, 0); - alloc_expr = build (TARGET_EXPR, TREE_TYPE (rval), alloc_temp, rval, 0); - TREE_SIDE_EFFECTS (alloc_expr) = 1; - rval = alloc_temp; - } + alloc_expr = rval = save_expr (rval); else alloc_expr = NULL_TREE; @@ -2930,6 +2920,10 @@ build_new (placement, decl, init, use_global_new) else rval = error_mark_node; } + else + rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), + save_expr (rval), init, nelts); +#if 0 else if (current_function_decl == NULL_TREE) { extern tree static_aggregates; @@ -3010,23 +3004,19 @@ build_new (placement, decl, init, use_global_new) } rval = xval; } +#endif } else if (TYPE_READONLY (true_type)) cp_error ("uninitialized const in `new' of `%#T'", true_type); done: - if (alloc_expr) + if (alloc_expr && rval != alloc_expr) { /* Did we modify the storage? */ - if (rval != alloc_temp) - { - tree ifexp = build_binary_op (NE_EXPR, alloc_expr, - integer_zero_node, 1); - rval = build_conditional_expr (ifexp, rval, alloc_temp); - } - else - rval = alloc_expr; + tree ifexp = build_binary_op (NE_EXPR, alloc_expr, + integer_zero_node, 1); + rval = build_conditional_expr (ifexp, rval, alloc_expr); } if (rval && TREE_TYPE (rval) != build_pointer_type (type)) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index d59932d..50b71a7 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1743,7 +1743,8 @@ check_for_missing_semicolon (type) if ((yychar > 255 && yychar != SCSPEC && yychar != IDENTIFIER - && yychar != TYPENAME) + && yychar != TYPENAME + && yychar != SELFNAME) || end_of_file) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) @@ -1911,12 +1912,6 @@ check_newline () && getch () == 'm' && getch () == 'a') { - c = getch (); - while (c == ' ' || c == '\t') - c = getch (); - put_back (c); - if (c == '\n' || c == EOF) - goto skipline; token = real_yylex (); if (token == IDENTIFIER && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) @@ -1999,15 +1994,9 @@ check_newline () /* Here we have just seen `#ident '. A string constant should follow. */ - while (c == ' ' || c == '\t') - c = getch (); - - /* If no argument, ignore the line. */ - if (c == EOF) - goto skipline; - - put_back (c); token = real_yylex (); + if (token == END_OF_LINE) + goto skipline; if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { @@ -2281,6 +2270,7 @@ linenum: skipline: linemode = 0; end_of_file = 0; + nextchar = -1; while ((c = getch ()) != EOF && c != '\n'); return c; } @@ -2471,6 +2461,10 @@ identifier_type (decl) return NSNAME; if (TREE_CODE (decl) != TYPE_DECL) return IDENTIFIER; + if (((got_scope && TREE_TYPE (decl) == got_scope) + || TREE_TYPE (decl) == current_class_type) + && DECL_ARTIFICIAL (decl)) + return SELFNAME; return TYPENAME; } @@ -4389,7 +4383,6 @@ handle_cp_pragma (pname) char *pname; { register int token; - register int c; if (! strcmp (pname, "vtable")) { @@ -4412,10 +4405,8 @@ handle_cp_pragma (pname) = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables); - if (nextchar < 0) - nextchar = getch (); - c = nextchar; - if (c != EOF) + token = real_yylex (); + if (token != END_OF_LINE) warning ("trailing characters ignored"); return 1; } @@ -4428,10 +4419,8 @@ handle_cp_pragma (pname) error ("invalid #pragma unit"); return -1; } - if (nextchar < 0) - nextchar = getch (); - c = nextchar; - if (c != EOF) + token = real_yylex (); + if (token != END_OF_LINE) warning ("trailing characters ignored"); return 1; } @@ -4443,15 +4432,10 @@ handle_cp_pragma (pname) main_filename = FILE_NAME_NONDIRECTORY (main_filename); - do - { - c = getch (); - } while (c == ' ' || c == '\t'); - - if (c != EOF) + token = real_yylex (); + + if (token != END_OF_LINE) { - put_back (c); - token = real_yylex (); if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) { @@ -4459,44 +4443,38 @@ handle_cp_pragma (pname) return -1; } main_filename = TREE_STRING_POINTER (yylval.ttype); - c = getch(); - put_back (c); - - while (c == ' ' || c == '\t') - c = getch (); - - while (c != EOF) + } + + while (token != END_OF_LINE) + { + if (!warned_already && extra_warnings) { - if (!warned_already && extra_warnings - && c != ' ' && c != '\t') - { - warning ("garbage after `#pragma interface' ignored"); - warned_already = 1; - } - c = getch (); + warning ("garbage after `#pragma interface' ignored"); + warned_already = 1; } + token = real_yylex (); + } - write_virtuals = 3; + write_virtuals = 3; - if (impl_file_chain == 0) - { - /* If this is zero at this point, then we are - auto-implementing. */ - if (main_input_filename == 0) - main_input_filename = input_filename; + if (impl_file_chain == 0) + { + /* If this is zero at this point, then we are + auto-implementing. */ + if (main_input_filename == 0) + main_input_filename = input_filename; #ifdef AUTO_IMPLEMENT - filename = FILE_NAME_NONDIRECTORY (main_input_filename); - fi = get_time_identifier (filename); - fi = IDENTIFIER_CLASS_VALUE (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = filename; - impl_file_chain->next = 0; + filename = FILE_NAME_NONDIRECTORY (main_input_filename); + fi = get_time_identifier (filename); + fi = IDENTIFIER_CLASS_VALUE (fi); + TREE_INT_CST_LOW (fi) = 0; + TREE_INT_CST_HIGH (fi) = 1; + /* Get default. */ + impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); + impl_file_chain->filename = filename; + impl_file_chain->next = 0; #endif - } } interface_only = interface_strcmp (main_filename); @@ -4514,28 +4492,25 @@ handle_cp_pragma (pname) main_filename = FILE_NAME_NONDIRECTORY (main_filename); token = real_yylex (); - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) + if (token != END_OF_LINE) { - error ("invalid `#pragma implementation'"); - return -1; + if (token != STRING + || TREE_CODE (yylval.ttype) != STRING_CST) + { + error ("invalid `#pragma implementation'"); + return -1; + } + main_filename = TREE_STRING_POINTER (yylval.ttype); } - main_filename = TREE_STRING_POINTER (yylval.ttype); - c = getch(); - put_back (c); - while (c == ' ' || c == '\t') - c = getch (); - - while (c != EOF) + while (token != END_OF_LINE) { - if (!warned_already && extra_warnings - && c != ' ' && c != '\t') + if (!warned_already && extra_warnings) { warning ("garbage after `#pragma implementation' ignored"); warned_already = 1; } - c = getch (); + token = real_yylex (); } if (write_virtuals == 3) @@ -4610,38 +4585,29 @@ handle_sysv_pragma (finput, token) case STRING: case CONSTANT: handle_pragma_token ("ignored", yylval.ttype); - token = yylex (); break; case '(': handle_pragma_token ("(", NULL_TREE); - token = yylex (); break; case ')': handle_pragma_token (")", NULL_TREE); - token = yylex (); break; case ',': handle_pragma_token (",", NULL_TREE); - token = yylex (); break; case '=': handle_pragma_token ("=", NULL_TREE); - token = yylex (); break; case LEFT_RIGHT: handle_pragma_token ("(", NULL_TREE); handle_pragma_token (")", NULL_TREE); - token = yylex (); break; case END_OF_LINE: - handle_pragma_token (NULL_PTR, NULL_TREE); - return 1; default: handle_pragma_token (NULL_PTR, NULL_TREE); - while (yylex () != END_OF_LINE) - /* continue */; return 1; } + token = real_yylex (); } } #endif /* HANDLE_SYSV_PRAGMA */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 8d1bba7..cdddeaf 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1819,7 +1819,7 @@ make_thunk (function, delta) DECL_INITIAL (thunk) = function; THUNK_DELTA (thunk) = delta; DECL_EXTERNAL (thunk) = 1; - TREE_PUBLIC (thunk) = 1; + TREE_PUBLIC (thunk) = 0; /* So that finish_file can write out any thunks that need to be: */ pushdecl_top_level (thunk); } @@ -1831,12 +1831,12 @@ emit_thunk (thunk_fndecl) tree thunk_fndecl; { rtx insns; - char *fnname; char buffer[250]; tree argp; struct args_size stack_args_size; tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0); int delta = THUNK_DELTA (thunk_fndecl); + char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0); int tem; int failure = 0; @@ -1856,16 +1856,14 @@ emit_thunk (thunk_fndecl) TREE_ASM_WRITTEN (thunk_fndecl) = 1; - if (! TREE_PUBLIC (function)) - TREE_PUBLIC (thunk_fndecl) = 0; - if (DECL_EXTERNAL (function)) - return; - DECL_EXTERNAL (thunk_fndecl) = 0; - decl_printable_name = thunk_printable_name; if (current_function_decl) abort (); current_function_decl = thunk_fndecl; +#ifdef ASM_OUTPUT_MI_THUNK + assemble_start_function (thunk_fndecl, fnname); + ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function); +#else init_function_start (thunk_fndecl, input_filename, lineno); pushlevel (0); expand_start_bindings (1); @@ -2031,12 +2029,9 @@ emit_thunk (thunk_fndecl) /* Now turn the rtl into assembler code. */ - { - char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0); - assemble_start_function (thunk_fndecl, fnname); - final (insns, asm_out_file, optimize, 0); - assemble_end_function (thunk_fndecl, fnname); - }; + assemble_start_function (thunk_fndecl, fnname); + final (insns, asm_out_file, optimize, 0); + assemble_end_function (thunk_fndecl, fnname); exit_rest_of_compilation: @@ -2047,6 +2042,7 @@ emit_thunk (thunk_fndecl) resume_temporary_allocation (); decl_printable_name = save_decl_printable_name; +#endif /* ASM_OUTPUT_MI_THUNK */ current_function_decl = 0; } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index fa521a3..6883572 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -108,6 +108,7 @@ empty_parms () In some contexts, they are treated just like IDENTIFIER, but they can also serve as typespecs in declarations. */ %token TYPENAME +%token SELFNAME /* Reserved words that specify storage class. yylval contains an IDENTIFIER_NODE which indicates which one. */ @@ -160,7 +161,7 @@ empty_parms () %nonassoc IF %nonassoc ELSE -%left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD +%left IDENTIFIER TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD %left '{' ',' ';' @@ -191,7 +192,7 @@ empty_parms () %type <code> unop %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist -%type <ttype> paren_expr_or_null nontrivial_exprlist +%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING %type <ttype> typed_declspecs reserved_declspecs boolean.literal %type <ttype> typed_typespecs reserved_typespecquals @@ -230,7 +231,7 @@ empty_parms () %token <ttype> TYPENAME_ELLIPSIS PTYPENAME %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL %token <ttype> PRE_PARSED_CLASS_DECL -%type <ttype> fn.def1 /* Not really! */ +%type <ttype> fn.def1 /* Not really! */ component_constructor_declarator %type <ttype> fn.def2 return_id fn.defpen constructor_declarator %type <itype> ctor_initializer_opt %type <ttype> named_class_head named_class_head_sans_basetype @@ -552,7 +553,7 @@ fndef: ; constructor_declarator: - nested_name_specifier type_name '(' + nested_name_specifier SELFNAME '(' { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) @@ -563,7 +564,7 @@ constructor_declarator: } parmlist ')' type_quals { $$ = build_parse_node (CALL_EXPR, $<ttype>4, $5, $7); } - | nested_name_specifier type_name LEFT_RIGHT type_quals + | nested_name_specifier SELFNAME LEFT_RIGHT type_quals { $$ = build_parse_node (SCOPE_REF, $1, $2); if ($1 != current_class_type) @@ -573,7 +574,7 @@ constructor_declarator: } $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $4); } - | global_scope nested_name_specifier type_name '(' + | global_scope nested_name_specifier SELFNAME '(' { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) @@ -584,7 +585,7 @@ constructor_declarator: } parmlist ')' type_quals { $$ = build_parse_node (CALL_EXPR, $<ttype>5, $6, $8); } - | global_scope nested_name_specifier type_name LEFT_RIGHT type_quals + | global_scope nested_name_specifier SELFNAME LEFT_RIGHT type_quals { $$ = build_parse_node (SCOPE_REF, $2, $3); if ($2 != current_class_type) @@ -630,26 +631,27 @@ fn.def1: $$ = NULL_TREE; } ; +component_constructor_declarator: + SELFNAME '(' parmlist ')' type_quals + { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); } + | SELFNAME LEFT_RIGHT type_quals + { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); } + ; + /* more C++ complexity. See component_decl for a comment on the reduce/reduce conflict introduced by these rules. */ fn.def2: - typed_declspecs '(' parmlist ')' type_quals exception_specification_opt + declmods component_constructor_declarator exception_specification_opt { tree specs = strip_attrs ($1); - $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), $3, $5); - $$ = start_method (TREE_CHAIN (specs), $$, $6); + $$ = start_method (specs, $2, $3); rest_of_mdef: if (! $$) YYERROR1; if (yychar == YYEMPTY) yychar = YYLEX; reinit_parse_for_method (yychar, $$); } - | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt - { tree specs = strip_attrs ($1); - $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), - empty_parms (), $3); - $$ = start_method (TREE_CHAIN (specs), $$, $4); - goto rest_of_mdef; - } + | component_constructor_declarator exception_specification_opt + { $$ = start_method (NULL_TREE, $1, $2); goto rest_of_mdef; } | typed_declspecs declarator exception_specification_opt { tree specs = strip_attrs ($1); $$ = start_method (specs, $2, $3); goto rest_of_mdef; } @@ -757,6 +759,7 @@ member_init: '(' nonnull_exprlist ')' identifier: IDENTIFIER | TYPENAME + | SELFNAME | PTYPENAME | NSNAME ; @@ -823,6 +826,18 @@ template_type: if ($$ != error_mark_node) $$ = TYPE_STUB_DECL ($$); } + | SELFNAME '<' template_arg_list template_close_bracket + { + $$ = lookup_template_class ($1, $3, NULL_TREE); + if ($$ != error_mark_node) + $$ = TYPE_STUB_DECL ($$); + } + | SELFNAME '<' template_close_bracket + { + $$ = lookup_template_class ($1, NULL_TREE, NULL_TREE); + if ($$ != error_mark_node) + $$ = TYPE_STUB_DECL ($$); + } ; template_close_bracket: @@ -1192,6 +1207,7 @@ notype_unqualified_id: unqualified_id: notype_unqualified_id | TYPENAME + | SELFNAME ; expr_or_declarator: @@ -2305,6 +2321,10 @@ base_class: base_class.1: complete_type_name + | TYPENAME_KEYWORD nested_name_specifier identifier + { $$ = TYPE_MAIN_DECL (make_typename_type ($2, $3)); } + | TYPENAME_KEYWORD global_scope nested_name_specifier identifier + { $$ = TYPE_MAIN_DECL (make_typename_type ($3, $4)); } | SIGOF '(' expr ')' { if (current_aggr == signature_type_node) @@ -2574,34 +2594,13 @@ component_decl_1: 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? */ - | typed_declspecs '(' parmlist ')' type_quals exception_specification_opt maybeasm maybe_attribute maybe_init + | declmods component_constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init { tree specs, attrs; split_specs_attrs ($1, &specs, &attrs); - if (TREE_VALUE (specs) == current_class_type) - { - if (TREE_CHAIN (specs) == NULL_TREE) - specs = get_decl_list (current_class_name); - else - TREE_VALUE (specs) = current_class_name; - } - $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), - $3, $5); - $$ = grokfield ($$, TREE_CHAIN (specs), $6, $9, $7, - build_tree_list ($8, attrs)); } - | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt maybeasm maybe_attribute maybe_init - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - if (TREE_VALUE (specs) == current_class_type) - { - if (TREE_CHAIN (specs) == NULL_TREE) - specs = get_decl_list (current_class_name); - else - TREE_VALUE (specs) = current_class_name; - } - $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), - empty_parms (), $3); - $$ = grokfield ($$, TREE_CHAIN (specs), $4, $7, $5, - build_tree_list ($6, attrs)); } + $$ = grokfield ($2, specs, $3, $6, $4, + build_tree_list ($5, attrs)); } + | component_constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, NULL_TREE, $2, $5, $3, $4); } | using_decl { $$ = do_class_using_decl ($1); } ; @@ -2808,7 +2807,6 @@ complete_type_name: { if (current_class_type && TYPE_BEING_DEFINED (current_class_type) - && ! TREE_MANGLED ($1) && ! IDENTIFIER_CLASS_VALUE ($1)) { /* Be sure to get an inherited typedef. */ @@ -2826,16 +2824,7 @@ complete_type_name: | global_scope type_name { if (TREE_CODE ($2) == IDENTIFIER_NODE) - { - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! TREE_MANGLED ($2) - && ! IDENTIFIER_CLASS_VALUE ($2)) - /* Be sure to get an inherited typedef. */ - $$ = lookup_name ($2, 1); - else - $$ = identifier_typedecl_value ($2); - } + $$ = identifier_typedecl_value ($2); else $$ = $2; got_scope = NULL_TREE; @@ -2948,6 +2937,7 @@ functional_cast: type_name: TYPENAME + | SELFNAME | template_type %prec EMPTY ; @@ -2962,14 +2952,22 @@ nested_name_specifier: nested_name_specifier_1: TYPENAME SCOPE { - $$ = lastiddecl; - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! TREE_MANGLED ($1) - && ! IDENTIFIER_CLASS_VALUE ($1)) - pushdecl_class_level ($$); + if (TREE_CODE ($1) == IDENTIFIER_NODE) + { + $$ = lastiddecl; + /* Remember that this name has been used in the class + definition, as per [class.scope0] */ + if (current_class_type + && TYPE_BEING_DEFINED (current_class_type) + && ! IDENTIFIER_CLASS_VALUE ($1)) + pushdecl_class_level ($$); + } + got_scope = $$ = TREE_TYPE ($$); + } + | SELFNAME SCOPE + { + if (TREE_CODE ($1) == IDENTIFIER_NODE) + $$ = lastiddecl; got_scope = $$ = TREE_TYPE ($$); } | NSNAME SCOPE @@ -2992,16 +2990,7 @@ complex_type_name: global_scope type_name { if (TREE_CODE ($2) == IDENTIFIER_NODE) - { - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! TREE_MANGLED ($2) - && ! IDENTIFIER_CLASS_VALUE ($2)) - /* Be sure to get an inherited typedef. */ - $$ = lookup_name ($2, 1); - else - $$ = identifier_typedecl_value ($2); - } + $$ = identifier_typedecl_value ($2); else $$ = $2; got_scope = NULL_TREE; @@ -3675,6 +3664,8 @@ label_colon: { goto do_label; } | TYPENAME ':' { goto do_label; } + | SELFNAME ':' + { goto do_label; } ; for.init.statement: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c1e422b..eaac1f1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1578,7 +1578,6 @@ tsubst (t, args, nargs, in_decl) tree r = copy_node (t); TREE_TYPE (r) = type; DECL_CONTEXT (r) = current_class_type; - set_nested_typename (r, current_class_type != NULL_TREE ? TYPE_NESTED_NAME (current_class_type) : current_class_name, DECL_NAME (r), type); TREE_CHAIN (r) = NULL_TREE; return r; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 75eff1d..45de00f 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -320,6 +320,18 @@ throw_bad_cast () return d; } +/* Check whether TEST is null before returning RESULT. If TEST is used in + RESULT, it must have previously had a save_expr applied to it. */ + +tree ifnonnull (test, result) + tree test, result; +{ + return build (COND_EXPR, TREE_TYPE (result), + build (EQ_EXPR, boolean_type_node, test, integer_zero_node), + convert (TREE_TYPE (result), integer_zero_node), + result); +} + /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working paper. */ @@ -406,6 +418,7 @@ build_dynamic_cast (type, expr) /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */ if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype))) { + tree expr1; /* if TYPE is `void *', return pointer to complete object. */ if (tc == POINTER_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) @@ -416,15 +429,18 @@ build_dynamic_cast (type, expr) && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE) return build1 (NOP_EXPR, type, expr); - expr = build_headof (expr); - if (TREE_TYPE (expr) != type) - expr = build1 (NOP_EXPR, type, expr); - return expr; + /* Since expr is used twice below, save it. */ + expr = save_expr (expr); + + expr1 = build_headof (expr); + if (TREE_TYPE (expr1) != type) + expr1 = build1 (NOP_EXPR, type, expr1); + return ifnonnull (expr, expr1); } else { tree retval; - tree result, td1, td2, td3, elems, expr1, expr2; + tree result, td1, td2, td3, elems, expr2; /* If we got here, we can't convert statically. Therefore, dynamic_cast<D&>(b) (b an object) cannot succeed. */ @@ -522,7 +538,7 @@ build_dynamic_cast (type, expr) /* Now back to the type we want from a void*. */ result = convert (type, result); - return result; + return ifnonnull (expr, result); } } @@ -603,7 +619,6 @@ expand_class_desc (tdecl, type) tree tdecl; tree type; { - tree tname = TYPE_NESTED_NAME (type); tree name_string; tree fn, tmp; char *name; diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index ace8c8f..ff65d33 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -291,6 +291,7 @@ yylex () switch (tmp_token.yychar) { case TYPENAME: + case SELFNAME: lastiddecl = identifier_typedecl_value (tmp_token.yylval.ttype); if (lastiddecl != trrr) { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 5c8fc1c..6db1069 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1073,17 +1073,9 @@ get_identifier_list (value) list = tree_cons (NULL_TREE, value, NULL_TREE); else { - register tree id; - /* This will return the correct thing for regular types, - nested types, and templates. Yay! */ - if (TYPE_NESTED_NAME (type)) - id = TYPE_NESTED_NAME (type); - else - id = TYPE_IDENTIFIER (type); - - if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE) + if (! CLASSTYPE_ID_AS_LIST (type)) CLASSTYPE_ID_AS_LIST (type) - = perm_tree_cons (NULL_TREE, id, NULL_TREE); + = perm_tree_cons (NULL_TREE, TYPE_IDENTIFIER (type), NULL_TREE); list = CLASSTYPE_ID_AS_LIST (type); } } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a2c79b4..85accd8 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5088,15 +5088,19 @@ build_reinterpret_cast (type, expr) { tree intype = TREE_TYPE (expr); - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); - if (current_template_parms) { tree t = build_min (REINTERPRET_CAST_EXPR, type, expr); return t; } + if (TYPE_PTRMEMFUNC_P (type)) + if (TYPE_PTRMEMFUNC_P (intype)) + return build1 (NOP_EXPR, type, expr); + + if (TYPE_PTRMEMFUNC_P (type)) + type = TYPE_PTRMEMFUNC_FN_TYPE (type); + if (TYPE_PTRMEMFUNC_P (intype)) intype = TYPE_PTRMEMFUNC_FN_TYPE (intype); |