summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-03-21 19:46:11 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-03-21 19:46:11 +0000
commitd2a15a126c1aadbdfef279e54b73047d26cb49f8 (patch)
tree71acc1f1dfc74c8765bd1a8cb6d4812f1fc07115 /gcc
parent33a0ea3cd02a3d94c6bd1e91808a298edbba2d90 (diff)
downloadgcc-d2a15a126c1aadbdfef279e54b73047d26cb49f8.tar.gz
85th Cygnus<->FSF quick merge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11587 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog230
-rw-r--r--gcc/cp/call.c68
-rw-r--r--gcc/cp/class.c229
-rw-r--r--gcc/cp/cp-tree.h26
-rw-r--r--gcc/cp/cvt.c61
-rw-r--r--gcc/cp/decl.c192
-rw-r--r--gcc/cp/decl2.c77
-rw-r--r--gcc/cp/error.c11
-rw-r--r--gcc/cp/except.c6
-rw-r--r--gcc/cp/expr.c3
-rw-r--r--gcc/cp/gxxint.texi32
-rw-r--r--gcc/cp/init.c169
-rw-r--r--gcc/cp/lex.c61
-rw-r--r--gcc/cp/method.c27
-rw-r--r--gcc/cp/parse.y27
-rw-r--r--gcc/cp/pt.c63
-rw-r--r--gcc/cp/search.c110
-rw-r--r--gcc/cp/spew.c54
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/cp/typeck.c79
-rw-r--r--gcc/cp/typeck2.c93
21 files changed, 893 insertions, 736 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7e7006fdb0c..3434665100c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,233 @@
+Wed Mar 20 14:51:55 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (named_complex_class_head_sans_basetype): Don't crash on
+ definition of nonexistent nested type.
+
+ * error.c (dump_decl, case TYPE_DECL): Fix decision for whether or
+ not to say 'typedef'.
+
+Wed Mar 20 00:11:47 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (struct lang_type): Make search_slot a tree, not a char*.
+ * search.c (dfs_walk, dfs_init_vbase_pointers,
+ expand_upcast_fixups): Remove cast of CLASSTYPE_SEARCH_SLOT.
+ (dfs_find_vbases): Remove cast for CLASSTYPE_SEARCH_SLOT init.
+
+Tue Mar 19 17:56:03 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * except.c (build_throw): Support minimal parse.
+ * pt.c (tsubst_copy): Support THROW_EXPR.
+ * decl2.c (build_expr_from_tree): Ditto.
+
+ * pt.c (mangle_class_name_for_template): Always allocate
+ scratch_firstobj.
+
+Tue Mar 19 16:34:31 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * cvt.c (cp_convert_to_pointer): Give an appropriate error
+ when trying to cast from an incomplete type.
+
+Tue Mar 19 16:00:33 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): Don't bother setting up
+ CLASSTYPE_TAGS explicitly, as the nested types will add
+ themselves.
+
+Tue Mar 19 15:48:43 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * decl.c (shadow_tag): Remove old error check for usage of
+ an enum without a previous declaration.
+ (xref_tag): Add error message about usage of enums without a
+ previous declaration.
+
+Tue Mar 19 09:21:35 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Only do name consistency check if we're
+ parsing.
+
+ * pt.c (push_template_decl): Don't crash if we get a member defn
+ that doesn't match.
+
+ * decl.c (xref_tag_from_type): New function to do an xref without
+ always having to figure out code_type_node.
+ * cp-tree.h: Declare it.
+ * pt.c (instantiate_class_template): Use it for friend classes.
+ (lookup_template_class): Use it.
+
+ * typeck2.c (build_functional_cast): Pull out a single parm before
+ passing it to build_c_cast.
+
+Tue Mar 19 09:07:15 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * expr.c (do_case): Give an error message if a pointer is
+ given as a case value.
+
+Mon Mar 18 21:57:54 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_c_cast): Don't pull single TEMPLATE_DECL out of
+ an overload list.
+
+ * lex.c (cons_up_default_function): Really, now, interface hackery
+ does not apply to synthesized methods.
+
+Mon Mar 18 18:20:57 1996 Mike Stump <mrs@cygnus.com>
+
+ * call.c (build_method_call): Ctors and dtors now have special names
+ with respect to lookups.
+ * class.c (add_method): Ditto.
+ (grow_method): Ditto.
+ (finish_struct_methods): Ditto.
+ (warn_hidden): Ditto.
+ (finish_struct_1): Ditto.
+ * cvt.c (convert_to_reference): Ditto.
+ (convert_to_aggr): Ditto.
+ (cp_convert): Ditto.
+ * decl2.c (check_classfn): Ditto.
+ * init.c (expand_member_init): Ditto.
+ (expand_default_init): Ditto.
+ (expand_aggr_init_1): Ditto.
+ (build_offset_ref): Ditto.
+ (build_new): Ditto.
+ (build_delete): Ditto.
+ * lex.c (do_inline_function_hair): Ditto.
+ * search.c (lookup_field_1): Ditto.
+ (lookup_fnfields_here): Ditto.
+ (lookup_field): Ditto.
+ (lookup_fnfields): Ditto.
+ (get_virtual_destructor): Ditto.
+ (dfs_debug_mark): Ditto.
+ (dfs_pushdecls): Ditto.
+ (dfs_compress_decls): Ditto.
+ * tree.c (layout_basetypes): Ditto.
+ * typeck.c (build_component_ref): Ditto.
+ (build_x_function_call): Ditto.
+ (build_modify_expr): Ditto.
+ (convert_for_initialization): Ditto.
+ (build_functional_cast): Ditto.
+ * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Ditto.
+ (CTOR_NAME): New.
+ (DTOR_NAME): New.
+ * decl.c (ctor_identifier): New.
+ (dtor_identifier): New.
+ (init_decl_processing): Set them.
+
+Mon Mar 18 18:00:51 1996 Mike Stump <mrs@cygnus.com>
+
+ * typeck.c (build_component_ref): Don't get confused by fields whose
+ context has no type name, like pointer to member functions.
+
+Mon Mar 18 13:19:03 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (grokdeclarator): Handle typedef without declarator.
+
+ * pt.c (tsubst): Handle SCOPE_REF in declarator.
+
+ * parse.y (bad_parm): Catch another case of missing `typename'.
+
+ * lex.c (yyprint): Handle TYPE_DECLs.
+
+ * decl.c (start_function): Don't try to be clever.
+
+ * lex.c: Lose compiler_error_with_decl.
+ * typeck2.c: Lose error_with_aggr_type.
+ (incomplete_type_error): Use cp_* instead of old functions.
+ (readonly_error): Ditto.
+ * typeck.c (convert_arguments): Ditto.
+ * search.c (lookup_nested_field): Ditto.
+ * method.c (make_thunk): Ditto.
+ * decl.c (grokparms): Ditto.
+ * cp-tree.h: Update.
+
+ * tree.c (min_tree_cons): Call copy_to_permanent for the purpose
+ and value.
+
+Mon Mar 18 11:25:52 1996 Bob Manson <manson@beauty.cygnus.com>
+
+ * method.c (build_opfncall): When deleting a pointer to an
+ array, build a new pointer to the tree past any ARRAY_TYPE
+ nodes.
+
+Mon Mar 18 10:11:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * decl.c (lookup_name_real): Initialize local var TYPE to NULL_TREE.
+
+Fri Mar 15 11:03:57 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_decl): Only call import_export_decl if at_eof
+ and ! DECL_INLINE.
+
+ * decl.c (finish_function): Don't set nested based on
+ hack_decl_function_context.
+ * parse.y (function_try_block): Check for nested function.
+ (pending_inlines): Ditto.
+
+ * decl2.c (build_expr_from_tree): If a unary op already has a
+ type, just return it.
+
+ * decl2.c (finish_prevtable_vardecl): Use ADJUST_VTABLE_LINKAGE.
+
+ * decl2.c (walk_vtables): vardecl_fn returns int; return 1 if it does.
+ (finish_file): Check the return value of walk_vtables.
+ (finish_prevtable_vardecl): Return int.
+ (finish_vtable_vardecl): Ditto.
+ (prune_vtable_vardecl): Ditto.
+ * lex.c (set_vardecl_interface_info): Ditto.
+ * cp-tree.h: Adjust return types.
+
+ * class.c (delete_duplicate_fields_1): Don't complain about
+ duplicate nested types if they're the same type.
+ (finish_struct): Remove check for duplicate.
+ * decl2.c (grokfield): Don't check for typedef of anonymous type.
+
+Thu Mar 14 10:00:19 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cp-tree.h: Lose SIGNATURE_GROKKING_TYPEDEF.
+
+ * decl.c (grokdeclarator): Lose special handling of class-level
+ typedef. Lose SIGNATURE_GROKKING_TYPEDEF. Set
+ SIGNATURE_HAS_OPAQUE_TYPEDECLS later.
+
+ * cvt.c (convert_pointer_to_real): Retain cv-quals in conversion.
+
+ * pt.c (tsubst_copy): Strip cv-quals from destructor name types.
+
+ * search.c (compute_access): Fix handling of anonymous union
+ members.
+ * class.c (finish_struct_anon): Propagate TREE_{PRIVATE,PROTECTED}
+ from anonymous unions to their members.
+
+ * typeck.c (build_x_function_call): For static member functions,
+ hand off to build_member_call.
+
+Wed Mar 13 14:03:34 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * typeck.c (build_component_ref): Handle OFFSET_REFs.
+
+ * init.c (expand_vec_init): Fix init == 0 case.
+
+Tue Mar 12 14:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * init.c (build_new): Pedwarn about init and array new.
+ (expand_vec_init): Handle lists, use convert_for_initialization
+
+ * typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION
+ when converting to an aggregate type.
+ * cvt.c (cp_convert): Pass it through.
+
+ * typeck.c (build_conditional_expr): Handle user-defined
+ conversions to slightly different types.
+
+ * decl.c (grokdeclarator): Force an array type in a parm to be
+ permanent.
+
+ * decl2.c (do_using_directive): Sorry.
+ (do_namespace_alias): Ditto.
+ * lex.c (real_yylex): Warn about using the `namespace' keyword.
+
+Sun Mar 10 22:26:09 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (datadef): Move call to note_list_got_semicolon up.
+
Fri Mar 8 11:47:26 1996 Mike Stump <mrs@cygnus.com>
* tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 570c02077e2..5f0560f3991 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1745,11 +1745,15 @@ build_method_call (instance, name, parms, basetype_path, flags)
;
/* call to a constructor... */
else if (basetype_path)
- basetype = BINFO_TYPE (basetype_path);
+ {
+ basetype = BINFO_TYPE (basetype_path);
+ if (name == DECL_NAME (TYPE_NAME (basetype)))
+ name = ctor_identifier;
+ }
else if (IDENTIFIER_HAS_TYPE_VALUE (name))
{
basetype = IDENTIFIER_TYPE_VALUE (name);
- name = constructor_name (basetype);
+ name = ctor_identifier;
}
else
{
@@ -1758,7 +1762,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
/* Canonicalize the typedef name. */
basetype = TREE_TYPE (typedef_name);
- name = TYPE_IDENTIFIER (basetype);
+ name = ctor_identifier;
}
else
{
@@ -2046,14 +2050,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* Look up function name in the structure type definition. */
+ /* FIXME Axe most of this now? */
if ((IDENTIFIER_HAS_TYPE_VALUE (name)
&& ! IDENTIFIER_OPNAME_P (name)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
- || name == constructor_name (basetype))
+ || name == constructor_name (basetype)
+ || name == ctor_identifier)
{
tree tmp = NULL_TREE;
if (IDENTIFIER_TYPE_VALUE (name) == basetype
- || name == constructor_name (basetype))
+ || name == constructor_name (basetype)
+ || name == ctor_identifier)
tmp = TYPE_BINFO (basetype);
else
tmp = get_binfo (IDENTIFIER_TYPE_VALUE (name), basetype, 0);
@@ -2092,19 +2099,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (result == error_mark_node)
return error_mark_node;
-
-#if 0
- /* Now, go look for this method name. We do not find destructors here.
-
- Putting `void_list_node' on the end of the parmtypes
- fakes out `build_decl_overload' into doing the right thing. */
- TREE_CHAIN (last) = void_list_node;
- method_name = build_decl_overload (name, parmtypes,
- 1 + (name == constructor_name (save_basetype)
- || name == constructor_name_full (save_basetype)));
- TREE_CHAIN (last) = NULL_TREE;
-#endif
-
for (pass = 0; pass < 2; pass++)
{
struct candidate *candidates;
@@ -2112,10 +2106,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
int len;
unsigned best = 1;
- /* This increments every time we go up the type hierarchy.
- The idea is to prefer a function of the derived class if possible. */
- int b_or_d = 0;
-
baselink = result;
if (pass > 0)
@@ -2167,7 +2157,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
- while (baselink)
+ if (baselink)
{
/* We have a hit (of sorts). If the parameter list is
"error_mark_node", or some variant thereof, it won't
@@ -2183,30 +2173,6 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype_path = TREE_VALUE (basetype_path);
basetype = BINFO_TYPE (basetype_path);
-#if 0
- /* Cast the instance variable if necessary. */
- if (basetype != TYPE_MAIN_VARIANT
- (TREE_TYPE (TREE_TYPE (TREE_VALUE (parms)))))
- {
- if (basetype == save_basetype)
- TREE_VALUE (parms) = instance_ptr;
- else
- {
- tree type = build_pointer_type
- (build_type_variant (basetype, constp, volatilep));
- TREE_VALUE (parms) = convert_force (type, instance_ptr, 0);
- }
- }
-
- /* FIXME: this is the wrong place to get an error. Hopefully
- the access-control rewrite will make this change more cleanly. */
- if (TREE_VALUE (parms) == error_mark_node)
- return error_mark_node;
-#endif
-
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
- function = DECL_CHAIN (function);
-
for (; function; function = DECL_CHAIN (function))
{
#ifdef GATHER_STATISTICS
@@ -2263,14 +2229,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
}
- /* Now we have run through one link's member functions.
- arrange to head-insert this link's links. */
- baselink = next_baselink (baselink);
- b_or_d += 1;
- /* Don't grab functions from base classes. lookup_fnfield will
- do the work to get us down into the right place. */
- baselink = NULL_TREE;
}
+
if (pass == 0)
{
tree igv = lookup_name_nonclass (name);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1628d65565b..ffe0104656e 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -932,8 +932,16 @@ add_method (type, fields, method)
tree method_vec = make_node (TREE_VEC);
if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
{
- TREE_VEC_ELT (method_vec, 0) = decl;
- TREE_VEC_LENGTH (method_vec) = 1;
+ /* ??? Is it possible for there to have been enough room in the
+ current chunk for the tree_vec structure but not a tree_vec
+ plus a tree*? Will this work in that case? */
+ obstack_free (current_obstack, method_vec);
+ obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
+ if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+ TREE_VEC_ELT (method_vec, 1) = decl;
+ else
+ TREE_VEC_ELT (method_vec, 0) = decl;
+ TREE_VEC_LENGTH (method_vec) = 2;
}
else
{
@@ -941,9 +949,9 @@ add_method (type, fields, method)
current chunk for the tree_vec structure but not a tree_vec
plus a tree*? Will this work in that case? */
obstack_free (current_obstack, method_vec);
- obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
- TREE_VEC_ELT (method_vec, 1) = decl;
- TREE_VEC_LENGTH (method_vec) = 2;
+ obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *));
+ TREE_VEC_ELT (method_vec, 2) = decl;
+ TREE_VEC_LENGTH (method_vec) = 3;
obstack_finish (current_obstack);
}
CLASSTYPE_METHOD_VEC (type) = method_vec;
@@ -957,11 +965,12 @@ add_method (type, fields, method)
METHOD_VEC always has a slot for such entries. */
if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
{
- /* TREE_VEC_ELT (method_vec, 0) = decl; */
- if (decl != TREE_VEC_ELT (method_vec, 0))
+ int index = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl));
+ /* TREE_VEC_ELT (method_vec, index) = decl; */
+ if (decl != TREE_VEC_ELT (method_vec, index))
{
- DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, 0);
- TREE_VEC_ELT (method_vec, 0) = decl;
+ DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, index);
+ TREE_VEC_ELT (method_vec, index) = decl;
}
}
else
@@ -1085,7 +1094,11 @@ delete_duplicate_fields_1 (field, fields)
x);
else if (TREE_CODE (field) == TYPE_DECL
&& TREE_CODE (x) == TYPE_DECL)
- cp_error_at ("duplicate nested type `%D'", x);
+ {
+ if (TREE_TYPE (field) == TREE_TYPE (x))
+ continue;
+ cp_error_at ("duplicate nested type `%D'", x);
+ }
else if (TREE_CODE (field) == TYPE_DECL
|| TREE_CODE (x) == TYPE_DECL)
{
@@ -1756,42 +1769,41 @@ finish_struct_bits (t, max_has_virtual)
}
}
-/* Add FN to the method_vec growing on the class_obstack. Used by
- finish_struct_methods. */
+/* Add FNDECL to the method_vec growing on the class_obstack. Used by
+ finish_struct_methods. Note, FNDECL cannot be a constructor or
+ destructor, those cases are handled by the caller. */
static void
-grow_method (fn, method_vec_ptr)
- tree fn;
+grow_method (fndecl, method_vec_ptr)
+ tree fndecl;
tree *method_vec_ptr;
{
tree method_vec = (tree)obstack_base (&class_obstack);
- tree *testp = &TREE_VEC_ELT (method_vec, 0);
- if (*testp == NULL_TREE)
- testp++;
- while (((HOST_WIDE_INT) testp
- < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
- && DECL_NAME (*testp) != DECL_NAME (fn))
+
+ /* Start off past the constructors and destructor. */
+ tree *testp = &TREE_VEC_ELT (method_vec, 2);
+
+ while (testp < (tree *) obstack_next_free (&class_obstack)
+ && (*testp == NULL_TREE || DECL_NAME (*testp) != DECL_NAME (fndecl)))
testp++;
- if ((HOST_WIDE_INT) testp
- < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
+
+ if (testp < (tree *) obstack_next_free (&class_obstack))
{
tree x, prev_x;
for (x = *testp; x; x = DECL_CHAIN (x))
{
- if (DECL_NAME (fn) == ansi_opname[(int) DELETE_EXPR]
- || DECL_NAME (fn) == ansi_opname[(int) VEC_DELETE_EXPR])
+ if (DECL_NAME (fndecl) == ansi_opname[(int) DELETE_EXPR]
+ || DECL_NAME (fndecl) == ansi_opname[(int) VEC_DELETE_EXPR])
{
/* ANSI C++ June 5 1992 WP 12.5.5.1 */
- cp_error_at ("`%D' overloaded", fn);
+ cp_error_at ("`%D' overloaded", fndecl);
cp_error_at ("previous declaration as `%D' here", x);
}
- if (DECL_ASSEMBLER_NAME (fn)==DECL_ASSEMBLER_NAME (x))
+ if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (x))
{
- /* We complain about multiple destructors on sight,
- so we do not repeat the warning here. Friend-friend
- ambiguities are warned about outside this loop. */
- if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn)))
- cp_error_at ("ambiguous method `%#D' in structure", fn);
+ /* Friend-friend ambiguities are warned about outside
+ this loop. */
+ cp_error_at ("ambiguous method `%#D' in structure", fndecl);
break;
}
prev_x = x;
@@ -1799,14 +1811,14 @@ grow_method (fn, method_vec_ptr)
if (x == 0)
{
if (*testp)
- DECL_CHAIN (prev_x) = fn;
+ DECL_CHAIN (prev_x) = fndecl;
else
- *testp = fn;
+ *testp = fndecl;
}
}
else
{
- obstack_ptr_grow (&class_obstack, fn);
+ obstack_ptr_grow (&class_obstack, fndecl);
*method_vec_ptr = (tree)obstack_base (&class_obstack);
}
}
@@ -1842,27 +1854,27 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
{
tree method_vec;
tree save_fn_fields = fn_fields;
- tree name = constructor_name (t);
+ tree ctor_name = constructor_name (t);
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
/* Now prepare to gather fn_fields into vector. */
struct obstack *ambient_obstack = current_obstack;
current_obstack = &class_obstack;
- method_vec = make_node (TREE_VEC);
- /* Room has been saved for constructors and destructors. */
+ method_vec = make_tree_vec (2);
current_obstack = ambient_obstack;
+
/* Now make this a live vector. */
obstack_free (&class_obstack, method_vec);
- obstack_blank (&class_obstack, sizeof (struct tree_vec));
- /* First fill in entry 0 with the constructors, and the next few with
- type conversion operators (if any). */
+ /* Save room for constructors and destructors. */
+ obstack_blank (&class_obstack, sizeof (struct tree_vec) + sizeof (struct tree *));
+
+ /* First fill in entry 0 with the constructors, entry 1 with destructors,
+ and the next few with type conversion operators (if any). */
for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
{
tree fn_name = DECL_NAME (fn_fields);
- if (fn_name == NULL_TREE)
- fn_name = name;
/* Clear out this flag.
@@ -1873,7 +1885,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
/* Note here that a copy ctor is private, so we don't dare generate
a default copy constructor for a class that has a member
of this type without making sure they have access to it. */
- if (fn_name == name)
+ if (fn_name == ctor_name)
{
tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields);
tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
@@ -1891,9 +1903,18 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
TYPE_HAS_NONPUBLIC_CTOR (t) = 2;
}
}
- /* Constructors are handled easily in search routines. */
- DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
- TREE_VEC_ELT (method_vec, 0) = fn_fields;
+ if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))
+ {
+ /* Destructors go in slot 1. */
+ DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 1);
+ TREE_VEC_ELT (method_vec, 1) = fn_fields;
+ }
+ else
+ {
+ /* Constructors go in slot 0. */
+ DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
+ TREE_VEC_ELT (method_vec, 0) = fn_fields;
+ }
}
else if (IDENTIFIER_TYPENAME_P (fn_name))
{
@@ -1914,10 +1935,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
{
tree fn_name = DECL_NAME (fn_fields);
- if (fn_name == NULL_TREE)
- fn_name = name;
- if (fn_name == name || IDENTIFIER_TYPENAME_P (fn_name))
+ if (fn_name == ctor_name || IDENTIFIER_TYPENAME_P (fn_name))
continue;
if (fn_name == ansi_opname[(int) MODIFY_EXPR])
@@ -1957,53 +1976,35 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
cp_warning ("all member functions in class `%T' are private", t);
}
- /* If there are constructors (and destructors), they are at the
- front. Place destructors at very front. Also warn if all
- constructors and/or destructors are private (in which case this
- class is effectively unusable. */
+ /* Warn if all destructors are private (in which case this class is
+ effectively unusable. */
if (TYPE_HAS_DESTRUCTOR (t))
{
- tree dtor, prev;
-
- for (dtor = TREE_VEC_ELT (method_vec, 0);
- dtor;
- prev = dtor, dtor = DECL_CHAIN (dtor))
- {
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor)))
- {
- if (TREE_PRIVATE (dtor)
- && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
- && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
- && warn_ctor_dtor_privacy)
- cp_warning ("`%#T' only defines a private destructor and has no friends",
- t);
- break;
- }
- }
+ tree dtor = TREE_VEC_ELT (method_vec, 1);
/* Wild parse errors can cause this to happen. */
if (dtor == NULL_TREE)
TYPE_HAS_DESTRUCTOR (t) = 0;
- else if (dtor != TREE_VEC_ELT (method_vec, 0))
- {
- DECL_CHAIN (prev) = DECL_CHAIN (dtor);
- DECL_CHAIN (dtor) = TREE_VEC_ELT (method_vec, 0);
- TREE_VEC_ELT (method_vec, 0) = dtor;
- }
+ else if (TREE_PRIVATE (dtor)
+ && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
+ && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
+ && warn_ctor_dtor_privacy)
+ cp_warning ("`%#T' only defines a private destructor and has no friends",
+ t);
}
/* Now for each member function (except for constructors and
destructors), compute where member functions of the same
name reside in base classes. */
if (n_baseclasses != 0
- && TREE_VEC_LENGTH (method_vec) > 1)
+ && TREE_VEC_LENGTH (method_vec) > 2)
{
int len = TREE_VEC_LENGTH (method_vec);
tree baselink_vec = make_tree_vec (len);
int any_links = 0;
tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t));
- for (i = 1; i < len; i++)
+ for (i = 2; i < len; i++)
{
TREE_VEC_ELT (baselink_vec, i)
= get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i)));
@@ -2016,44 +2017,6 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
obstack_free (current_obstack, baselink_vec);
}
-#if 0
- /* Now add the methods to the TYPE_METHODS of T, arranged in a chain. */
- {
- tree x, last_x = NULL_TREE;
- int limit = TREE_VEC_LENGTH (method_vec);
-
- for (i = 1; i < limit; i++)
- {
- for (x = TREE_VEC_ELT (method_vec, i); x; x = DECL_CHAIN (x))
- {
- if (last_x != NULL_TREE)
- TREE_CHAIN (last_x) = x;
- last_x = x;
- }
- }
-
- /* Put ctors and dtors at the front of the list. */
- x = TREE_VEC_ELT (method_vec, 0);
- if (x)
- {
- while (DECL_CHAIN (x))
- {
- /* Let's avoid being circular about this. */
- if (x == DECL_CHAIN (x))
- break;
- TREE_CHAIN (x) = DECL_CHAIN (x);
- x = DECL_CHAIN (x);
- }
- if (TREE_VEC_LENGTH (method_vec) > 1)
- TREE_CHAIN (x) = TREE_VEC_ELT (method_vec, 1);
- else
- TREE_CHAIN (x) = NULL_TREE;
- }
- }
-
- TYPE_METHODS (t) = method_vec;
-#endif
-
return method_vec;
}
@@ -2077,17 +2040,17 @@ duplicate_tag_error (t)
* This used to be in finish_struct, but it turns out that the
* TREE_CHAIN is used by dbxout_type_methods and perhaps some other things...
*/
- if (CLASSTYPE_METHOD_VEC(t))
+ if (CLASSTYPE_METHOD_VEC (t))
{
- tree tv = CLASSTYPE_METHOD_VEC(t);
- int i, len = TREE_VEC_LENGTH (tv);
+ tree method_vec = CLASSTYPE_METHOD_VEC (t);
+ int i, len = TREE_VEC_LENGTH (method_vec);
for (i = 0; i < len; i++)
{
- tree unchain = TREE_VEC_ELT (tv, i);
+ tree unchain = TREE_VEC_ELT (method_vec, i);
while (unchain != NULL_TREE)
{
TREE_CHAIN (unchain) = NULL_TREE;
- unchain = DECL_CHAIN(unchain);
+ unchain = DECL_CHAIN (unchain);
}
}
}
@@ -2829,7 +2792,8 @@ check_for_override (decl, ctype)
}
}
-/* Warn about hidden virtual functions that are not overridden in t. */
+/* Warn about hidden virtual functions that are not overridden in t.
+ We know that constructors and destructors don't apply. */
void
warn_hidden (t)
tree t;
@@ -2839,7 +2803,7 @@ warn_hidden (t)
int i;
/* We go through each separately named virtual function. */
- for (i = 1; i < n_methods; ++i)
+ for (i = 2; i < n_methods; ++i)
{
tree fndecl = TREE_VEC_ELT (method_vec, i);
@@ -2927,6 +2891,9 @@ finish_struct_anon (t)
else if (TREE_PROTECTED (*uelt))
cp_pedwarn_at ("protected member `%#D' in anonymous union",
*uelt);
+
+ TREE_PRIVATE (*uelt) = TREE_PRIVATE (field);
+ TREE_PROTECTED (*uelt) = TREE_PROTECTED (field);
}
}
}
@@ -3692,8 +3659,8 @@ finish_struct_1 (t, attributes, warn_anon)
tree fdecl = TREE_VALUE (access_decls);
tree flist = NULL_TREE;
tree name;
- tree access = TREE_PURPOSE(access_decls);
- int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
+ tree access = TREE_PURPOSE (access_decls);
+ int i = 2;
tree tmp;
if (TREE_CODE (fdecl) == TREE_LIST)
@@ -3811,9 +3778,11 @@ finish_struct_1 (t, attributes, warn_anon)
for (x = fields; x; x = TREE_CHAIN (x))
{
tree name = DECL_NAME (x);
- int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1;
+ int i = 2;
+
if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
continue;
+
for (; i < n_methods; ++i)
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
{
@@ -4368,14 +4337,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
{
tree tag = TYPE_NAME (TREE_VALUE (x));
- /* Check to see if it is already there. This will be the case if
- was do enum { red; } color; */
- if (chain_member (tag, fields))
- {
- x = TREE_CHAIN (x);
- continue;
- }
-
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 120948d6f66..7d9f12cf96e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -427,9 +427,9 @@ struct lang_type
unsigned marked4 : 1;
unsigned marked5 : 1;
unsigned marked6 : 1;
+ unsigned debug_requested : 1;
unsigned use_template : 2;
- unsigned debug_requested : 1;
unsigned has_method_call_overloaded : 1;
unsigned private_attr : 1;
unsigned got_semicolon : 1;
@@ -439,14 +439,13 @@ struct lang_type
unsigned is_signature_reference : 1;
unsigned has_default_implementation : 1;
- unsigned grokking_typedef : 1;
unsigned has_opaque_typedecls : 1;
unsigned sigtable_has_been_generated : 1;
unsigned was_anonymous : 1;
unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1;
-
unsigned has_const_init_ref : 1;
+
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1;
@@ -455,7 +454,7 @@ struct lang_type
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
- unsigned dummy : 19;
+ unsigned dummy : 20;
unsigned n_vancestors : 16;
} type_flags;
@@ -475,7 +474,7 @@ struct lang_type
union tree_node *tags;
char *memoized_table_entry;
- char *search_slot;
+ union tree_node *search_slot;
#ifdef ONLY_INT_FIELDS
unsigned int mode : 8;
@@ -604,9 +603,6 @@ struct lang_type
/* Nonzero means that this signature type has a default implementation. */
# define HAS_DEFAULT_IMPLEMENTATION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_default_implementation)
-/* Nonzero means that grokdeclarator works on a signature-local typedef. */
-#define SIGNATURE_GROKKING_TYPEDEF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.grokking_typedef)
-
/* Nonzero means that this signature contains opaque type declarations. */
#define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls)
@@ -664,8 +660,8 @@ struct lang_type
searched with TREE_CHAIN), or the first non-constructor function if
there are no type conversion operators. */
#define CLASSTYPE_FIRST_CONVERSION(NODE) \
- TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 1 \
- ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 1) \
+ TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 2 \
+ ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \
: NULL_TREE;
/* Pointer from any member function to the head of the list of
@@ -1491,6 +1487,7 @@ extern tree __ptmf_desc_type_node, __ptmd_desc_type_node;
extern tree type_info_type_node;
extern tree class_star_type_node;
extern tree this_identifier;
+extern tree ctor_identifier, dtor_identifier;
extern tree pfn_identifier;
extern tree index_identifier;
extern tree delta_identifier;
@@ -1675,6 +1672,8 @@ extern int current_function_parms_stored;
#define THIS_NAME "this"
#define DESTRUCTOR_NAME_FORMAT "~%s"
#define FILE_FUNCTION_PREFIX_LEN 9
+#define CTOR_NAME "__ct"
+#define DTOR_NAME "__dt"
#define IN_CHARGE_NAME "__in_chrg"
@@ -2047,6 +2046,7 @@ extern tree build_ptrmemfunc_type PROTO((tree));
/* the grokdeclarator prototype is in decl.h */
extern int parmlist_is_exprlist PROTO((tree));
extern tree xref_tag PROTO((tree, tree, tree, int));
+extern tree xref_tag_from_type PROTO((tree, tree, int));
extern void xref_basetypes PROTO((tree, tree, tree, tree));
extern tree start_enum PROTO((tree));
extern tree finish_enum PROTO((tree, tree));
@@ -2099,7 +2099,7 @@ extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree));
extern tree coerce_new_type PROTO((tree));
extern tree coerce_delete_type PROTO((tree));
extern void import_export_vtable PROTO((tree, tree, int));
-extern void walk_vtables PROTO((void (*)(), void (*)()));
+extern int walk_vtables PROTO((void (*)(), int (*)()));
extern void walk_sigtables PROTO((void (*)(), void (*)()));
extern void finish_file PROTO((void));
extern void warn_if_unknown_interface PROTO((tree));
@@ -2203,7 +2203,7 @@ extern void reinit_parse_for_function PROTO((void));
extern int *init_parse PROTO((void));
extern void print_parse_statistics PROTO((void));
extern void extract_interface_info PROTO((void));
-extern void set_vardecl_interface_info PROTO((tree, tree));
+extern int set_vardecl_interface_info PROTO((tree, tree));
extern void do_pending_inlines PROTO((void));
extern void process_next_inline PROTO((tree));
/* skip restore_pending_input */
@@ -2231,7 +2231,6 @@ extern tree make_lang_type PROTO((enum tree_code));
extern void copy_decl_lang_specific PROTO((tree));
extern void dump_time_statistics PROTO((void));
/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */
-extern void compiler_error_with_decl PROTO((tree, char *));
extern void yyerror PROTO((char *));
/* in errfn.c */
@@ -2472,7 +2471,6 @@ extern tree build_ptrmemfunc PROTO((tree, tree, int));
/* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree));
extern tree binfo_or_else PROTO((tree, tree));
-extern void error_with_aggr_type (); /* PROTO((tree, char *, HOST_WIDE_INT)); */
extern void readonly_error PROTO((tree, char *, int));
extern void abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index e6a047a988f..f9f3dfc8e3b 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -201,6 +201,14 @@ cp_convert_to_pointer (type, expr)
if (IS_AGGR_TYPE (intype))
{
tree rval;
+
+ if (TYPE_SIZE (complete_type (intype)) == NULL_TREE)
+ {
+ cp_error ("can't convert from incomplete type `%T' to `%T'",
+ intype, type);
+ return error_mark_node;
+ }
+
rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
if (rval)
{
@@ -774,7 +782,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call
- (NULL_TREE, constructor_name_full (type),
+ (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
| LOOKUP_ONLYCONVERTING)))
@@ -785,7 +793,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{
extern tree static_aggregates;
tree t = get_temp_name (type, toplevel_bindings_p ());
- init = build_method_call (t, constructor_name_full (type),
+ init = build_method_call (t, ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
@@ -800,7 +808,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
}
else
{
- init = build_method_call (NULL_TREE, constructor_name_full (type),
+ init = build_method_call (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
@@ -919,47 +927,9 @@ convert_to_aggr (type, expr, msgp, protect)
parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);
parmtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes);
-#if 0
- method_name = build_decl_overload (name, parmtypes, 1);
-
- /* constructors are up front. */
- fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
- if (TYPE_HAS_DESTRUCTOR (basetype))
- fndecl = DECL_CHAIN (fndecl);
-
- while (fndecl)
- {
- if (DECL_ASSEMBLER_NAME (fndecl) == method_name)
- {
- function = fndecl;
- if (protect)
- {
- if (TREE_PRIVATE (fndecl))
- {
- can_be_private =
- (basetype == current_class_type
- || is_friend (basetype, current_function_decl)
- || purpose_member (basetype, DECL_ACCESS (fndecl)));
- if (! can_be_private)
- goto found;
- }
- else if (TREE_PROTECTED (fndecl))
- {
- if (! can_be_protected)
- goto found;
- }
- }
- goto found_and_ok;
- }
- fndecl = DECL_CHAIN (fndecl);
- }
-#endif
-
/* No exact conversion was found. See if an approximate
one will do. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
- if (TYPE_HAS_DESTRUCTOR (basetype))
- fndecl = DECL_CHAIN (fndecl);
{
int saw_private = 0;
@@ -1119,7 +1089,9 @@ convert_pointer_to_real (binfo, expr)
binfo = NULL_TREE;
}
- ptr_type = build_pointer_type (type);
+ ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)),
+ TYPE_VOLATILE (TREE_TYPE (intype)));
+ ptr_type = build_pointer_type (ptr_type);
if (ptr_type == TYPE_MAIN_VARIANT (intype))
return expr;
@@ -1338,11 +1310,12 @@ cp_convert (type, expr, convtype, flags)
}
if (TYPE_HAS_CONSTRUCTOR (complete_type (type)))
- ctor = build_method_call (NULL_TREE, constructor_name_full (type),
+ ctor = build_method_call (NULL_TREE, ctor_identifier,
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
(flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY
- | (convtype&CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)
+ | (convtype & CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)
+ | (flags & LOOKUP_NO_CONVERSION)
| (conversion ? LOOKUP_NO_CONVERSION : 0));
if (ctor == error_mark_node)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index eb7e17e9883..9855baca005 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -294,6 +294,7 @@ tree base_init_expr;
Identifiers for `this' in member functions and the auto-delete
parameter for destructors. */
tree this_identifier, in_charge_identifier;
+tree ctor_identifier, dtor_identifier;
/* Used in pointer to member functions, in vtables, and in sigtables. */
tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier;
tree pfn_or_delta2_identifier, tag_identifier;
@@ -1461,11 +1462,11 @@ print_binding_level (lvl)
/* We can probably fit 3 names to a line? */
for (t = lvl->names; t; t = TREE_CHAIN (t))
{
- if (no_print_functions && (TREE_CODE(t) == FUNCTION_DECL))
+ if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
continue;
if (no_print_builtins
- && (TREE_CODE(t) == TYPE_DECL)
- && (!strcmp(DECL_SOURCE_FILE(t),"<built-in>")))
+ && (TREE_CODE (t) == TYPE_DECL)
+ && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
continue;
/* Function decls tend to have longer names. */
@@ -4298,16 +4299,25 @@ lookup_namespace_name (namespace, name)
tree namespace, name;
{
struct binding_level *b = (struct binding_level *)NAMESPACE_LEVEL (namespace);
- tree x;
+ tree x = NULL_TREE;
- for (x = NULL_TREE; b && !x; b = b->level_chain)
+#if 1
+ /* This searches just one level. */
+ if (b)
{
for (x = b->names; x; x = TREE_CHAIN (x))
if (DECL_NAME (x) == name || DECL_ASSEMBLER_NAME (x) == name)
break;
- /* Must find directly in the namespace. */
- break;
}
+#else
+ /* This searches all levels. */
+ for (; b && !x; b = b->level_chain)
+ {
+ for (x = b->names; x; x = TREE_CHAIN (x))
+ if (DECL_NAME (x) == name || DECL_ASSEMBLER_NAME (x) == name)
+ break;
+ }
+#endif
return x;
}
@@ -4370,7 +4380,7 @@ lookup_name_real (name, prefer_type, nonclass)
if (prefer_type == -2)
{
extern int looking_for_typename;
- tree type;
+ tree type = NULL_TREE;
yylex = 1;
prefer_type = looking_for_typename;
@@ -4773,6 +4783,8 @@ init_decl_processing ()
this_identifier = get_identifier (THIS_NAME);
in_charge_identifier = get_identifier (IN_CHARGE_NAME);
+ ctor_identifier = get_identifier (CTOR_NAME);
+ dtor_identifier = get_identifier (DTOR_NAME);
pfn_identifier = get_identifier (VTABLE_PFN_NAME);
index_identifier = get_identifier (VTABLE_INDEX_NAME);
delta_identifier = get_identifier (VTABLE_DELTA_NAME);
@@ -5525,7 +5537,7 @@ init_type_desc()
tdecl = lookup_name (get_identifier ("type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
- __t_desc_type_node = TREE_TYPE(tdecl);
+ __t_desc_type_node = TREE_TYPE (tdecl);
#if 0
__tp_desc_type_node = build_pointer_type (__t_desc_type_node);
#endif
@@ -5651,10 +5663,7 @@ shadow_tag (declspecs)
{
my_friendly_assert (TYPE_NAME (value) != NULL_TREE, 261);
- if (code == ENUMERAL_TYPE && TYPE_SIZE (value) == 0)
- cp_error ("forward declaration of `%#T'", value);
-
- else if (IS_AGGR_TYPE (value) && CLASSTYPE_USE_TEMPLATE (value))
+ if (IS_AGGR_TYPE (value) && CLASSTYPE_USE_TEMPLATE (value))
{
if (CLASSTYPE_IMPLICIT_INSTANTIATION (value)
&& TYPE_SIZE (value) == NULL_TREE)
@@ -7916,8 +7925,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
type = ctor_return_type;
else if (current_class_type
&& IS_SIGNATURE (current_class_type)
- && (RIDBIT_SETP (RID_TYPEDEF, specbits)
- || SIGNATURE_GROKKING_TYPEDEF (current_class_type))
+ && RIDBIT_SETP (RID_TYPEDEF, specbits)
&& (decl_context == FIELD || decl_context == NORMAL))
{
explicit_int = 0;
@@ -8147,8 +8155,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
is used in a signature member function declaration. */
if (decl_context == FIELD
&& IS_SIGNATURE (current_class_type)
- && RIDBIT_NOTSETP(RID_TYPEDEF, specbits)
- && !SIGNATURE_GROKKING_TYPEDEF (current_class_type))
+ && RIDBIT_NOTSETP (RID_TYPEDEF, specbits))
{
if (constp)
{
@@ -8192,82 +8199,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
&& (RIDBIT_SETP (RID_REGISTER, specbits)
|| RIDBIT_SETP (RID_AUTO, specbits)))
;
+ else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
+ ;
else if (decl_context == FIELD
- && RIDBIT_SETP (RID_TYPEDEF, specbits))
- {
- /* Processing a typedef declaration nested within a class type
- definition. */
- register tree scanner;
- register tree previous_declspec;
- tree loc_typedecl;
-
- if (initialized)
- error ("typedef declaration includes an initializer");
-
- /* To process a class-local typedef declaration, we descend down
- the chain of declspecs looking for the `typedef' spec. When
- we find it, we replace it with `static', and then recursively
- call `grokdeclarator' with the original declarator and with
- the newly adjusted declspecs. This call should return a
- FIELD_DECL node with the TREE_TYPE (and other parts) set
- appropriately. We can then just change the TREE_CODE on that
- from FIELD_DECL to TYPE_DECL and we're done. */
-
- for (previous_declspec = NULL_TREE, scanner = declspecs;
- scanner;
- previous_declspec = scanner, scanner = TREE_CHAIN (scanner))
- {
- if (TREE_VALUE (scanner) == ridpointers[(int) RID_TYPEDEF])
- break;
- }
-
- if (previous_declspec)
- TREE_CHAIN (previous_declspec) = TREE_CHAIN (scanner);
- else
- declspecs = TREE_CHAIN (scanner);
-
- declspecs = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC],
- declspecs);
-
- /* In the recursive call to grokdeclarator we need to know
- whether we are working on a signature-local typedef. */
- if (IS_SIGNATURE (current_class_type))
- SIGNATURE_GROKKING_TYPEDEF (current_class_type) = 1;
-
- loc_typedecl =
- grokdeclarator (declarator, declspecs, FIELD, 0, NULL_TREE, NULL_TREE);
-
- if (previous_declspec)
- TREE_CHAIN (previous_declspec) = scanner;
-
- if (loc_typedecl != error_mark_node)
- {
- register int i = sizeof (struct lang_decl_flags) / sizeof (int);
- register int *pi;
-
- TREE_SET_CODE (loc_typedecl, TYPE_DECL);
- /* This is the same field as DECL_ARGUMENTS, which is set for
- function typedefs by the above grokdeclarator. */
- DECL_NESTED_TYPENAME (loc_typedecl) = 0;
-
- pi = (int *) permalloc (sizeof (struct lang_decl_flags));
- while (i > 0)
- pi[--i] = 0;
- DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
- }
-
- if (IS_SIGNATURE (current_class_type))
- {
- SIGNATURE_GROKKING_TYPEDEF (current_class_type) = 0;
- if (loc_typedecl != error_mark_node && opaque_typedef)
- SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
- }
-
- return loc_typedecl;
- }
- else if (decl_context == FIELD
- && (! IS_SIGNATURE (current_class_type)
- || SIGNATURE_GROKKING_TYPEDEF (current_class_type))
+ && ! IS_SIGNATURE (current_class_type)
/* C++ allows static class elements */
&& RIDBIT_SETP (RID_STATIC, specbits))
/* C++ also allows inlines and signed and unsigned elements,
@@ -8511,7 +8446,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
integer_one_node), 1));
if (! TREE_CONSTANT (itype))
itype = variable_size (itype);
- itype = build_index_type (itype);
+
+ /* If we're a parm, we need to have a permanent type so
+ mangling checks for re-use will work right. If both the
+ element and index types are permanent, the array type
+ will be, too. */
+ if (decl_context == PARM
+ && allocation_temporary_p () && TREE_PERMANENT (type))
+ {
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ itype = build_index_type (itype);
+ pop_obstacks ();
+ }
+ else
+ itype = build_index_type (itype);
+
dont_grok_size:
resume_momentary (yes);
}
@@ -8636,7 +8585,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
}
{
RID_BIT_TYPE tmp_bits;
- bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof(RID_BIT_TYPE));
+ bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE));
RIDBIT_RESET (RID_INLINE, tmp_bits);
RIDBIT_RESET (RID_STATIC, tmp_bits);
if (RIDBIT_ANY_SET (tmp_bits))
@@ -9034,7 +8983,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
}
}
- if (RIDBIT_SETP (RID_TYPEDEF, specbits))
+ if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)
{
tree decl;
@@ -9076,7 +9025,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
}
}
- decl = build_decl (TYPE_DECL, declarator, type);
+ if (decl_context == FIELD)
+ {
+ decl = build_lang_decl (TYPE_DECL, declarator, type);
+ if (IS_SIGNATURE (current_class_type) && opaque_typedef)
+ SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
+ }
+ else
+ decl = build_decl (TYPE_DECL, declarator, type);
+
if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
{
cp_error_at ("typedef name may not be class-qualified", decl);
@@ -9802,8 +9759,7 @@ grokparms (first_parm, funcdef_flag)
{
/* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST)
- error ("invalid string constant `%s'",
- TREE_STRING_POINTER (decl));
+ cp_error ("invalid string constant `%E'", decl);
else if (TREE_CODE (decl) == INTEGER_CST)
error ("invalid integer constant in parameter list, did you forget to give parameter name?");
continue;
@@ -9824,10 +9780,10 @@ grokparms (first_parm, funcdef_flag)
else if (TREE_CODE (type) == METHOD_TYPE)
{
if (DECL_NAME (decl))
- /* Cannot use `error_with_decl' here because
+ /* Cannot use the decl here because
we don't have DECL_CONTEXT set up yet. */
- error ("parameter `%s' invalidly declared method type",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
+ cp_error ("parameter `%D' invalidly declared method type",
+ DECL_NAME (decl));
else
error ("parameter invalidly declared method type");
type = build_pointer_type (type);
@@ -9836,8 +9792,8 @@ grokparms (first_parm, funcdef_flag)
else if (TREE_CODE (type) == OFFSET_TYPE)
{
if (DECL_NAME (decl))
- error ("parameter `%s' invalidly declared offset type",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
+ cp_error ("parameter `%D' invalidly declared offset type",
+ DECL_NAME (decl));
else
error ("parameter invalidly declared offset type");
type = build_pointer_type (type);
@@ -10345,7 +10301,7 @@ xref_tag (code_type_node, name, binfo, globalize)
}
/* 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) && TREE_MANGLED (name))
ref = t;
else
ref = lookup_tag (code, name, b, 1);
@@ -10387,6 +10343,8 @@ xref_tag (code_type_node, name, binfo, globalize)
if (code == ENUMERAL_TYPE)
{
+ cp_error ("use of enum `%#D' without previous declaration", name);
+
ref = make_node (ENUMERAL_TYPE);
/* Give the type a default layout like unsigned int
@@ -10462,6 +10420,25 @@ xref_tag (code_type_node, name, binfo, globalize)
return ref;
}
+tree
+xref_tag_from_type (old, id, globalize)
+ tree old, id;
+ int globalize;
+{
+ tree code_type_node;
+
+ if (TREE_CODE (old) == RECORD_TYPE)
+ code_type_node = (CLASSTYPE_DECLARED_CLASS (old)
+ ? class_type_node : record_type_node);
+ else
+ code_type_node = union_type_node;
+
+ if (id == NULL_TREE)
+ id = TYPE_IDENTIFIER (old);
+
+ return xref_tag (code_type_node, id, NULL_TREE, globalize);
+}
+
void
xref_basetypes (code_type_node, name, ref, binfo)
tree code_type_node;
@@ -11048,7 +11025,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
announce_function (decl1);
- if (! current_template_parms || ! uses_template_parms (TREE_TYPE (fntype)))
+ if (! current_template_parms)
{
if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
{
@@ -11533,9 +11510,6 @@ finish_function (lineno, call_poplevel, nested)
if (fndecl == NULL_TREE)
return;
- if (! nested && hack_decl_function_context (fndecl) != NULL_TREE)
- nested = 1;
-
fntype = TREE_TYPE (fndecl);
/* TREE_READONLY (fndecl) = 1;
@@ -11715,7 +11689,7 @@ finish_function (lineno, call_poplevel, nested)
}
/* End of destructor. */
- expand_end_bindings (NULL_TREE, getdecls() != NULL_TREE, 0);
+ expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0);
poplevel (2, 0, 0); /* XXX change to 1 */
/* Back to the top of destructor. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fae800e8205..a902a4f473f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -757,27 +757,27 @@ grok_x_components (specs, components)
/* This code may be needed for UNION_TYPEs as
well. */
tcode = record_type_node;
- if (CLASSTYPE_DECLARED_CLASS(t))
+ if (CLASSTYPE_DECLARED_CLASS (t))
tcode = class_type_node;
- else if (IS_SIGNATURE(t))
+ else if (IS_SIGNATURE (t))
tcode = signature_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
- if (TYPE_CONTEXT(t))
- CLASSTYPE_NO_GLOBALIZE(t) = 1;
+ if (TYPE_CONTEXT (t))
+ CLASSTYPE_NO_GLOBALIZE (t) = 1;
return NULL_TREE;
break;
case UNION_TYPE:
case ENUMERAL_TYPE:
- if (TREE_CODE(t) == UNION_TYPE)
+ if (TREE_CODE (t) == UNION_TYPE)
tcode = union_type_node;
else
tcode = enum_type_node;
t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
- if (TREE_CODE(t) == UNION_TYPE && TYPE_CONTEXT(t))
- CLASSTYPE_NO_GLOBALIZE(t) = 1;
+ if (TREE_CODE (t) == UNION_TYPE && TYPE_CONTEXT (t))
+ CLASSTYPE_NO_GLOBALIZE (t) = 1;
if (TREE_CODE (t) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
{
@@ -1233,7 +1233,11 @@ check_classfn (ctype, function)
end = TREE_VEC_END (method_vec);
/* First suss out ctors and dtors. */
- if (*methods && fn_name == DECL_NAME (*methods))
+ if (*methods && fn_name == DECL_NAME (*methods)
+ && DECL_CONSTRUCTOR_P (function))
+ goto got_it;
+ if (*++methods && fn_name == DECL_NAME (*methods)
+ && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
goto got_it;
while (++methods != end)
@@ -1295,8 +1299,8 @@ check_classfn (ctype, function)
function, ctype);
}
- /* If we did not find the method in the class, add it to
- avoid spurious errors. */
+ /* If we did not find the method in the class, add it to avoid
+ spurious errors. */
add_method (ctype, methods, function);
return NULL_TREE;
}
@@ -1381,16 +1385,6 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree, attrlist)
DECL_CLASS_CONTEXT (value) = current_class_type;
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
- /* If we declare a typedef name for something that has no name,
- the typedef name is used for linkage. See 7.1.3 p4 94/0158. */
- if (TYPE_NAME (TREE_TYPE (value))
- && TREE_CODE (TYPE_NAME (TREE_TYPE (value))) == TYPE_DECL
- && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (value))))
- {
- TYPE_NAME (TREE_TYPE (value)) = value;
- TYPE_STUB_DECL (TREE_TYPE (value)) = value;
- }
-
pushdecl_class_level (value);
return value;
}
@@ -2094,6 +2088,7 @@ get_temp_name (type, staticp)
}
TREE_USED (decl) = 1;
TREE_STATIC (decl) = staticp;
+ DECL_ARTIFICIAL (decl) = 1;
/* If this is a local variable, then lay out its rtl now.
Otherwise, callers of this function are responsible for dealing
@@ -2529,7 +2524,7 @@ import_export_template (type)
}
}
-static void
+static int
finish_prevtable_vardecl (prev, vars)
tree prev, vars;
{
@@ -2550,6 +2545,9 @@ finish_prevtable_vardecl (prev, vars)
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
+#ifdef ADJUST_VTABLE_LINKAGE
+ ADJUST_VTABLE_LINKAGE (vars, method);
+#endif
break;
}
}
@@ -2570,14 +2568,17 @@ finish_prevtable_vardecl (prev, vars)
at the top level. */
build_t_desc (ctype, 1);
}
+
+ return 1;
}
-static void
+static int
finish_vtable_vardecl (prev, vars)
tree prev, vars;
{
if (write_virtuals >= 0
- && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
+ && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))
+ && ! TREE_ASM_WRITTEN (vars))
{
#if 0
/* The long term plan it to make the TD entries statically initialized,
@@ -2622,29 +2623,33 @@ finish_vtable_vardecl (prev, vars)
#endif /* DWARF_DEBUGGING_INFO */
rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
+ return 1;
}
else if (! TREE_USED (vars))
/* We don't know what to do with this one yet. */
- return;
+ return 0;
/* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars);
+ return 0;
}
-static void
+static int
prune_vtable_vardecl (prev, vars)
tree prev, vars;
{
/* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars);
+ return 1;
}
-void
+int
walk_vtables (typedecl_fn, vardecl_fn)
register void (*typedecl_fn)();
- register void (*vardecl_fn)();
+ register int (*vardecl_fn)();
{
tree prev, vars;
+ int flag = 0;
for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars))
{
@@ -2652,7 +2657,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars))
{
- if (vardecl_fn) (*vardecl_fn) (prev, vars);
+ if (vardecl_fn)
+ flag |= (*vardecl_fn) (prev, vars);
if (prev && TREE_CHAIN (prev) != vars)
continue;
@@ -2667,6 +2673,8 @@ walk_vtables (typedecl_fn, vardecl_fn)
prev = vars;
}
+
+ return flag;
}
static void
@@ -2910,7 +2918,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
NULL_TREE));
- expand_end_bindings (getdecls(), 1, 0);
+ expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
@@ -3027,7 +3035,7 @@ finish_file ()
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
NULL_TREE));
- expand_end_bindings (getdecls(), 1, 0);
+ expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
@@ -3107,7 +3115,7 @@ finish_file ()
SET_DECL_ARTIFICIAL (vars);
pushdecl (vars);
- walk_vtables ((void (*)())0, finish_vtable_vardecl);
+ reconsider |= walk_vtables ((void (*)())0, finish_vtable_vardecl);
while (*p)
{
@@ -3314,6 +3322,8 @@ build_expr_from_tree (t)
case TRUTH_NOT_EXPR:
case ADDR_EXPR:
case CONVERT_EXPR: /* Unary + */
+ if (TREE_TYPE (t))
+ return t;
return build_x_unary_op (TREE_CODE (t),
build_expr_from_tree (TREE_OPERAND (t, 0)));
@@ -3472,6 +3482,9 @@ build_expr_from_tree (t)
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1);
+ case THROW_EXPR:
+ return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
+
default:
return t;
}
@@ -3599,6 +3612,7 @@ void
do_namespace_alias (alias, namespace)
tree alias, namespace;
{
+ sorry ("namespace alias");
}
tree
@@ -3651,6 +3665,7 @@ void
do_using_directive (namespace)
tree namespace;
{
+ sorry ("using directive");
}
void
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ccce90f5fed..bb93dd4a17c 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -543,7 +543,7 @@ ident_fndecl (t)
#endif
#define GLOBAL_IORD_P(NODE) \
- !strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1)
+ ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
void
dump_global_iord (t)
@@ -581,12 +581,9 @@ dump_decl (t, v)
case TYPE_DECL:
{
/* Don't say 'typedef class A' */
- tree type = TREE_TYPE (t);
- if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type))
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && type == TYPE_MAIN_VARIANT (type))
+ if (DECL_ARTIFICIAL (t))
{
- dump_type (type, v);
+ dump_type (TREE_TYPE (t), v);
break;
}
}
@@ -1087,7 +1084,7 @@ dump_expr (t, nop)
args = TREE_CHAIN (args);
}
dump_expr (fn, 0);
- OB_PUTC('(');
+ OB_PUTC ('(');
dump_expr_list (args);
OB_PUTC (')');
}
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 71421ccc8fa..41742a73251 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1398,7 +1398,7 @@ expand_builtin_throw ()
/* Fall into epilogue to unwind prologue. */
}
- expand_end_bindings (getdecls(), 1, 0);
+ expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
@@ -1626,7 +1626,7 @@ start_anon_func ()
void
end_anon_func ()
{
- expand_end_bindings (getdecls(), 1, 0);
+ expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
@@ -1809,6 +1809,8 @@ build_throw (e)
{
if (e != error_mark_node)
{
+ if (current_template_parms)
+ return build_min (THROW_EXPR, void_type_node, e);
e = build1 (THROW_EXPR, void_type_node, e);
TREE_SIDE_EFFECTS (e) = 1;
TREE_USED (e) = 1;
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index fc59cb6cfa2..9986698d20f 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -366,6 +366,9 @@ do_case (start, end)
{
tree value1 = NULL_TREE, value2 = NULL_TREE, label;
+ if (start && POINTER_TYPE_P (TREE_TYPE (start)))
+ error ("pointers are not permitted as case values");
+
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi
index 64ffb84068a..64d9776cac2 100644
--- a/gcc/cp/gxxint.texi
+++ b/gcc/cp/gxxint.texi
@@ -1226,22 +1226,22 @@ stands.
Only exact type matching or reference matching of throw types works when
-fno-rtti is used. Only works on a SPARC (like Suns), i386, arm,
-rs6000, PowerPC, Alpha, mips and VAX machines. Partial support is in
-for all other machines, but a stack unwinder called __unwind_function
-has to be written, and added to libgcc2 for them. The new EH code
-doesn't rely upon the __unwind_function for C++ code, instead it creates
-per function unwinders right inside the function, unfortunately, on many
-platforms the definition of RETURN_ADDR_RTX in the tm.h file for the
-machine port is wrong. The HPPA has a brain dead abi that prevents
-exception handling from just working. See below for details on
-__unwind_function. Don't expect exception handling to work right if you
-optimize, in fact the compiler will probably core dump. RTL_EXPRs for
-EH cond variables for && and || exprs should probably be wrapped in
-UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the
-UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR
-should be ripped out and exactly one finalization allowed to be expanded
-by the backend. I talked with kenner about this, and we have to allow
-multiple expansions.
+rs6000, PowerPC, Alpha, mips, VAX, and m68k machines. Partial support
+is in for all other machines, but a stack unwinder called
+__unwind_function has to be written, and added to libgcc2 for them. The
+new EH code doesn't rely upon the __unwind_function for C++ code,
+instead it creates per function unwinders right inside the function,
+unfortunately, on many platforms the definition of RETURN_ADDR_RTX in
+the tm.h file for the machine port is wrong. The HPPA has a brain dead
+abi that prevents exception handling from just working. See below for
+details on __unwind_function. Don't expect exception handling to work
+right if you optimize, in fact the compiler will probably core dump.
+RTL_EXPRs for EH cond variables for && and || exprs should probably be
+wrapped in UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be
+unsaved, and the UNSAVE_EXPR code should be in the backend, or
+alternatively, UNSAVE_EXPR should be ripped out and exactly one
+finalization allowed to be expanded by the backend. I talked with
+kenner about this, and we have to allow multiple expansions.
We only do pointer conversions on exception matching a la 15.3 p2 case
3: `A handler with type T, const T, T&, or const T& is a match for a
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 2858f653e1f..289cef8e117 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -596,7 +596,7 @@ emit_base_init (t, immediately)
target_temp_slot_level = temp_slot_level;
member = convert_pointer_to_real (base_binfo, current_class_decl);
- expand_aggr_init_1 (base_binfo, 0,
+ expand_aggr_init_1 (base_binfo, NULL_TREE,
build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
expand_cleanups_to (old_cleanups);
@@ -935,7 +935,6 @@ expand_member_init (exp, name, init)
tree basetype = NULL_TREE, field;
tree parm;
tree rval, type;
- tree actual_name;
if (exp == NULL_TREE)
return; /* complain about this later */
@@ -1071,14 +1070,10 @@ expand_member_init (exp, name, init)
TREE_USED (exp) = 1;
}
type = TYPE_MAIN_VARIANT (TREE_TYPE (field));
- actual_name = TYPE_IDENTIFIER (type);
parm = build_component_ref (exp, name, 0, 0);
- /* Now get to the constructor. */
+ /* Now get to the constructors. */
fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
- /* Get past destructor, if any. */
- if (TYPE_HAS_DESTRUCTOR (type))
- fndecl = DECL_CHAIN (fndecl);
if (fndecl)
my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209);
@@ -1102,7 +1097,8 @@ expand_member_init (exp, name, init)
init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL);
if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node)
- rval = build_method_call (NULL_TREE, actual_name, init, NULL_TREE, LOOKUP_NORMAL);
+ rval = build_method_call (NULL_TREE, ctor_identifier, init,
+ TYPE_BINFO (type), LOOKUP_NORMAL);
else
return;
@@ -1245,14 +1241,15 @@ expand_aggr_init (exp, init, alias_this, flags)
}
static void
-expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
+expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
tree binfo;
tree true_exp, exp;
- tree type;
tree init;
int alias_this;
int flags;
{
+ tree type = TREE_TYPE (exp);
+
/* It fails because there may not be a constructor which takes
its own type as the first (or only parameter), but which does
take other types via a conversion. So, if the thing initializing
@@ -1301,7 +1298,7 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
{
if (flags & LOOKUP_ONLYCONVERTING)
flags |= LOOKUP_NO_CONVERSION;
- rval = build_method_call (exp, constructor_name_full (type),
+ rval = build_method_call (exp, ctor_identifier,
parms, binfo, flags);
/* Private, protected, or otherwise unavailable. */
@@ -1534,7 +1531,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
tree parms = build_tree_list (NULL_TREE, init);
tree as_cons = NULL_TREE;
if (TYPE_HAS_CONSTRUCTOR (type))
- as_cons = build_method_call (exp, constructor_name_full (type),
+ as_cons = build_method_call (exp, ctor_identifier,
parms, binfo,
LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION);
if (as_cons != NULL_TREE && as_cons != error_mark_node)
@@ -1551,7 +1548,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
/* We know that expand_default_init can handle everything we want
at this point. */
- expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags);
+ expand_default_init (binfo, true_exp, exp, init, alias_this, flags);
}
/* Report an error if NAME is not the name of a user-defined,
@@ -1781,7 +1778,7 @@ build_offset_ref (type, name)
tree type, name;
{
tree decl, fnfields, fields, t = error_mark_node;
- tree basetypes = NULL_TREE;
+ tree basebinfo = NULL_TREE;
int dtor = 0;
if (current_template_parms)
@@ -1843,9 +1840,9 @@ build_offset_ref (type, name)
}
if (current_class_type == 0
- || get_base_distance (type, current_class_type, 0, &basetypes) == -1)
+ || get_base_distance (type, current_class_type, 0, &basebinfo) == -1)
{
- basetypes = TYPE_BINFO (type);
+ basebinfo = TYPE_BINFO (type);
decl = build1 (NOP_EXPR, type, error_mark_node);
}
else if (current_class_decl == 0)
@@ -1853,8 +1850,18 @@ build_offset_ref (type, name)
else
decl = C_C_D;
- fnfields = lookup_fnfields (basetypes, name, 1);
- fields = lookup_field (basetypes, name, 0, 0);
+ if (constructor_name (BINFO_TYPE (basebinfo)) == name)
+ if (dtor)
+ name = dtor_identifier;
+ else
+ name = ctor_identifier;
+ else
+ if (dtor)
+ my_friendly_abort (999);
+
+
+ fnfields = lookup_fnfields (basebinfo, name, 1);
+ fields = lookup_field (basebinfo, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
return error_mark_node;
@@ -1863,91 +1870,58 @@ build_offset_ref (type, name)
lookup_fnfield. */
if (fnfields)
{
- basetypes = TREE_PURPOSE (fnfields);
+ extern int flag_save_memoized_contexts;
+ basebinfo = TREE_PURPOSE (fnfields);
/* Go from the TREE_BASELINK to the member function info. */
t = TREE_VALUE (fnfields);
- if (fields)
+ if (DECL_CHAIN (t) == NULL_TREE)
{
- if (DECL_FIELD_CONTEXT (fields) == DECL_FIELD_CONTEXT (t))
+ tree access;
+
+ /* unique functions are handled easily. */
+ unique:
+ access = compute_access (basebinfo, t);
+ if (access == access_protected_node)
{
- error ("ambiguous member reference: member `%s' defined as both field and function",
- IDENTIFIER_POINTER (name));
+ cp_error_at ("member function `%#D' is protected", t);
+ error ("in this context");
return error_mark_node;
}
- if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (fields), DECL_FIELD_CONTEXT (t)))
- ;
- else if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (t), DECL_FIELD_CONTEXT (fields)))
- t = fields;
- else
+ if (access == access_private_node)
{
- error ("ambiguous member reference: member `%s' derives from distinct classes in multiple inheritance lattice");
+ cp_error_at ("member function `%#D' is private", t);
+ error ("in this context");
return error_mark_node;
}
+ mark_used (t);
+ return build (OFFSET_REF, TREE_TYPE (t), decl, t);
}
- if (t == TREE_VALUE (fnfields))
- {
- extern int flag_save_memoized_contexts;
+ /* FNFIELDS is most likely allocated on the search_obstack,
+ which will go away after this class scope. If we need
+ to save this value for later (either for memoization
+ or for use as an initializer for a static variable), then
+ do so here.
- if (DECL_CHAIN (t) == NULL_TREE || dtor)
- {
- tree access;
-
- /* unique functions are handled easily. */
- unique:
- access = compute_access (basetypes, t);
- if (access == access_protected_node)
- {
- cp_error_at ("member function `%#D' is protected", t);
- error ("in this context");
- return error_mark_node;
- }
- if (access == access_private_node)
- {
- cp_error_at ("member function `%#D' is private", t);
- error ("in this context");
- return error_mark_node;
- }
- mark_used (t);
- return build (OFFSET_REF, TREE_TYPE (t), decl, t);
- }
+ ??? The smart thing to do for the case of saving initializers
+ is to resolve them before we're done with this scope. */
+ if (!TREE_PERMANENT (fnfields)
+ && ((flag_save_memoized_contexts && global_bindings_p ())
+ || ! allocation_temporary_p ()))
+ fnfields = copy_list (fnfields);
- /* overloaded functions may need more work. */
- if (name == constructor_name (type))
- {
- if (TYPE_HAS_DESTRUCTOR (type)
- && DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE)
- {
- t = DECL_CHAIN (t);
- goto unique;
- }
- }
- /* FNFIELDS is most likely allocated on the search_obstack,
- which will go away after this class scope. If we need
- to save this value for later (either for memoization
- or for use as an initializer for a static variable), then
- do so here.
-
- ??? The smart thing to do for the case of saving initializers
- is to resolve them before we're done with this scope. */
- if (!TREE_PERMANENT (fnfields)
- && ((flag_save_memoized_contexts && global_bindings_p ())
- || ! allocation_temporary_p ()))
- fnfields = copy_list (fnfields);
-
- t = build_tree_list (error_mark_node, fnfields);
- TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
- return t;
- }
+ t = build_tree_list (error_mark_node, fnfields);
+ TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
+ return t;
}
/* Now that we know we are looking for a field, see if we
have access to that field. Lookup_field will give us the
error message. */
- t = lookup_field (basetypes, name, 1, 0);
+ t = lookup_field (basebinfo, name, 1, 0);
if (t == error_mark_node)
return error_mark_node;
@@ -2802,7 +2776,12 @@ build_new (placement, decl, init, use_global_new)
}
if (has_array)
- code = VEC_NEW_EXPR;
+ {
+ code = VEC_NEW_EXPR;
+
+ if (init && pedantic)
+ cp_pedwarn ("initialization in array new");
+ }
/* Allocate the object. */
if (! use_global_new && TYPE_LANG_SPECIFIC (true_type)
@@ -2930,8 +2909,8 @@ build_new (placement, decl, init, use_global_new)
if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE)
newrval = build_indirect_ref (newrval, NULL_PTR);
- newrval = build_method_call (newrval, constructor_name_full (true_type),
- init, NULL_TREE, flags);
+ newrval = build_method_call (newrval, ctor_identifier,
+ init, TYPE_BINFO (true_type), flags);
if (newrval)
{
@@ -3272,6 +3251,9 @@ expand_vec_init (decl, base, maxindex, init, from_array)
expand_assignment (rval, base, 0, 0);
base = get_temp_regvar (build_pointer_type (type), base);
+ if (init != NULL_TREE && TREE_CODE (init) == TREE_LIST)
+ init = build_compound_expr (init);
+
if (init != NULL_TREE
&& TREE_CODE (init) == CONSTRUCTOR
&& TREE_TYPE (init) == TREE_TYPE (decl))
@@ -3387,7 +3369,18 @@ expand_vec_init (decl, base, maxindex, init, from_array)
array_type_nelts (type), 0, 0);
}
else
- expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0, 0);
+ {
+ tree targ = build1 (INDIRECT_REF, type, base);
+ tree rhs;
+
+ if (init)
+ rhs = convert_for_initialization (targ, type, init, LOOKUP_NORMAL,
+ "initialization", NULL_TREE, 0);
+ else
+ rhs = NULL_TREE;
+
+ expand_aggr_init (targ, rhs, 0, 0);
+ }
expand_assignment (base,
build (PLUS_EXPR, build_pointer_type (type), base, size),
@@ -3578,7 +3571,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
of the base classes; otherwise, we must do that here. */
if (TYPE_HAS_DESTRUCTOR (type))
{
- tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0));
+ tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
tree basetypes = TYPE_BINFO (type);
tree passed_auto_delete;
tree do_delete = NULL_TREE;
@@ -3631,7 +3624,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
complete right way to do this. this offsets may not be right
in the below. (mrs) */
/* This destructor must be called via virtual function table. */
- dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 0);
+ dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 1);
basetype = DECL_CLASS_CONTEXT (dtor);
binfo = get_binfo (basetype,
TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))),
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index a1a335525a6..a1b841bf467 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -837,6 +837,11 @@ yyprint (file, yychar, yylval)
case SCSPEC:
case PRE_PARSED_CLASS_DECL:
t = yylval.ttype;
+ if (TREE_CODE (t) == TYPE_DECL)
+ {
+ fprintf (file, " `%s'", DECL_NAME (t));
+ break;
+ }
my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
@@ -1076,7 +1081,7 @@ set_typedecl_interface_info (prev, vars)
= interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
}
-void
+int
set_vardecl_interface_info (prev, vars)
tree prev, vars;
{
@@ -1090,7 +1095,9 @@ set_vardecl_interface_info (prev, vars)
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1;
+ return 1;
}
+ return 0;
}
/* Called from the top level: if there are any pending inlines to
@@ -1683,6 +1690,7 @@ cons_up_default_function (type, full_name, kind)
}
#endif
+#if 0
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
DECL_INTERFACE_KNOWN (fn) = 1;
@@ -1690,6 +1698,7 @@ cons_up_default_function (type, full_name, kind)
&& flag_implement_inlines);
}
else
+#endif
DECL_NOT_REALLY_EXTERN (fn) = 1;
mark_inline_for_output (fn);
@@ -1986,7 +1995,7 @@ check_newline ()
goto skipline;
}
main_filename = TREE_STRING_POINTER (yylval.ttype);
- c = getch();
+ c = getch ();
put_back (c);
}
@@ -2063,7 +2072,7 @@ check_newline ()
goto skipline;
}
main_filename = TREE_STRING_POINTER (yylval.ttype);
- c = getch();
+ c = getch ();
put_back (c);
}
@@ -2683,7 +2692,7 @@ see_typename ()
{
looking_for_typename = 1;
if (yychar < 0)
- if ((yychar = yylex()) < 0) yychar = 0;
+ if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0;
if (yychar == IDENTIFIER)
{
@@ -2742,7 +2751,7 @@ do_identifier (token, parsing)
/* Remember that this name has been used in the class definition, as per
[class.scope0] */
- if (id && current_class_type
+ if (id && current_class_type && parsing
&& TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE (token))
pushdecl_class_level (id);
@@ -3238,6 +3247,14 @@ real_yylex ()
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;
}
@@ -4037,7 +4054,7 @@ real_yylex ()
skipnewline:
c = getch ();
if (c == EOF) {
- error("Unterminated string");
+ error ("Unterminated string");
break;
}
}
@@ -4383,7 +4400,7 @@ build_lang_decl (code, name, type)
#endif
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
+ tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
return t;
@@ -4480,7 +4497,7 @@ make_lang_type (code)
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1;
- tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
return t;
@@ -4509,7 +4526,7 @@ copy_decl_lang_specific (decl)
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
+ tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
}
@@ -4549,32 +4566,6 @@ compiler_error (s, v, v2)
sprintf (buf, s, v, v2);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
-
-void
-compiler_error_with_decl (decl, s)
- tree decl;
- char *s;
-{
- char *name;
- count_error (0);
-
- report_error_function (0);
-
- if (TREE_CODE (decl) == PARM_DECL)
- fprintf (stderr, "%s:%d: ",
- DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
- DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
- else
- fprintf (stderr, "%s:%d: ",
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
-
- name = lang_printable_name (decl);
- if (name)
- fprintf (stderr, s, name);
- else
- fprintf (stderr, s, "((anonymous))");
- fprintf (stderr, " (compiler error)\n");
-}
void
yyerror (string)
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index f5f3bbe4e1d..c8732072d0a 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -91,10 +91,12 @@ do_inline_function_hair (type, friend_list)
if (method && TREE_CODE (method) == TREE_VEC)
{
- if (TREE_VEC_ELT (method, 0))
+ if (TREE_VEC_ELT (method, 1))
+ method = TREE_VEC_ELT (method, 1);
+ else if (TREE_VEC_ELT (method, 0))
method = TREE_VEC_ELT (method, 0);
else
- method = TREE_VEC_ELT (method, 1);
+ method = TREE_VEC_ELT (method, 2);
}
while (method)
@@ -1277,9 +1279,26 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
build_tree_list (NULL_TREE, xarg1),
flags & LOOKUP_COMPLAIN,
(struct candidate *)0);
+ arg1 = TREE_TYPE (xarg1);
+
+ /* This handles the case where we're trying to delete
+ X (*a)[10];
+ a=new X[5][10];
+ delete[] a; */
+
+ if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
+ {
+ /* Strip off the pointer and the array. */
+ arg1 = TREE_TYPE (TREE_TYPE (arg1));
+
+ while (TREE_CODE (arg1) == ARRAY_TYPE)
+ arg1 = (TREE_TYPE (arg1));
+
+ arg1 = build_pointer_type (arg1);
+ }
rval = build_method_call
- (build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1),
+ (build_indirect_ref (build1 (NOP_EXPR, arg1,
error_mark_node),
NULL_PTR),
fnname, tree_cons (NULL_TREE, xarg1,
@@ -1826,7 +1845,7 @@ make_thunk (function, delta)
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
if (thunk && TREE_CODE (thunk) != THUNK_DECL)
{
- error_with_decl ("implementation-reserved name `%s' used");
+ cp_error ("implementation-reserved name `%D' used", thunk_id);
IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
}
if (thunk == NULL_TREE)
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 5c7b53c7112..d2b6f95e202 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -499,10 +499,10 @@ datadef:
| typed_declspecs declarator ';'
{ tree d, specs, attrs;
split_specs_attrs ($1, &specs, &attrs);
+ note_list_got_semicolon (specs);
d = start_decl ($<ttype>2, specs, 0, NULL_TREE);
cplus_decl_attributes (d, NULL_TREE, attrs);
cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
- note_list_got_semicolon ($<ttype>$);
}
| declmods ';'
{ pedwarn ("empty declaration"); }
@@ -1990,7 +1990,9 @@ pending_inlines:
| pending_inlines fn.defpen maybe_return_init ctor_initializer_opt
compstmt_or_error
{
- finish_function (lineno, (int)$4, 0);
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
+ finish_function (lineno, (int)$4, nested);
process_next_inline ($2);
}
| pending_inlines fn.defpen maybe_return_init function_try_block
@@ -2108,7 +2110,19 @@ named_class_head_sans_basetype_defn:
named_complex_class_head_sans_basetype:
aggr nested_name_specifier identifier
- { current_aggr = $$; $$ = $3; }
+ {
+ current_aggr = $1;
+ if (TREE_CODE ($3) == TYPE_DECL)
+ $$ = $3;
+ else
+ {
+ cp_error ("`%T' does not have a nested type named `%D'",
+ $2, $3);
+ $$ = xref_tag
+ (current_aggr, make_anon_name (), NULL_TREE, 1);
+ $$ = TYPE_MAIN_DECL ($$);
+ }
+ }
| aggr template_type
{ current_aggr = $$; $$ = $2; }
| aggr nested_name_specifier template_type
@@ -3519,8 +3533,10 @@ function_try_block:
expand_start_all_catch (); }
handler_seq
{
+ int nested = (hack_decl_function_context
+ (current_function_decl) != NULL_TREE);
expand_end_all_catch ();
- finish_function (lineno, (int)$3, 0);
+ finish_function (lineno, (int)$3, nested);
}
;
@@ -3820,6 +3836,9 @@ bad_parm:
| notype_declarator
{
error ("type specifier omitted for parameter");
+ if (TREE_CODE ($$) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM)
+ cp_error (" perhaps you want `typename %E' to make it a type", $$);
$$ = build_tree_list (integer_type_node, $$);
}
;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 54efe9f7f20..0ecc40018b0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1,6 +1,7 @@
/* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
+ Rewritten by Jason Merrill (jason@cygnus.com).
This file is part of GNU CC.
@@ -233,6 +234,9 @@ push_template_decl (decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
+ else if (! DECL_TEMPLATE_INFO (decl))
+ /* A member definition that doesn't match anything in the class. */
+ return;
else
tmpl = DECL_TI_TEMPLATE (decl);
}
@@ -475,12 +479,10 @@ mangle_class_name_for_template (name, parms, arglist)
int i, nparms;
if (!scratch_firstobj)
- {
- gcc_obstack_init (&scratch_obstack);
- scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
- }
+ gcc_obstack_init (&scratch_obstack);
else
obstack_free (&scratch_obstack, scratch_firstobj);
+ scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
#if 0
#define buflen sizeof(buf)
@@ -629,12 +631,6 @@ lookup_template_class (d1, arglist, in_decl)
return error_mark_node;
}
- if (TREE_CODE (TREE_TYPE (template)) == RECORD_TYPE)
- code_type_node = (CLASSTYPE_DECLARED_CLASS (TREE_TYPE (template))
- ? class_type_node : record_type_node);
- else
- code_type_node = union_type_node;
-
if (PRIMARY_TEMPLATE_P (template))
{
parmlist = DECL_TEMPLATE_PARMS (template);
@@ -675,7 +671,7 @@ lookup_template_class (d1, arglist, in_decl)
IDENTIFIER_TEMPLATE (id) = d1;
maybe_push_to_top_level (uses_template_parms (arglist));
- t = xref_tag (code_type_node, id, NULL_TREE, 1);
+ t = xref_tag_from_type (TREE_TYPE (template), id, 1);
pop_from_top_level ();
}
else
@@ -689,7 +685,7 @@ lookup_template_class (d1, arglist, in_decl)
{
tree save_parms = current_template_parms;
current_template_parms = NULL_TREE;
- t = xref_tag (code_type_node, id, NULL_TREE, 0);
+ t = xref_tag_from_type (TREE_TYPE (template), id, 0);
current_template_parms = save_parms;
}
else
@@ -978,7 +974,7 @@ tree
instantiate_class_template (type)
tree type;
{
- tree template, template_info, args, pattern, t, *field_chain, *tag_chain;
+ tree template, template_info, args, pattern, t, *field_chain;
if (type == error_mark_node)
return error_mark_node;
@@ -1060,7 +1056,6 @@ instantiate_class_template (type)
CLASSTYPE_LOCAL_TYPEDECLS (type) = CLASSTYPE_LOCAL_TYPEDECLS (pattern);
field_chain = &TYPE_FIELDS (type);
- tag_chain = &CLASSTYPE_TAGS (type);
for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t))
{
@@ -1068,15 +1063,13 @@ instantiate_class_template (type)
tree tag = TREE_VALUE (t);
tree newtag;
+ /* These will add themselves to CLASSTYPE_TAGS for the new type. */
if (TREE_CODE (tag) == ENUMERAL_TYPE)
newtag = start_enum (name);
else
newtag = tsubst (tag, &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
- *tag_chain = build_tree_list (name, newtag);
- tag_chain = &TREE_CHAIN (*tag_chain);
-
if (TREE_CODE (tag) == ENUMERAL_TYPE)
{
tree e, values = NULL_TREE, *last = &values;
@@ -1124,16 +1117,30 @@ instantiate_class_template (type)
TYPE_METHODS (type) = tsubst_chain (TYPE_METHODS (pattern), args);
DECL_FRIENDLIST (TYPE_MAIN_DECL (type))
- = tsubst_chain (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)), args);
- CLASSTYPE_FRIEND_CLASSES (type)
- = tsubst_chain (CLASSTYPE_FRIEND_CLASSES (pattern), args);
+ = tsubst (DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)),
+ &TREE_VEC_ELT (args, 0), TREE_VEC_LENGTH (args), NULL_TREE);
{
- tree d = tsubst (DECL_TEMPLATE_INJECT (template), &TREE_VEC_ELT (args, 0),
+ tree d = CLASSTYPE_FRIEND_CLASSES (type) =
+ tsubst (CLASSTYPE_FRIEND_CLASSES (pattern), &TREE_VEC_ELT (args, 0),
+ TREE_VEC_LENGTH (args), NULL_TREE);
+
+ /* This does injection for friend classes. */
+ for (; d; d = TREE_CHAIN (d))
+ TREE_VALUE (d) = xref_tag_from_type (TREE_VALUE (d), NULL_TREE, 1);
+
+ d = tsubst (DECL_TEMPLATE_INJECT (template), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), NULL_TREE);
for (; d; d = TREE_CHAIN (d))
- pushdecl (TREE_VALUE (d));
+ {
+ tree t = TREE_VALUE (d);
+
+ if (TREE_CODE (t) == TYPE_DECL)
+ /* Already injected. */;
+ else
+ pushdecl (t);
+ }
}
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
@@ -1781,6 +1788,11 @@ tsubst (t, args, nargs, in_decl)
(CALL_EXPR, tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl), 0);
+ case SCOPE_REF:
+ return build_parse_node
+ (TREE_CODE (t), tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
+ tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl));
+
default:
sorry ("use of `%s' in template",
tree_code_name [(int) TREE_CODE (t)]);
@@ -1866,6 +1878,7 @@ tsubst_copy (t, args, nargs, in_decl)
case CONVERT_EXPR: /* Unary + */
case SIZEOF_EXPR:
case ARROW_EXPR:
+ case THROW_EXPR:
return build1
(code, NULL_TREE,
tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
@@ -1928,7 +1941,7 @@ tsubst_copy (t, args, nargs, in_decl)
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
- name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, TYPE_MAIN_VARIANT (name));
}
else if (TREE_CODE (name) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
@@ -1936,7 +1949,7 @@ tsubst_copy (t, args, nargs, in_decl)
tree base = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
name = TREE_OPERAND (name, 1);
name = tsubst_copy (TREE_OPERAND (name, 0), args, nargs, in_decl);
- name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, TYPE_MAIN_VARIANT (name));
name = build_nt (SCOPE_REF, base, name);
}
else
@@ -2915,7 +2928,7 @@ instantiate_decl (d)
warn_if_unknown_interface (pattern);
}
- if (at_eof)
+ if (at_eof && ! DECL_INLINE (d))
import_export_decl (d);
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index bd46eb79c25..588d8231f09 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -146,7 +146,7 @@ static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
static int n_calls_get_base_type;
static int n_outer_fields_searched;
static int n_contexts_saved;
-#endif
+#endif /* GATHER_STATISTICS */
/* Local variables to help save memoization contexts. */
static tree prev_type_memoized;
@@ -323,7 +323,7 @@ push_memoized_context (type, use_old)
{
#ifdef GATHER_STATISTICS
n_contexts_saved++;
-#endif
+#endif /* GATHER_STATISTICS */
type_stack = prev_type_stack;
prev_type_stack = 0;
@@ -694,12 +694,12 @@ lookup_field_1 (type, name)
#ifdef GATHER_STATISTICS
n_calls_lookup_field_1++;
-#endif
+#endif /* GATHER_STATISTICS */
while (field)
{
#ifdef GATHER_STATISTICS
n_fields_searched++;
-#endif
+#endif /* GATHER_STATISTICS */
if (DECL_NAME (field) == NULL_TREE
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
{
@@ -724,8 +724,6 @@ lookup_field_1 (type, name)
if (TYPE_VIRTUAL_P (type))
return CLASSTYPE_VFIELD (type);
}
- if (name == constructor_name (type))
- return TYPE_STUB_DECL (type);
return NULL_TREE;
}
@@ -845,10 +843,10 @@ compute_access (basetype_path, field)
/* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT
slot set to the union type rather than the record type containing
- the anonymous union. In this case, DECL_FIELD_CONTEXT is correct. */
+ the anonymous union. */
if (context && TREE_CODE (context) == UNION_TYPE
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
- context = DECL_FIELD_CONTEXT (field);
+ context = TYPE_CONTEXT (context);
/* Virtual function tables are never private. But we should know that
we are looking for this, and not even try to hide it. */
@@ -1020,7 +1018,8 @@ lookup_fnfields_here (type, name)
int index = lookup_fnfields_1 (type, name);
tree fndecls;
- if (index <= 0)
+ /* ctors and dtors are always only in the right class. */
+ if (index <= 1)
return index;
fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
while (fndecls)
@@ -1074,10 +1073,14 @@ lookup_field (xbasetype, name, protect, want_type)
accurate error messages for access control. */
int index = MEMOIZED_HASH_FN (name);
+#if 0
+ /* We cannot search for constructor/destructor names like this. */
+ /* This can't go here, but where should it go? */
/* If we are looking for a constructor in a templated type, use the
unspecialized name, as that is how we store it. */
if (IDENTIFIER_TEMPLATE (name))
name = constructor_name (name);
+#endif
if (TREE_CODE (xbasetype) == TREE_VEC)
{
@@ -1121,7 +1124,7 @@ lookup_field (xbasetype, name, protect, want_type)
#ifdef GATHER_STATISTICS
n_calls_lookup_field++;
-#endif
+#endif /* GATHER_STATISTICS */
if (protect && flag_memoize_lookups && ! global_bindings_p ())
entry = make_memoized_table_entry (type, name, 0);
else
@@ -1137,10 +1140,7 @@ lookup_field (xbasetype, name, protect, want_type)
{
if (TREE_CODE (rval) != TYPE_DECL)
{
- if (name == constructor_name (type))
- rval = type;
- else
- rval = purpose_member (name, CLASSTYPE_TAGS (type));
+ rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (rval)
rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
}
@@ -1322,10 +1322,7 @@ lookup_field (xbasetype, name, protect, want_type)
{
if (TREE_CODE (rval) != TYPE_DECL)
{
- if (name == constructor_name (type))
- rval = type;
- else
- rval = purpose_member (name, CLASSTYPE_TAGS (type));
+ rval = purpose_member (name, CLASSTYPE_TAGS (type));
if (rval)
rval = TYPE_MAIN_DECL (TREE_VALUE (rval));
}
@@ -1468,10 +1465,8 @@ lookup_nested_field (name, complain)
enums in nested classes) when we do need to call
this fn at parse time. So, in those cases, we pass
complain as a 0 and just return a NULL_TREE. */
- error ("assignment to non-static member `%s' of enclosing class `%s'",
- lang_printable_name (id),
- IDENTIFIER_POINTER (TYPE_IDENTIFIER
- (DECL_CONTEXT (t))));
+ cp_error ("assignment to non-static member `%D' of enclosing class `%T'",
+ id, DECL_CONTEXT (t));
/* Mark this for do_identifier(). It would otherwise
claim that the variable was undeclared. */
TREE_TYPE (id) = error_mark_node;
@@ -1505,15 +1500,21 @@ lookup_fnfields_1 (type, name)
#ifdef GATHER_STATISTICS
n_calls_lookup_fnfields_1++;
-#endif
- if (*methods && name == constructor_name (type))
+#endif /* GATHER_STATISTICS */
+
+ /* Constructors are first... */
+ if (*methods && name == ctor_identifier)
return 0;
+ /* and destructors are second. */
+ if (*++methods && name == dtor_identifier)
+ return 1;
+
while (++methods != end)
{
#ifdef GATHER_STATISTICS
n_outer_fields_searched++;
-#endif
+#endif /* GATHER_STATISTICS */
if (DECL_NAME (*methods) == name)
break;
}
@@ -1581,10 +1582,14 @@ lookup_fnfields (basetype_path, name, complain)
protect = complain = 0;
}
+#if 0
+ /* We cannot search for constructor/destructor names like this. */
+ /* This can't go here, but where should it go? */
/* If we are looking for a constructor in a templated type, use the
unspecialized name, as that is how we store it. */
if (IDENTIFIER_TEMPLATE (name))
name = constructor_name (name);
+#endif
binfo = basetype_path;
binfo_h = binfo;
@@ -1644,7 +1649,7 @@ lookup_fnfields (basetype_path, name, complain)
#ifdef GATHER_STATISTICS
n_calls_lookup_fnfields++;
-#endif
+#endif /* GATHER_STATISTICS */
if (protect && flag_memoize_lookups && ! global_bindings_p ())
entry = make_memoized_table_entry (type, name, 1);
else
@@ -1674,6 +1679,16 @@ lookup_fnfields (basetype_path, name, complain)
}
rval = NULL_TREE;
+ if (name == ctor_identifier || name == dtor_identifier)
+ {
+ /* Don't allow lookups of constructors and destructors to go
+ deeper than the first place we look. */
+ if (entry)
+ TREE_TYPE (entry) = TREE_VALUE (entry) = NULL_TREE;
+
+ return NULL_TREE;
+ }
+
if (basetype_path == TYPE_BINFO (type))
{
basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
@@ -1930,7 +1945,8 @@ get_virtuals_named_this (binfo)
return NULL_TREE;
}
-static tree get_virtual_destructor (binfo, i)
+static tree
+get_virtual_destructor (binfo, i)
tree binfo;
int i;
{
@@ -1938,8 +1954,8 @@ static tree get_virtual_destructor (binfo, i)
if (i >= 0)
type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
if (TYPE_HAS_DESTRUCTOR (type)
- && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)))
- return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
+ && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1)))
+ return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1);
return 0;
}
@@ -2336,7 +2352,7 @@ dfs_walk (binfo, fn, qfn)
/* No need for the conversion here, as we know it is the
right type. */
vbase_decl_ptr_intermediate
- = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
+ = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
}
else
{
@@ -2477,10 +2493,12 @@ dfs_debug_mark (binfo)
if (current_function_decl == NULL_TREE
|| DECL_CLASS_CONTEXT (current_function_decl) != t)
{
- if (TREE_VEC_ELT (methods, 0))
+ if (TREE_VEC_ELT (methods, 1))
+ methods = TREE_VEC_ELT (methods, 1);
+ else if (TREE_VEC_ELT (methods, 0))
methods = TREE_VEC_ELT (methods, 0);
else
- methods = TREE_VEC_ELT (methods, 1);
+ methods = TREE_VEC_ELT (methods, 2);
while (methods)
{
if (DECL_VINDEX (methods)
@@ -2523,8 +2541,8 @@ dfs_find_vbases (binfo)
tree binfo = binfo_member (vbase, vbase_types);
CLASSTYPE_SEARCH_SLOT (vbase)
- = (char *) build (PLUS_EXPR, build_pointer_type (vbase),
- vbase_decl_ptr, BINFO_OFFSET (binfo));
+ = build (PLUS_EXPR, build_pointer_type (vbase),
+ vbase_decl_ptr, BINFO_OFFSET (binfo));
}
}
SET_BINFO_VTABLE_PATH_MARKED (binfo);
@@ -2563,7 +2581,7 @@ dfs_init_vbase_pointers (binfo)
{
tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
- tree init = (tree)CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
+ tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
vbase_types),
build_modify_expr (ref, NOP_EXPR, init),
@@ -2682,7 +2700,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
delta = purpose_member (vbase, *vbase_offsets);
if (! delta)
{
- delta = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbase));
+ delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbase));
delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr);
delta = save_expr (delta);
delta = tree_cons (vbase, delta, *vbase_offsets);
@@ -2751,7 +2769,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
if (! vc_delta)
{
tree vc_addr = convert_pointer_to_real (vc, orig_addr);
- vc_delta = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vc));
+ vc_delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vc));
vc_delta = build (MINUS_EXPR, ptrdiff_type_node,
vc_delta, vc_addr);
vc_delta = save_expr (vc_delta);
@@ -3207,10 +3225,10 @@ dfs_pushdecls (binfo)
}
method_vec = CLASSTYPE_METHOD_VEC (type);
- if (method_vec != 0)
+ if (method_vec)
{
/* Farm out constructors and destructors. */
- methods = &TREE_VEC_ELT (method_vec, 1);
+ methods = &TREE_VEC_ELT (method_vec, 2);
end = TREE_VEC_END (method_vec);
while (methods != end)
@@ -3257,7 +3275,7 @@ dfs_compress_decls (binfo)
if (method_vec != 0)
{
/* Farm out constructors and destructors. */
- tree *methods = &TREE_VEC_ELT (method_vec, 1);
+ tree *methods = &TREE_VEC_ELT (method_vec, 2);
tree *end = TREE_VEC_END (method_vec);
for (; methods != end; methods++)
@@ -3404,9 +3422,9 @@ print_search_statistics ()
fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
n_outer_fields_searched, n_calls_lookup_fnfields);
fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
-#else
+#else /* GATHER_STATISTICS */
fprintf (stderr, "no search statistics\n");
-#endif
+#endif /* GATHER_STATISTICS */
}
void
@@ -3441,7 +3459,7 @@ reinit_search_statistics ()
n_calls_get_base_type = 0;
n_outer_fields_searched = 0;
n_contexts_saved = 0;
-#endif
+#endif /* GATHER_STATISTICS */
}
static tree conversions;
@@ -3450,11 +3468,11 @@ add_conversions (binfo)
tree binfo;
{
int i;
- tree vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+ tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
- for (i = 1; i < TREE_VEC_LENGTH (vec); ++i)
+ for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
{
- tree tmp = TREE_VEC_ELT (vec, i);
+ tree tmp = TREE_VEC_ELT (method_vec, i);
if (! IDENTIFIER_TYPENAME_P (DECL_NAME (tmp)))
break;
conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)),
diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c
index 6564cab2e63..ace8c8f56c4 100644
--- a/gcc/cp/spew.c
+++ b/gcc/cp/spew.c
@@ -71,7 +71,7 @@ static int debug_yychar ();
void
init_spew ()
{
- gcc_obstack_init(&token_obstack);
+ gcc_obstack_init (&token_obstack);
}
#ifdef SPEW_DEBUG
@@ -81,7 +81,7 @@ init_spew ()
static int
num_tokens ()
{
- return (obstack_object_size(&token_obstack)/sizeof(struct token))
+ return (obstack_object_size (&token_obstack) / sizeof (struct token))
- first_token;
}
@@ -92,8 +92,8 @@ nth_token (n)
{
/* could just have this do slurp_ implicitly, but this way is easier
* to debug... */
- my_friendly_assert (n < num_tokens(), 298);
- return ((struct token*)obstack_base(&token_obstack))+n+first_token;
+ my_friendly_assert (n < num_tokens (), 298);
+ return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
}
/* Add a token to the token fifo. */
@@ -101,16 +101,16 @@ static void
add_token (t)
struct token* t;
{
- obstack_grow(&token_obstack,t,sizeof (struct token));
+ obstack_grow (&token_obstack, t, sizeof (struct token));
}
/* Consume the next token out of the fifo. */
static void
-consume_token()
+consume_token ()
{
- if (num_tokens() == 1)
+ if (num_tokens () == 1)
{
- obstack_free(&token_obstack, obstack_base (&token_obstack));
+ obstack_free (&token_obstack, obstack_base (&token_obstack));
first_token = 0;
}
else
@@ -121,15 +121,15 @@ consume_token()
/* ...otherwise use macros. */
#define num_tokens() \
- ((obstack_object_size(&token_obstack)/sizeof(struct token)) - first_token)
+ ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token)
#define nth_token(N) \
- (((struct token*)obstack_base(&token_obstack))+(N)+first_token)
+ (((struct token*)obstack_base (&token_obstack))+(N)+first_token)
-#define add_token(T) obstack_grow(&token_obstack, (T), sizeof (struct token))
+#define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token))
#define consume_token() \
- (num_tokens() == 1 \
+ (num_tokens () == 1 \
? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
(first_token = 0)) \
: first_token++)
@@ -158,11 +158,11 @@ scan_tokens (n)
goto pad_tokens;
}
- while (num_tokens() <= n)
+ while (num_tokens () <= n)
{
- obstack_blank(&token_obstack,sizeof (struct token));
+ obstack_blank (&token_obstack, sizeof (struct token));
tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
- tmp->yychar = real_yylex();
+ tmp->yychar = real_yylex ();
tmp->end_of_file = end_of_file;
tmp->yylval = yylval;
end_of_file = 0;
@@ -173,7 +173,7 @@ scan_tokens (n)
pad_tokens:
while (num_tokens () <= n)
{
- obstack_blank(&token_obstack,sizeof (struct token));
+ obstack_blank (&token_obstack, sizeof (struct token));
tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
tmp->yychar = EMPTY;
tmp->end_of_file = 0;
@@ -216,14 +216,14 @@ tree got_scope;
tree got_object;
int
-peekyylex()
+peekyylex ()
{
scan_tokens (0);
return nth_token (0)->yychar;
}
int
-yylex()
+yylex ()
{
struct token tmp_token;
tree trrr;
@@ -233,14 +233,14 @@ yylex()
if (spew_debug)
{
yylex_ctr ++;
- fprintf(stderr, "\t\t## %d ##",yylex_ctr);
+ fprintf (stderr, "\t\t## %d ##", yylex_ctr);
}
#endif
/* if we've got tokens, send them */
- if (num_tokens())
+ if (num_tokens ())
{
- tmp_token= *nth_token(0);
+ tmp_token= *nth_token (0);
/* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
If we don't find it in CURRENT_OBSTACK's current or immediately
@@ -258,13 +258,13 @@ yylex()
tmp_token.yychar = real_yylex ();
tmp_token.yylval = yylval;
tmp_token.end_of_file = end_of_file;
- add_token(&tmp_token);
+ add_token (&tmp_token);
}
/* many tokens just need to be returned. At first glance, all we
* have to do is send them back up, but some of them are needed to
* figure out local context. */
- switch(tmp_token.yychar)
+ switch (tmp_token.yychar)
{
case EMPTY:
/* This is a lexical no-op. */
@@ -341,7 +341,7 @@ yylex()
break;
case AGGR:
- *nth_token(0) = tmp_token;
+ *nth_token (0) = tmp_token;
do_aggr ();
/* fall through to output... */
case ENUM:
@@ -349,7 +349,7 @@ yylex()
looking_for_typename = 1;
/* fall through... */
default:
- consume_token();
+ consume_token ();
}
got_object = NULL_TREE;
@@ -358,7 +358,7 @@ yylex()
end_of_file = tmp_token.end_of_file;
#ifdef SPEW_DEBUG
if (spew_debug)
- debug_yychar(yychar);
+ debug_yychar (yychar);
#endif
return yychar;
}
@@ -423,7 +423,7 @@ debug_yychar (yy)
int i;
- if(yy<256) {
+ if (yy<256) {
fprintf (stderr, "<%d: %c >\n", yy, yy);
return 0;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index fb484e2a690..5c8fc1ce36b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -800,9 +800,9 @@ layout_basetypes (rec, binfos)
vbase_decls = decl;
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
- && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
+ && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
- warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
+ warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s: virtual %s'",
TYPE_NAME_STRING (rec),
@@ -827,9 +827,9 @@ layout_basetypes (rec, binfos)
claim it as theirs and explain exactly what circumstances
warrant the warning. */
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
- && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
+ && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
- warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
+ warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s:%s %s'",
TYPE_NAME_STRING (rec),
@@ -1950,7 +1950,8 @@ min_tree_cons (purpose, value, chain)
register struct obstack *ambient_obstack = current_obstack;
current_obstack = &permanent_obstack;
- node = tree_cons (purpose, value, chain);
+ node = tree_cons (copy_to_permanent (purpose),
+ copy_to_permanent (value), chain);
current_obstack = ambient_obstack;
return node;
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 16f7228bf88..44e05b848b1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1767,6 +1767,12 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = TREE_TYPE (datum);
code = TREE_CODE (basetype);
}
+ if (TREE_CODE (datum) == OFFSET_REF)
+ {
+ datum = resolve_offset_ref (datum);
+ basetype = TREE_TYPE (datum);
+ code = TREE_CODE (basetype);
+ }
/* First, see if there is a field or component with name COMPONENT. */
if (TREE_CODE (component) == TREE_LIST)
@@ -1803,7 +1809,7 @@ build_component_ref (datum, component, basetype_path, protect)
cp_error ("type `%T' has no destructor", basetype);
return error_mark_node;
}
- return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
+ return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1);
}
/* Look up component name in the structure type definition. */
@@ -1905,7 +1911,8 @@ build_component_ref (datum, component, basetype_path, protect)
{
tree context = DECL_FIELD_CONTEXT (field);
tree base = context;
- while (base != basetype && ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
+ while (base != basetype && TYPE_NAME (base)
+ && ANON_AGGRNAME_P (TYPE_IDENTIFIER (base)))
{
base = TYPE_CONTEXT (base);
}
@@ -1935,7 +1942,7 @@ build_component_ref (datum, component, basetype_path, protect)
basetype = base;
/* Handle things from anon unions here... */
- if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
+ if (TYPE_NAME (context) && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
{
tree subfield = lookup_anon_field (basetype, context);
tree subdatum = build_component_ref (datum, subfield,
@@ -2231,6 +2238,23 @@ build_x_function_call (function, params, decl)
return build_min_nt (CALL_EXPR, function, params, 0);
type = TREE_TYPE (function);
+
+ if (TREE_CODE (type) == OFFSET_TYPE
+ && TREE_TYPE (type) == unknown_type_node
+ && TREE_CODE (function) == TREE_LIST
+ && TREE_CHAIN (function) == NULL_TREE)
+ {
+ /* Undo (Foo:bar)()... */
+ type = TYPE_OFFSET_BASETYPE (type);
+ function = TREE_VALUE (function);
+ my_friendly_assert (TREE_CODE (function) == TREE_LIST, 999);
+ my_friendly_assert (TREE_CHAIN (function) == NULL_TREE, 999);
+ function = TREE_VALUE (function);
+ my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999);
+ function = DECL_NAME (function);
+ return build_method_call (decl, function, params, TYPE_BINFO (type), LOOKUP_NORMAL);
+ }
+
is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE
&& IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) == function)
@@ -2238,6 +2262,11 @@ build_x_function_call (function, params, decl)
|| TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEMFUNC_P (type));
+ if (TREE_CODE (function) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (function))
+ return build_member_call
+ (DECL_CONTEXT (function), DECL_NAME (function), params);
+
/* Handle methods, friends, and overloaded functions, respectively. */
if (is_method)
{
@@ -2712,9 +2741,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
{
if (fndecl)
{
- char *buf = (char *)alloca (40 + strlen (called_thing));
- sprintf (buf, "too many arguments to %s `%%s'", called_thing);
- error_with_decl (fndecl, buf);
+ cp_error_at ("too many arguments to %s `%+D'", called_thing,
+ fndecl);
error ("at this point in file");
}
else
@@ -4877,30 +4905,42 @@ build_conditional_expr (ifexp, op1, op2)
cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2);
return error_mark_node;
}
+ /* Warning: this code assumes that conversion between cv-variants of
+ a type is done using NOP_EXPRs. */
if (code1 == RECORD_TYPE && TYPE_HAS_CONVERSION (type1))
{
- tree tmp = build_type_conversion (CONVERT_EXPR, type2, op1, 0);
+ tree tmp = build_pointer_type
+ (build_type_variant (TREE_TYPE (type2), 1, 1));
+ tmp = build_type_conversion (CONVERT_EXPR, tmp, op1, 0);
if (tmp == NULL_TREE)
{
- cp_error ("aggregate type `%T' could not convert on lhs of `:'", type1);
+ cp_error ("incompatible types `%T' and `%T' in `?:'",
+ type1, type2);
return error_mark_node;
}
if (tmp == error_mark_node)
error ("ambiguous pointer conversion");
- result_type = type2;
+ else
+ STRIP_NOPS (tmp);
+ result_type = common_type (type1, TREE_TYPE (tmp));
op1 = tmp;
}
else if (code2 == RECORD_TYPE && TYPE_HAS_CONVERSION (type2))
{
- tree tmp = build_type_conversion (CONVERT_EXPR, type1, op2, 0);
+ tree tmp = build_pointer_type
+ (build_type_variant (TREE_TYPE (type1), 1, 1));
+ tmp = build_type_conversion (CONVERT_EXPR, tmp, op2, 0);
if (tmp == NULL_TREE)
{
- cp_error ("aggregate type `%T' could not convert on rhs of `:'", type2);
+ cp_error ("incompatible types `%T' and `%T' in `?:'",
+ type1, type2);
return error_mark_node;
}
if (tmp == error_mark_node)
error ("ambiguous pointer conversion");
- result_type = type1;
+ else
+ STRIP_NOPS (tmp);
+ result_type = common_type (type1, TREE_TYPE (tmp));
op2 = tmp;
}
else if (flag_cond_mismatch)
@@ -5183,12 +5223,6 @@ build_c_cast (type, expr, allow_nonconverting)
return error_mark_node;
}
- /* If there's only one function in the overloaded space,
- just take it. */
- if (TREE_CODE (value) == TREE_LIST
- && TREE_CHAIN (value) == NULL_TREE)
- value = TREE_VALUE (value);
-
if (current_template_parms)
{
tree t = build_min (CAST_EXPR, type,
@@ -5471,9 +5505,9 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */;
else
{
- result = build_method_call (lhs, constructor_name_full (lhstype),
+ result = build_method_call (lhs, ctor_identifier,
build_tree_list (NULL_TREE, rhs),
- NULL_TREE, LOOKUP_NORMAL);
+ TYPE_BINFO (lhstype), LOOKUP_NORMAL);
if (result == NULL_TREE)
return error_mark_node;
return result;
@@ -6688,7 +6722,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
{
if (TYPE_HAS_INIT_REF (type))
{
- tree init = build_method_call (exp, constructor_name_full (type),
+ tree init = build_method_call (exp, ctor_identifier,
build_tree_list (NULL_TREE, rhs),
TYPE_BINFO (type), LOOKUP_NORMAL);
@@ -6721,7 +6755,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return rhs;
}
- return cp_convert (type, rhs, CONV_OLD_CONVERT, flags);
+ return cp_convert (type, rhs, CONV_OLD_CONVERT,
+ flags | LOOKUP_NO_CONVERSION);
}
if (type == TREE_TYPE (rhs))
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 891a9f70a49..76ac10402e3 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -71,29 +71,6 @@ binfo_or_else (parent_or_type, type)
return NULL_TREE;
}
-/* Print an error message stemming from an invalid use of an
- aggregate type.
-
- TYPE is the type or binfo which draws the error.
- MSG is the message to print.
- ARG is an optional argument which may provide more information. */
-void
-error_with_aggr_type (type, msg, arg)
- tree type;
- char *msg;
- HOST_WIDE_INT arg;
-{
- tree name;
-
- if (TREE_CODE (type) == TREE_VEC)
- type = BINFO_TYPE (type);
-
- name = TYPE_NAME (type);
- if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
- error (msg, IDENTIFIER_POINTER (name), arg);
-}
-
/* According to ARM $7.1.6, "A `const' object may be initialized, but its
value may not be changed thereafter. Thus, we emit hard errors for these,
rather than just pedwarns. If `SOFT' is 1, then we just pedwarn. (For
@@ -108,40 +85,37 @@ readonly_error (arg, string, soft)
void (*fn)();
if (soft)
- fn = pedwarn;
+ fn = cp_pedwarn;
else
- fn = error;
+ fn = cp_error;
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- fmt = "%s of member `%s' in read-only structure";
+ fmt = "%s of member `%D' in read-only structure";
else
- fmt = "%s of read-only member `%s'";
- (*fn) (fmt, string, lang_printable_name (TREE_OPERAND (arg, 1)));
+ fmt = "%s of read-only member `%D'";
+ (*fn) (fmt, string, TREE_OPERAND (arg, 1));
}
else if (TREE_CODE (arg) == VAR_DECL)
{
if (DECL_LANG_SPECIFIC (arg)
&& DECL_IN_AGGR_P (arg)
&& !TREE_STATIC (arg))
- fmt = "%s of constant field `%s'";
+ fmt = "%s of constant field `%D'";
else
- fmt = "%s of read-only variable `%s'";
- (*fn) (fmt, string, lang_printable_name (arg));
+ fmt = "%s of read-only variable `%D'";
+ (*fn) (fmt, string, arg);
}
else if (TREE_CODE (arg) == PARM_DECL)
- (*fn) ("%s of read-only parameter `%s'", string,
- lang_printable_name (arg));
+ (*fn) ("%s of read-only parameter `%D'", string, arg);
else if (TREE_CODE (arg) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
&& (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
|| TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
- (*fn) ("%s of read-only reference `%s'",
- string, lang_printable_name (TREE_OPERAND (arg, 0)));
+ (*fn) ("%s of read-only reference `%D'", string, TREE_OPERAND (arg, 0));
else if (TREE_CODE (arg) == RESULT_DECL)
- (*fn) ("%s of read-only named return value `%s'",
- string, lang_printable_name (arg));
+ (*fn) ("%s of read-only named return value `%D'", string, arg);
else
(*fn) ("%s of read-only location", string);
}
@@ -239,8 +213,7 @@ incomplete_type_error (value, type)
if (value != 0 && (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL))
- error ("`%s' has an incomplete type",
- IDENTIFIER_POINTER (DECL_NAME (value)));
+ cp_error ("`%D' has incomplete type", value);
else
{
retry:
@@ -249,15 +222,9 @@ incomplete_type_error (value, type)
switch (TREE_CODE (type))
{
case RECORD_TYPE:
- errmsg = "invalid use of undefined type `struct %s'";
- break;
-
case UNION_TYPE:
- errmsg = "invalid use of undefined type `union %s'";
- break;
-
case ENUMERAL_TYPE:
- errmsg = "invalid use of undefined type `enum %s'";
+ errmsg = "invalid use of undefined type `%#T'";
break;
case VOID_TYPE:
@@ -281,7 +248,7 @@ incomplete_type_error (value, type)
my_friendly_abort (108);
}
- error_with_aggr_type (type, errmsg);
+ cp_error (errmsg, type);
}
}
@@ -1410,28 +1377,23 @@ build_m_component_ref (datum, component)
return build (OFFSET_REF, rettype, datum, component);
}
-/* Return a tree node for the expression TYPENAME '(' PARMS ')'.
-
- Because we cannot tell whether this construct is really a call to a
- constructor or a request for a type conversion, we try both, and
- report any ambiguities we find. */
+/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
tree
build_functional_cast (exp, parms)
tree exp;
tree parms;
{
+ tree binfo;
+
/* This is either a call to a constructor,
or a C cast in C++'s `functional' notation. */
- tree type, name = NULL_TREE;
- tree expr_as_ctor = NULL_TREE;
+ tree type;
if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node;
if (TREE_CODE (exp) == IDENTIFIER_NODE)
{
- name = exp;
-
if (IDENTIFIER_HAS_TYPE_VALUE (exp))
/* Either an enum or an aggregate type. */
type = IDENTIFIER_TYPE_VALUE (exp);
@@ -1440,7 +1402,7 @@ build_functional_cast (exp, parms)
type = lookup_name (exp, 1);
if (!type || TREE_CODE (type) != TYPE_DECL)
{
- cp_error ("`%T' fails to be a typedef or built-in type", name);
+ cp_error ("`%T' fails to be a typedef or built-in type", exp);
return error_mark_node;
}
type = TREE_TYPE (type);
@@ -1482,13 +1444,6 @@ build_functional_cast (exp, parms)
then the slot being initialized will be filled in. */
- if (name == NULL_TREE)
- {
- name = TYPE_NAME (type);
- if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NESTED_TYPENAME (name);
- }
-
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
cp_error ("type `%T' is not yet defined", type);
@@ -1496,15 +1451,15 @@ build_functional_cast (exp, parms)
}
if (parms && TREE_CHAIN (parms) == NULL_TREE)
- return build_c_cast (type, parms, 1);
+ return build_c_cast (type, TREE_VALUE (parms), 1);
- expr_as_ctor = build_method_call (NULL_TREE, name, parms,
- NULL_TREE, LOOKUP_NORMAL);
+ exp = build_method_call (NULL_TREE, ctor_identifier, parms,
+ TYPE_BINFO (type), LOOKUP_NORMAL);
- if (expr_as_ctor == error_mark_node)
+ if (exp == error_mark_node)
return error_mark_node;
- return build_cplus_new (type, expr_as_ctor);
+ return build_cplus_new (type, exp);
}
/* Return the character string for the name that encodes the