aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1996-04-19 00:48:03 +0000
committerMike Stump <mrs@gcc.gnu.org>1996-04-19 00:48:03 +0000
commita80e41955ad1262ea9e923ca6ea3044fe005e8fa (patch)
treebdbf773e17cdf6ea25a65257bf8b7dd0bdf59bf7 /gcc
parentec497122f7dc8787f6db51c8ab30dc3532455255 (diff)
downloadgcc-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/ChangeLog77
-rw-r--r--gcc/cp/call.c25
-rw-r--r--gcc/cp/class.c5
-rw-r--r--gcc/cp/cp-tree.def5
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/cvt.c4
-rw-r--r--gcc/cp/decl.c125
-rw-r--r--gcc/cp/decl2.c15
-rw-r--r--gcc/cp/expr.c8
-rw-r--r--gcc/cp/init.c30
-rw-r--r--gcc/cp/lex.c140
-rw-r--r--gcc/cp/method.c24
-rw-r--r--gcc/cp/parse.y135
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/rtti.c29
-rw-r--r--gcc/cp/spew.c1
-rw-r--r--gcc/cp/tree.c12
-rw-r--r--gcc/cp/typeck.c10
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);