Commit 28cbf42c by Mike Stump

59th Cygnus<->FSF merge

From-SVN: r9225
parent e96a50cc
Wed Mar 22 15:10:34 1995 Mike Stump <mrs@cygnus.com>
* decl2.c (finish_prevtable_vardecl, finish_vtable_vardecl): Revert
Brendan's last change and fix latent problem that causes TD entries
to not come out when the things that need them has yet to be
expanded.
Wed Mar 22 15:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault, comparison ops): Update type0
and type1, since we might have changed op0 or op1.
Wed Mar 22 13:33:45 1995 Jason Merrill <jason@python.cygnus.com>
* typeck.c (common_type): Don't mess up templates.
Wed Mar 22 04:56:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (common_type): Handle ptms properly. Also handle
T* -> void*.
(build_binary_op_nodefault): New variable build_type controls what
type is given to the expression when it is created. Set this to
boolean_type_node for comparison ops instead of using result_type.
(comp_target_types): Allow T * -> void *.
* cvt.c (cp_convert_to_pointer): Do access control when converting
ptms, too.
Tue Mar 21 17:25:06 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* parse.y (extern_lang_string): Catch use of linkage specs that
aren't all naming the same language.
* class.c (finish_struct): Delete accidental duplicate code.
Tue Mar 21 14:00:57 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault): Disable pedwarns about
comparing functions and incomplete types.
* decl.c (finish_function): Only unset current_function_decl if
!nested.
(duplicate_decls): Last change went too far; we only want to stop
checking for value/reference ambiguity.
Tue Mar 21 01:26:39 1995 Mike Stump <mrs@cygnus.com>
* gc.c (build_generic_desc): Zap the DECL_SIZE so that we can lay it
out fresh, as the new type may be larger.
Mon Mar 20 19:01:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* expr.c (extract_init): Try to expand the RTL for the
initialization and figure out what it will look like so we can avoid
run-time initialization. Disabled for now.
(extract_scalar_init): Helper for scalar initialization.
(extract_aggr_init): Helper for aggregate initialization.
* decl.c (duplicate_decls): Don't complain about ambiguous
declarations.
(obscure_complex_init): Now returns a tree. Call extract_init if
we're optimizing and this is a toplevel decl.
(finish_decl): Update accordingly.
* lex.c (check_newline): If we're just changing files (not pushing
or popping), update input_file_stack->name.
Mon Mar 20 17:55:04 1995 Mike Stump <mrs@cygnus.com>
* pt.c (type_unification): Only TEMPLATE_DECLs are handled right now
in the transitive unification code.
Mon Mar 20 16:07:50 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (shadow_tag): Don't allow inline, virtual, or explicit on
non-functions.
(grokdeclarator): Don't allow friends to be defined in local classes.
Sat Mar 18 04:03:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (finish_prevtable_vardecl): Use DECL_DECLARED_STATIC
rather than DECL_SAVED_INSNS to decide whether or not this method
was declared inline.
* method.c (synthesize_method): Turn off DECL_INLINE if
function_cannot_inline_p thinks we're too large.
* typeck.c (build_indirect_ref): Use build_expr_type_conversion.
Fri Mar 17 17:47:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (instantiate_type): Handle pmfs.
* typeck.c (convert_for_assignment): Check types when assigning one
pmf to another.
* decl.c (define_label): Fix logic for printing out the name of the
label in an error message.
* error.c (dump_expr): Support ARRAY_REF.
Fri Mar 17 17:43:02 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl2.c (finish_vtable_vardecl): Call build_t_desc here.
(finish_prevtable_vardecl): Instead of here.
Fri Mar 17 14:40:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (expand_static_init): Also use expand_aggr_init if the
initializer is a TREE_LIST.
(grokdeclarator): Only pedwarn about extra qualification if -pedantic.
* pt.c (unify): Fix unification of return type.
* expr.c (fixup_result_decl): Use store_expr, rather than
emit_move_insn, to move the return value into the place where
callers will expect it.
Thu Mar 16 22:05:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* init.c (build_offset_ref): Call assmble_external on functions.
* typeck.c (build_component_ref): Ditto.
Thu Mar 16 20:28:16 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (struct saved_scope): Add members base_init_list and
member_init_list.
(push_to_top_level): Save current_base_init_list and
current_member_init_list to them.
(pop_from_top_level): Put it back.
Thu Mar 16 19:21:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (instantiate_template): Call assemble_external.
Thu Mar 16 18:07:54 1995 Brendan Kehoe (brendan@phydeaux.cygnus.com)
* class.c: Include rtl.h, to get NULL_RTX.
(finish_struct): Also zero out DECL_SAVED_INSNS, to avoid problems
on hosts with different sizes for each part of the union.
* tree.c: Also include rtl.h.
(layout_basetypes): Same change for DECL_SAVED_INSNS.
Thu Mar 16 13:57:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (unify): Fix array domain unification for 64-bit targets.
* decl2.c (finish_file): Push bizarre type decl before walking the
vtables the first time.
(walk_vtables): OK, don't set prev to vars if the vardecl_fn messed
with TREE_CHAIN (prev).
* init.c (emit_base_init): Use convert_pointer_to_real instead of
convert_pointer_to when converting to a direct base.
Wed Mar 15 20:26:29 1995 Mike Stump <mrs@cygnus.com>
* pt.c (type_unification): Handle transitive unification better.
Wed Mar 15 13:56:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (walk_vtables): Always set prev to vars.
(mark_vtable_entries): Call assemble_external on the vtable entries.
* class.c (finish_struct): Set the vtable's size to NULL_TREE before
calling layout_decl, so that it gets updated properly.
Finally re-enable dynamic synthesis. This time it works.
* method.c (synthesize_method): Pass decl_function_context (fndecl)
to {push,pop}_cp_function_context.
* decl.c (push_cp_function_context): Now takes a tree argument.
(pop_cp_function_context): Ditto.
* call.c (build_method_call): Enable synthesis.
* lex.c (cons_up_default_function): Ditto.
Tue Mar 14 19:14:19 1995 Doug Evans <dje@chestnut.cygnus.com>
* parse.y (setattrs): Chain onto prefix_attributes rather than
setting it.
Wed Mar 15 13:00:00 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (pushdecl): Check if the type of the VAR_DECL is an
error_mark_node before trying to read TYPE_LANG_SPECIFIC.
Mon Mar 13 21:00:28 1995 Brendan Kehoe (brendan@lisa.cygnus.com) Mon Mar 13 21:00:28 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold, * decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold,
......
...@@ -167,6 +167,7 @@ OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o ...@@ -167,6 +167,7 @@ OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
compiler: ../cc1plus compiler: ../cc1plus
../cc1plus: $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS) ../cc1plus: $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS)
rm -f $@
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o ../cc1plus \ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o ../cc1plus \
$(CXX_OBJS) $(OBJS) $(LIBS) $(CXX_OBJS) $(OBJS) $(LIBS)
......
...@@ -2379,7 +2379,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2379,7 +2379,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* Declare external function if necessary. */ /* Declare external function if necessary. */
assemble_external (function); assemble_external (function);
#if 0 #if 1
/* Is it a synthesized method that needs to be synthesized? */ /* Is it a synthesized method that needs to be synthesized? */
if (DECL_ARTIFICIAL (function) && ! flag_no_inline if (DECL_ARTIFICIAL (function) && ! flag_no_inline
&& DECL_SAVED_INSNS (function) == 0 && DECL_SAVED_INSNS (function) == 0
......
...@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h> #include <stdio.h>
#include "cp-tree.h" #include "cp-tree.h"
#include "flags.h" #include "flags.h"
#include "rtl.h"
#include "obstack.h" #include "obstack.h"
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
...@@ -2963,6 +2964,11 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -2963,6 +2964,11 @@ finish_struct (t, list_of_fieldlists, warn_anon)
DECL_CLASS_CONTEXT (x) = t; DECL_CLASS_CONTEXT (x) = t;
/* Do both of these, even though they're in the same union;
if the insn `r' member and the size `i' member are
different sizes, as on the alpha, the larger of the two
will end up with garbage in it. */
DECL_SAVED_INSNS (x) = NULL_RTX;
DECL_FIELD_SIZE (x) = 0; DECL_FIELD_SIZE (x) = 0;
/* The name of the field is the original field name /* The name of the field is the original field name
...@@ -3027,6 +3033,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -3027,6 +3033,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
fields = x; fields = x;
last_x = x; last_x = x;
DECL_SAVED_INSNS (x) = NULL_RTX;
DECL_FIELD_SIZE (x) = 0; DECL_FIELD_SIZE (x) = 0;
/* When this goes into scope, it will be a non-local reference. */ /* When this goes into scope, it will be a non-local reference. */
...@@ -3505,6 +3512,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -3505,6 +3512,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
DECL_FIELD_CONTEXT (vfield) = t; DECL_FIELD_CONTEXT (vfield) = t;
DECL_CLASS_CONTEXT (vfield) = t; DECL_CLASS_CONTEXT (vfield) = t;
DECL_FCONTEXT (vfield) = t; DECL_FCONTEXT (vfield) = t;
DECL_SAVED_INSNS (vfield) = NULL_RTX;
DECL_FIELD_SIZE (vfield) = 0; DECL_FIELD_SIZE (vfield) = 0;
DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node); DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
if (CLASSTYPE_RTTI (t)) if (CLASSTYPE_RTTI (t))
...@@ -3576,47 +3584,6 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -3576,47 +3584,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_ALIGN (t) = round_up_size; TYPE_ALIGN (t) = round_up_size;
/* Pass layout information about base classes to layout_type, if any. */ /* Pass layout information about base classes to layout_type, if any. */
{
tree field;
for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
{
if (TREE_STATIC (field))
continue;
if (TREE_CODE (field) != FIELD_DECL)
continue;
/* If this field is an anonymous union,
give each union-member the same position as the union has.
??? This is a real kludge because it makes the structure
of the types look strange. This feature is only used by
C++, which should have build_component_ref build two
COMPONENT_REF operations, one for the union and one for
the inner field. We set the offset of this field to zero
so that either the old or the correct method will work.
Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are
moved into the type of this field, but nothing seems to break
by doing this. */
if (DECL_NAME (field) == NULL_TREE
&& TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
{
tree uelt = TYPE_FIELDS (TREE_TYPE (field));
for (; uelt; uelt = TREE_CHAIN (uelt))
{
if (TREE_CODE (uelt) != FIELD_DECL)
continue;
DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
}
DECL_FIELD_BITPOS (field) = integer_zero_node;
}
}
}
if (n_baseclasses) if (n_baseclasses)
{ {
tree pseudo_basetype = TREE_TYPE (base_layout_decl); tree pseudo_basetype = TREE_TYPE (base_layout_decl);
...@@ -3911,6 +3878,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -3911,6 +3878,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype)
{ {
TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype;
DECL_SIZE (TYPE_BINFO_VTABLE (t)) = 0;
layout_decl (TYPE_BINFO_VTABLE (t), 0); layout_decl (TYPE_BINFO_VTABLE (t), 0);
/* At one time the vtable info was grabbed 2 words at a time. This /* At one time the vtable info was grabbed 2 words at a time. This
fails on sparc unless you have 8-byte alignment. (tiemann) */ fails on sparc unless you have 8-byte alignment. (tiemann) */
...@@ -4726,6 +4694,9 @@ instantiate_type (lhstype, rhs, complain) ...@@ -4726,6 +4694,9 @@ instantiate_type (lhstype, rhs, complain)
functions or member functions. May have to undo what functions or member functions. May have to undo what
`default_conversion' might do to lhstype. */ `default_conversion' might do to lhstype. */
if (TYPE_PTRMEMFUNC_P (lhstype))
lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
if (TREE_CODE (lhstype) == POINTER_TYPE) if (TREE_CODE (lhstype) == POINTER_TYPE)
if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
...@@ -4884,8 +4855,7 @@ instantiate_type (lhstype, rhs, complain) ...@@ -4884,8 +4855,7 @@ instantiate_type (lhstype, rhs, complain)
#endif #endif
} }
if (complain) if (complain)
error ("no compatible member functions named `%s'", cp_error ("no compatible member functions named `%D'", name);
IDENTIFIER_POINTER (name));
return error_mark_node; return error_mark_node;
} }
......
/* Definitions for C++ parsing and type checking. /* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1993, 1995 Free Software Foundation, Inc. Copyright (C) 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com) Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC. This file is part of GNU CC.
......
...@@ -155,6 +155,18 @@ cp_convert_to_pointer (type, expr) ...@@ -155,6 +155,18 @@ cp_convert_to_pointer (type, expr)
&& TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
return convert_fn_ptr (type, expr); return convert_fn_ptr (type, expr);
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
&& TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE)
{
tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
tree binfo = get_binfo (b1, b2, 1);
if (binfo == NULL_TREE)
binfo = get_binfo (b2, b1, 1);
if (binfo == error_mark_node)
return error_mark_node;
}
return build1 (NOP_EXPR, type, expr); return build1 (NOP_EXPR, type, expr);
} }
......
...@@ -1443,6 +1443,7 @@ struct saved_scope { ...@@ -1443,6 +1443,7 @@ struct saved_scope {
tree old_bindings; tree old_bindings;
struct saved_scope *prev; struct saved_scope *prev;
tree class_name, class_type, class_decl, function_decl; tree class_name, class_type, class_decl, function_decl;
tree base_init_list, member_init_list;
struct binding_level *class_bindings; struct binding_level *class_bindings;
tree previous_class_type; tree previous_class_type;
tree *lang_base, *lang_stack, lang_name; tree *lang_base, *lang_stack, lang_name;
...@@ -1519,6 +1520,8 @@ push_to_top_level () ...@@ -1519,6 +1520,8 @@ push_to_top_level ()
s->class_type = current_class_type; s->class_type = current_class_type;
s->class_decl = current_class_decl; s->class_decl = current_class_decl;
s->function_decl = current_function_decl; s->function_decl = current_function_decl;
s->base_init_list = current_base_init_list;
s->member_init_list = current_member_init_list;
s->class_bindings = class_binding_level; s->class_bindings = class_binding_level;
s->previous_class_type = previous_class_type; s->previous_class_type = previous_class_type;
s->lang_stack = current_lang_stack; s->lang_stack = current_lang_stack;
...@@ -1571,6 +1574,8 @@ pop_from_top_level () ...@@ -1571,6 +1574,8 @@ pop_from_top_level ()
C_C_D = CLASSTYPE_INST_VAR (current_class_type); C_C_D = CLASSTYPE_INST_VAR (current_class_type);
else else
C_C_D = NULL_TREE; C_C_D = NULL_TREE;
current_base_init_list = s->base_init_list;
current_member_init_list = s->member_init_list;
current_function_decl = s->function_decl; current_function_decl = s->function_decl;
class_binding_level = s->class_bindings; class_binding_level = s->class_bindings;
previous_class_type = s->previous_class_type; previous_class_type = s->previous_class_type;
...@@ -2230,7 +2235,7 @@ duplicate_decls (newdecl, olddecl) ...@@ -2230,7 +2235,7 @@ duplicate_decls (newdecl, olddecl)
cp_error_at ("previous declaration `%#D' here", olddecl); cp_error_at ("previous declaration `%#D' here", olddecl);
} }
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2)) TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 3))
{ {
cp_error ("new declaration `%#D'", newdecl); cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl);
...@@ -3061,6 +3066,7 @@ pushdecl (x) ...@@ -3061,6 +3066,7 @@ pushdecl (x)
/* Keep count of variables in this level with incomplete type. */ /* Keep count of variables in this level with incomplete type. */
/* RTTI TD entries are created while defining the type_info. */ /* RTTI TD entries are created while defining the type_info. */
if (TREE_CODE (x) == VAR_DECL if (TREE_CODE (x) == VAR_DECL
&& TREE_TYPE (x) != error_mark_node
&& TYPE_LANG_SPECIFIC (TREE_TYPE (x)) && TYPE_LANG_SPECIFIC (TREE_TYPE (x))
&& TYPE_BEING_DEFINED (TREE_TYPE (x))) && TYPE_BEING_DEFINED (TREE_TYPE (x)))
{ {
...@@ -3606,6 +3612,7 @@ define_label (filename, line, name) ...@@ -3606,6 +3612,7 @@ define_label (filename, line, name)
else else
{ {
tree uses, prev; tree uses, prev;
int identified = 0;
/* Mark label as having been defined. */ /* Mark label as having been defined. */
DECL_INITIAL (decl) = error_mark_node; DECL_INITIAL (decl) = error_mark_node;
...@@ -3636,10 +3643,11 @@ define_label (filename, line, name) ...@@ -3636,10 +3643,11 @@ define_label (filename, line, name)
&& DECL_INITIAL (new_decls) != error_mark_node) && DECL_INITIAL (new_decls) != error_mark_node)
|| TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
{ {
if (IDENTIFIER_ERROR_LOCUS (decl) == NULL_TREE) if (! identified)
cp_error ("invalid jump to label `%D'", decl); cp_error ("jump to label `%D'", decl);
SET_IDENTIFIER_ERROR_LOCUS (decl, current_function_decl); identified = 1;
cp_error ("crosses initialization of `%D'", new_decls); cp_error_at (" crosses initialization of `%#D'",
new_decls);
} }
new_decls = TREE_CHAIN (new_decls); new_decls = TREE_CHAIN (new_decls);
} }
...@@ -5259,7 +5267,10 @@ shadow_tag (declspecs) ...@@ -5259,7 +5267,10 @@ shadow_tag (declspecs)
else if (value == ridpointers[(int) RID_STATIC] else if (value == ridpointers[(int) RID_STATIC]
|| value == ridpointers[(int) RID_EXTERN] || value == ridpointers[(int) RID_EXTERN]
|| value == ridpointers[(int) RID_AUTO] || value == ridpointers[(int) RID_AUTO]
|| value == ridpointers[(int) RID_REGISTER]) || value == ridpointers[(int) RID_REGISTER]
|| value == ridpointers[(int) RID_INLINE]
|| value == ridpointers[(int) RID_VIRTUAL]
|| value == ridpointers[(int) RID_EXPLICIT])
ob_modifier = value; ob_modifier = value;
} }
...@@ -5290,9 +5301,19 @@ shadow_tag (declspecs) ...@@ -5290,9 +5301,19 @@ shadow_tag (declspecs)
{ {
/* Anonymous unions are objects, that's why we only check for /* Anonymous unions are objects, that's why we only check for
inappropriate specifiers in this branch. */ inappropriate specifiers in this branch. */
if (ob_modifier) if (ob_modifier)
cp_error ("`%D' can only be specified for objects and functions", {
ob_modifier); if (ob_modifier == ridpointers[(int) RID_INLINE]
|| ob_modifier == ridpointers[(int) RID_VIRTUAL])
cp_error ("`%D' can only be specified for functions", ob_modifier);
else if (ob_modifier == ridpointers[(int) RID_EXPLICIT])
cp_error ("`%D' can only be specified for constructors",
ob_modifier);
else
cp_error ("`%D' can only be specified for objects and functions",
ob_modifier);
}
if (found_tag == 0) if (found_tag == 0)
pedwarn ("abstract declarator used as declaration"); pedwarn ("abstract declarator used as declaration");
...@@ -5837,16 +5858,24 @@ grok_reference_init (decl, type, init, cleanupp) ...@@ -5837,16 +5858,24 @@ grok_reference_init (decl, type, init, cleanupp)
it in with a dummy CONSTRUCTOR to force the variable into .data; it in with a dummy CONSTRUCTOR to force the variable into .data;
otherwise we can use error_mark_node. */ otherwise we can use error_mark_node. */
static void static tree
obscure_complex_init (decl) obscure_complex_init (decl, init)
tree decl; tree decl, init;
{ {
if (! flag_no_inline && TREE_STATIC (decl))
{
if (extract_init (decl, init))
return NULL_TREE;
}
if (current_binding_level == global_binding_level if (current_binding_level == global_binding_level
&& ! DECL_COMMON (decl)) && ! DECL_COMMON (decl))
DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE,
NULL_TREE); NULL_TREE);
else else
DECL_INITIAL (decl) = error_mark_node; DECL_INITIAL (decl) = error_mark_node;
return init;
} }
/* Finish processing of a declaration; /* Finish processing of a declaration;
...@@ -6078,22 +6107,18 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) ...@@ -6078,22 +6107,18 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
} }
} }
#endif #endif
/* We must hide the initializer so that expand_decl
won't try to do something it does not understand. */
obscure_complex_init (decl);
} }
else else
{ {
dont_use_constructor: dont_use_constructor:
if (TREE_CODE (init) != TREE_VEC) if (TREE_CODE (init) != TREE_VEC)
init = store_init_value (decl, init); init = store_init_value (decl, init);
/* Don't let anyone try to initialize this variable
until we are ready to do so. */
if (init)
obscure_complex_init (decl);
} }
if (init)
/* We must hide the initializer so that expand_decl
won't try to do something it does not understand. */
init = obscure_complex_init (decl, init);
} }
else if (DECL_EXTERNAL (decl)) else if (DECL_EXTERNAL (decl))
; ;
...@@ -6120,7 +6145,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags) ...@@ -6120,7 +6145,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (TYPE_SIZE (type) != NULL_TREE if (TYPE_SIZE (type) != NULL_TREE
&& TYPE_NEEDS_CONSTRUCTING (type)) && TYPE_NEEDS_CONSTRUCTING (type))
obscure_complex_init (decl); init = obscure_complex_init (decl, NULL_TREE);
} }
else if (TREE_CODE (decl) == VAR_DECL else if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE && TREE_CODE (type) != REFERENCE_TYPE
...@@ -6589,7 +6614,8 @@ expand_static_init (decl, init) ...@@ -6589,7 +6614,8 @@ expand_static_init (decl, init)
integer_zero_node, 1), 0); integer_zero_node, 1), 0);
old_cleanups = cleanups_this_call; old_cleanups = cleanups_this_call;
expand_assignment (temp, integer_one_node, 0, 0); expand_assignment (temp, integer_one_node, 0, 0);
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
|| TREE_CODE (init) == TREE_LIST)
{ {
expand_aggr_init (decl, init, 0, 0); expand_aggr_init (decl, init, 0, 0);
do_pending_stack_adjust (); do_pending_stack_adjust ();
...@@ -8372,11 +8398,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) ...@@ -8372,11 +8398,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
RIDBIT_RESET (RID_FRIEND, specbits); RIDBIT_RESET (RID_FRIEND, specbits);
friendp = 0; friendp = 0;
} }
if (decl_context == NORMAL)
error ("friend declaration not in class definition");
if (current_function_decl && funcdef_flag)
cp_error ("can't define friend function `%s' in a local class definition",
name);
} }
if (decl_context == NORMAL && friendp)
error ("friend declaration not in class definition");
/* Traditionally, declaring return type float means double. */ /* Traditionally, declaring return type float means double. */
if (flag_traditional if (flag_traditional
...@@ -8598,8 +8626,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) ...@@ -8598,8 +8626,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
basetype :: member . */ basetype :: member . */
if (ctype == current_class_type) if (ctype == current_class_type)
cp_pedwarn ("extra qualification `%T::' on member `%s' ignored", {
ctype, name); /* class A {
void A::f ();
};
Is this ill-formed? */
if (pedantic)
cp_pedwarn ("extra qualification `%T::' on member `%s' ignored",
ctype, name);
}
else if (TREE_CODE (type) == FUNCTION_TYPE) else if (TREE_CODE (type) == FUNCTION_TYPE)
{ {
if (current_class_type == NULL_TREE if (current_class_type == NULL_TREE
...@@ -11307,7 +11344,7 @@ finish_function (lineno, call_poplevel, nested) ...@@ -11307,7 +11344,7 @@ finish_function (lineno, call_poplevel, nested)
int ok_to_optimize_dtor = 0; int ok_to_optimize_dtor = 0;
if (current_function_assigns_this) if (current_function_assigns_this)
cond = build (NE_EXPR, integer_type_node, cond = build (NE_EXPR, boolean_type_node,
current_class_decl, integer_zero_node); current_class_decl, integer_zero_node);
else else
{ {
...@@ -11756,8 +11793,14 @@ finish_function (lineno, call_poplevel, nested) ...@@ -11756,8 +11793,14 @@ finish_function (lineno, call_poplevel, nested)
if (DECL_STATIC_DESTRUCTOR (fndecl)) if (DECL_STATIC_DESTRUCTOR (fndecl))
static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors); static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors);
/* Let the error reporting routines know that we're outside a function. */ if (! nested)
current_function_decl = NULL_TREE; {
/* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in
pop_cp_function_context and then reset via pop_function_context. */
current_function_decl = NULL_TREE;
}
named_label_uses = NULL_TREE; named_label_uses = NULL_TREE;
} }
...@@ -12190,13 +12233,13 @@ struct cp_function *cp_function_chain; ...@@ -12190,13 +12233,13 @@ struct cp_function *cp_function_chain;
used during compilation of a C++ function. */ used during compilation of a C++ function. */
void void
push_cp_function_context (toplev) push_cp_function_context (context)
int toplev; tree context;
{ {
struct cp_function *p struct cp_function *p
= (struct cp_function *) xmalloc (sizeof (struct cp_function)); = (struct cp_function *) xmalloc (sizeof (struct cp_function));
push_function_context_to (toplev); push_function_context_to (context);
p->next = cp_function_chain; p->next = cp_function_chain;
cp_function_chain = p; cp_function_chain = p;
...@@ -12221,8 +12264,8 @@ push_cp_function_context (toplev) ...@@ -12221,8 +12264,8 @@ push_cp_function_context (toplev)
/* Restore the variables used during compilation of a C++ function. */ /* Restore the variables used during compilation of a C++ function. */
void void
pop_cp_function_context (toplev) pop_cp_function_context (context)
int toplev; tree context;
{ {
struct cp_function *p = cp_function_chain; struct cp_function *p = cp_function_chain;
tree link; tree link;
...@@ -12244,7 +12287,7 @@ pop_cp_function_context (toplev) ...@@ -12244,7 +12287,7 @@ pop_cp_function_context (toplev)
} }
#endif #endif
pop_function_context_from (toplev); pop_function_context_from (context);
cp_function_chain = p->next; cp_function_chain = p->next;
......
...@@ -1932,7 +1932,8 @@ build_push_scope (cname, name) ...@@ -1932,7 +1932,8 @@ build_push_scope (cname, name)
return rval; return rval;
} }
void cplus_decl_attributes (decl, attributes, prefix_attributes) void
cplus_decl_attributes (decl, attributes, prefix_attributes)
tree decl, attributes, prefix_attributes; tree decl, attributes, prefix_attributes;
{ {
if (decl && decl != void_type_node) if (decl && decl != void_type_node)
...@@ -2463,7 +2464,14 @@ mark_vtable_entries (decl) ...@@ -2463,7 +2464,14 @@ mark_vtable_entries (decl)
extern tree abort_fndecl; extern tree abort_fndecl;
if (flag_vtable_thunks) if (flag_vtable_thunks)
fnaddr = TREE_VALUE (entries); fnaddr = TREE_VALUE (entries);
TREE_OPERAND (fnaddr, 0) = abort_fndecl; TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl;
}
if (TREE_PUBLIC (fn) && ! TREE_ASM_WRITTEN (fn))
{
int save_extern = DECL_EXTERNAL (fn);
DECL_EXTERNAL (fn) = 1;
assemble_external (fn);
DECL_EXTERNAL (fn) = save_extern;
} }
} }
} }
...@@ -2561,7 +2569,8 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2561,7 +2569,8 @@ finish_prevtable_vardecl (prev, vars)
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
method = DECL_NEXT_METHOD (method)) method = DECL_NEXT_METHOD (method))
{ {
if (DECL_VINDEX (method) != NULL_TREE && !DECL_SAVED_INSNS (method) if (DECL_VINDEX (method) != NULL_TREE
&& !DECL_DECLARED_STATIC (method)
&& !DECL_ABSTRACT_VIRTUAL_P (method)) && !DECL_ABSTRACT_VIRTUAL_P (method))
{ {
SET_CLASSTYPE_INTERFACE_KNOWN (ctype); SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
...@@ -2574,10 +2583,17 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2574,10 +2583,17 @@ finish_prevtable_vardecl (prev, vars)
import_export_vtable (vars, ctype, 1); import_export_vtable (vars, ctype, 1);
/* We cannot use TREE_USED here, as it may be set by the expanding of a
ctor that is used to build a global object. The long term plan is to
make the TD entries statically initialized and move this to
finish_vtable_vardecl time. */
if (flag_rtti && write_virtuals >= 0 if (flag_rtti && write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || 1 || TREE_USED (vars)))
{ {
/* Kick out the type descriptor before writing out the vtable. */ /* Kick out the type descriptor before we dump out global
initializers, as they are initialized at run time and
we have to find them when we scan for things that need initialized
at the top level. */
build_t_desc (ctype, 1); build_t_desc (ctype, 1);
} }
} }
...@@ -2589,6 +2605,15 @@ finish_vtable_vardecl (prev, vars) ...@@ -2589,6 +2605,15 @@ finish_vtable_vardecl (prev, vars)
if (write_virtuals >= 0 if (write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
{ {
#if 0
/* The long term plan it to make the TD entries statically initialized,
have the entries built and emitted here. When that happens, this
can be enabled, and the other call to build_t_desc removed. */
/* Kick out the type descriptor before writing out the vtable. */
if (flag_rtti)
build_t_desc (DECL_CONTEXT (vars), 1);
#endif
/* Write it out. */ /* Write it out. */
mark_vtable_entries (vars); mark_vtable_entries (vars);
if (TREE_TYPE (DECL_INITIAL (vars)) == 0) if (TREE_TYPE (DECL_INITIAL (vars)) == 0)
...@@ -2651,19 +2676,22 @@ walk_vtables (typedecl_fn, vardecl_fn) ...@@ -2651,19 +2676,22 @@ walk_vtables (typedecl_fn, vardecl_fn)
{ {
register tree type = TREE_TYPE (vars); register tree type = TREE_TYPE (vars);
if (TREE_CODE (vars) == TYPE_DECL if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars))
&& type != error_mark_node
&& TYPE_LANG_SPECIFIC (type)
&& CLASSTYPE_VSIZE (type))
{ {
if (typedecl_fn) (*typedecl_fn) (prev, vars); if (vardecl_fn) (*vardecl_fn) (prev, vars);
if (prev && TREE_CHAIN (prev) != vars)
continue;
} }
else if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) else if (TREE_CODE (vars) == TYPE_DECL
&& type != error_mark_node
&& TYPE_LANG_SPECIFIC (type)
&& CLASSTYPE_VSIZE (type))
{ {
if (vardecl_fn) (*vardecl_fn) (prev, vars); if (typedecl_fn) (*typedecl_fn) (prev, vars);
} }
else
prev = vars; prev = vars;
} }
} }
...@@ -2805,6 +2833,31 @@ finish_file () ...@@ -2805,6 +2833,31 @@ finish_file ()
interface_unknown = 1; interface_unknown = 1;
interface_only = 0; interface_only = 0;
#if 1
/* The reason for pushing garbage onto the global_binding_level is to
ensure that we can slice out _DECLs which pertain to virtual function
tables. If the last thing pushed onto the global_binding_level was a
virtual function table, then slicing it out would slice away all the
decls (i.e., we lose the head of the chain).
There are several ways of getting the same effect, from changing the
way that iterators over the chain treat the elements that pertain to
virtual function tables, moving the implementation of this code to
decl.c (where we can manipulate global_binding_level directly),
popping the garbage after pushing it and slicing away the vtable
stuff, or just leaving it alone. */
/* Make last thing in global scope not be a virtual function table. */
#if 0 /* not yet, should get fixed properly later */
vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node);
#else
vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node);
#endif
DECL_IGNORED_P (vars) = 1;
SET_DECL_ARTIFICIAL (vars);
pushdecl (vars);
#endif
/* Walk to mark the inline functions we need, then output them so /* Walk to mark the inline functions we need, then output them so
that we can pick up any other tdecls that those routines need. */ that we can pick up any other tdecls that those routines need. */
walk_vtables ((void (*)())0, finish_prevtable_vardecl); walk_vtables ((void (*)())0, finish_prevtable_vardecl);
...@@ -3023,37 +3076,12 @@ finish_file () ...@@ -3023,37 +3076,12 @@ finish_file ()
start_time = get_run_time (); start_time = get_run_time ();
/* Now delete from the chain of variables all virtual function tables.
We output them all ourselves, because each will be treated specially. */
#if 1
/* The reason for pushing garbage onto the global_binding_level is to
ensure that we can slice out _DECLs which pertain to virtual function
tables. If the last thing pushed onto the global_binding_level was a
virtual function table, then slicing it out would slice away all the
decls (i.e., we lose the head of the chain).
There are several ways of getting the same effect, from changing the
way that iterators over the chain treat the elements that pertain to
virtual function tables, moving the implementation of this code to
decl.c (where we can manipulate global_binding_level directly),
popping the garbage after pushing it and slicing away the vtable
stuff, or just leaving it alone. */
/* Make last thing in global scope not be a virtual function table. */
#if 0 /* not yet, should get fixed properly later */
vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node);
#else
vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node);
#endif
DECL_IGNORED_P (vars) = 1;
SET_DECL_ARTIFICIAL (vars);
pushdecl (vars);
#endif
if (flag_handle_signatures) if (flag_handle_signatures)
walk_sigtables ((void (*)())0, finish_sigtable_vardecl); walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
for (fnname = saved_inlines; fnname; fnname = TREE_CHAIN (fnname))
import_export_inline (TREE_VALUE (fnname));
/* Now write out inline functions which had their addresses taken and /* Now write out inline functions which had their addresses taken and
which were not declared virtual and which were not declared `extern which were not declared virtual and which were not declared `extern
inline'. */ inline'. */
...@@ -3089,7 +3117,7 @@ finish_file () ...@@ -3089,7 +3117,7 @@ finish_file ()
TREE_CHAIN (last) = TREE_CHAIN (place); TREE_CHAIN (last) = TREE_CHAIN (place);
continue; continue;
} }
import_export_inline (decl);
if (TREE_PUBLIC (decl) if (TREE_PUBLIC (decl)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|| flag_keep_inline_functions) || flag_keep_inline_functions)
...@@ -3112,6 +3140,9 @@ finish_file () ...@@ -3112,6 +3140,9 @@ finish_file ()
} }
} }
/* Now delete from the chain of variables all virtual function tables.
We output them all ourselves, because each will be treated specially. */
walk_vtables ((void (*)())0, prune_vtable_vardecl); walk_vtables ((void (*)())0, prune_vtable_vardecl);
for (vars = getdecls (); vars; vars = TREE_CHAIN (vars)) for (vars = getdecls (); vars; vars = TREE_CHAIN (vars))
......
...@@ -1142,6 +1142,13 @@ dump_expr (t, nop) ...@@ -1142,6 +1142,13 @@ dump_expr (t, nop)
} }
break; break;
case ARRAY_REF:
dump_expr (TREE_OPERAND (t, 0), 0);
OB_PUTC ('[');
dump_expr (TREE_OPERAND (t, 1), 0);
OB_PUTC (']');
break;
case CONVERT_EXPR: case CONVERT_EXPR:
dump_unary_op ("+", t, nop); dump_unary_op ("+", t, nop);
break; break;
......
...@@ -264,7 +264,7 @@ fixup_result_decl (decl, result) ...@@ -264,7 +264,7 @@ fixup_result_decl (decl, result)
REG_FUNCTION_VALUE_P (real_decl_result) = 1; REG_FUNCTION_VALUE_P (real_decl_result) = 1;
result = real_decl_result; result = real_decl_result;
} }
emit_move_insn (result, DECL_RTL (decl)); store_expr (decl, result, 0);
emit_insn (gen_rtx (USE, VOIDmode, result)); emit_insn (gen_rtx (USE, VOIDmode, result));
} }
} }
...@@ -274,9 +274,90 @@ fixup_result_decl (decl, result) ...@@ -274,9 +274,90 @@ fixup_result_decl (decl, result)
in some cases. We cannot use `memory_operand' as a test in some cases. We cannot use `memory_operand' as a test
here because on most RISC machines, a variable's address here because on most RISC machines, a variable's address
is not, by itself, a legitimate address. */ is not, by itself, a legitimate address. */
int int
decl_in_memory_p (decl) decl_in_memory_p (decl)
tree decl; tree decl;
{ {
return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM; return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM;
} }
/* Expand this initialization inline and see if it's simple enough that
it can be done at compile-time. */
static tree
extract_aggr_init (decl, init)
tree decl, init;
{
return 0;
}
static tree
extract_scalar_init (decl, init)
tree decl, init;
{
rtx value, insns, insn;
extern struct obstack temporary_obstack;
tree t = NULL_TREE;
push_obstacks (&temporary_obstack, &temporary_obstack);
start_sequence ();
value = expand_expr (init, NULL_RTX, VOIDmode, 0);
insns = get_insns ();
end_sequence ();
reg_scan (insns, max_reg_num (), 0);
jump_optimize (insns, 0, 0, 1);
pop_obstacks ();
for (insn = insns; insn; insn = NEXT_INSN (insn))
{
rtx r, to;
if (GET_CODE (insn) == NOTE)
continue;
else if (GET_CODE (insn) != INSN)
return 0;
r = PATTERN (insn);
if (GET_CODE (r) != SET)
return 0;
to = XEXP (r, 0);
if (! (to == value ||
(GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
return 0;
r = XEXP (r, 1);
switch (GET_CODE (r))
{
case CONST_INT:
t = build_int_2 (XEXP (r, 0), 0);
break;
default:
return 0;
}
}
return t;
}
int
extract_init (decl, init)
tree decl, init;
{
return 0;
if (IS_AGGR_TYPE (TREE_TYPE (decl))
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
init = extract_aggr_init (decl, init);
else
init = extract_scalar_init (decl, init);
if (init == NULL_TREE)
return 0;
DECL_INITIAL (decl) = init;
return 1;
}
...@@ -571,7 +571,7 @@ emit_base_init (t, immediately) ...@@ -571,7 +571,7 @@ emit_base_init (t, immediately)
if (init != void_list_node) if (init != void_list_node)
{ {
member = convert_pointer_to (base_binfo, current_class_decl); member = convert_pointer_to_real (base_binfo, current_class_decl);
expand_aggr_init_1 (base_binfo, 0, expand_aggr_init_1 (base_binfo, 0,
build_indirect_ref (member, NULL_PTR), init, build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL); BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
...@@ -1980,6 +1980,10 @@ build_offset_ref (cname, name) ...@@ -1980,6 +1980,10 @@ build_offset_ref (cname, name)
&& ((flag_save_memoized_contexts && global_bindings_p ()) && ((flag_save_memoized_contexts && global_bindings_p ())
|| ! allocation_temporary_p ())) || ! allocation_temporary_p ()))
fnfields = copy_list (fnfields); fnfields = copy_list (fnfields);
for (t = TREE_VALUE (fnfields); t; t = DECL_CHAIN (t))
assemble_external (t);
t = build_tree_list (error_mark_node, fnfields); t = build_tree_list (error_mark_node, fnfields);
TREE_TYPE (t) = build_offset_type (type, unknown_type_node); TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
return t; return t;
......
...@@ -1796,8 +1796,10 @@ cons_up_default_function (type, full_name, kind) ...@@ -1796,8 +1796,10 @@ cons_up_default_function (type, full_name, kind)
/* When on-the-fly synthesis works properly, remove the second and third /* When on-the-fly synthesis works properly, remove the second and third
conditions here. */ conditions here. */
if (flag_keep_inline_functions if (flag_keep_inline_functions
#if 0
|| ! flag_no_inline || ! flag_no_inline
|| complex || complex
#endif
|| ! DECL_EXTERNAL (fn)) || ! DECL_EXTERNAL (fn))
{ {
struct pending_inline *t; struct pending_inline *t;
...@@ -2812,7 +2814,13 @@ linenum: ...@@ -2812,7 +2814,13 @@ linenum:
extract_interface_info (); extract_interface_info ();
c = get_last_nonwhite_on_line (); c = get_last_nonwhite_on_line ();
if (c != EOF) if (c == EOF)
{
/* Update the name in the top element of input_file_stack. */
if (input_file_stack)
input_file_stack->name = input_filename;
}
else
{ {
put_back (c); put_back (c);
......
...@@ -2209,12 +2209,12 @@ synthesize_method (fndecl) ...@@ -2209,12 +2209,12 @@ synthesize_method (fndecl)
tree fndecl; tree fndecl;
{ {
int nested = (current_function_decl != NULL_TREE); int nested = (current_function_decl != NULL_TREE);
int toplev = (decl_function_context (fndecl) == NULL_TREE); tree context = decl_function_context (fndecl);
char *f = input_filename; char *f = input_filename;
tree base = DECL_CLASS_CONTEXT (fndecl); tree base = DECL_CLASS_CONTEXT (fndecl);
if (nested) if (nested)
push_cp_function_context (toplev); push_cp_function_context (context);
input_filename = DECL_SOURCE_FILE (fndecl); input_filename = DECL_SOURCE_FILE (fndecl);
interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (base); interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (base);
...@@ -2238,8 +2238,19 @@ synthesize_method (fndecl) ...@@ -2238,8 +2238,19 @@ synthesize_method (fndecl)
} }
finish_function (lineno, 0, nested); finish_function (lineno, 0, nested);
/* Do we really *want* to inline this function? */
if (DECL_INLINE (fndecl))
{
/* Turn off DECL_INLINE for the moment so function_cannot_inline_p
will check our size. */
DECL_INLINE (fndecl) = 0;
if (function_cannot_inline_p (fndecl) == 0)
DECL_INLINE (fndecl) = 1;
}
input_filename = f; input_filename = f;
extract_interface_info (); extract_interface_info ();
if (nested) if (nested)
pop_cp_function_context (toplev); pop_cp_function_context (context);
} }
...@@ -402,8 +402,12 @@ any_id: ...@@ -402,8 +402,12 @@ any_id:
; ;
extern_lang_string: extern_lang_string:
EXTERN_LANG_STRING EXTERN_LANG_STRING
{ push_lang_context ($1); } { push_lang_context ($1); }
| extern_lang_string EXTERN_LANG_STRING
{ if (current_lang_name != $2)
cp_error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name);
pop_lang_context (); push_lang_context ($2); }
; ;
template_header: template_header:
...@@ -1725,7 +1729,7 @@ object: primary '.' ...@@ -1725,7 +1729,7 @@ object: primary '.'
; ;
setattrs: /* empty */ setattrs: /* empty */
{ prefix_attributes = $<ttype>0; } { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
; ;
decl: decl:
......
...@@ -1712,6 +1712,8 @@ instantiate_template (tmpl, targ_ptr) ...@@ -1712,6 +1712,8 @@ instantiate_template (tmpl, targ_ptr)
if (fndecl == error_mark_node) if (fndecl == error_mark_node)
goto exit; goto exit;
assemble_external (fndecl);
/* If it's a static member fn in the template, we need to change it /* If it's a static member fn in the template, we need to change it
into a FUNCTION_TYPE and chop off its this pointer. */ into a FUNCTION_TYPE and chop off its this pointer. */
if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE
...@@ -2059,6 +2061,23 @@ type_unification (tparms, targs, parms, args, nsubsts, subr) ...@@ -2059,6 +2061,23 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't') if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't')
{ {
my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293); my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
if (TREE_CODE (arg) == TREE_LIST
&& TREE_TYPE (arg) == unknown_type_node
&& TREE_CODE (TREE_VALUE (arg)) == TEMPLATE_DECL)
{
int nsubsts, ntparms;
tree *targs;
/* Have to back unify here */
arg = TREE_VALUE (arg);
nsubsts = 0;
ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (arg));
targs = (tree *) alloca (sizeof (tree) * ntparms);
parm = tree_cons (NULL_TREE, parm, NULL_TREE);
return type_unification (DECL_TEMPLATE_PARMS (arg), targs,
TYPE_ARG_TYPES (TREE_TYPE (arg)),
parm, &nsubsts, 0);
}
arg = TREE_TYPE (arg); arg = TREE_TYPE (arg);
} }
#endif #endif
...@@ -2200,6 +2219,8 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2200,6 +2219,8 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
nsubsts); nsubsts);
case REFERENCE_TYPE: case REFERENCE_TYPE:
if (TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts); return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts);
case ARRAY_TYPE: case ARRAY_TYPE:
...@@ -2242,8 +2263,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2242,8 +2263,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
tree t1, t2; tree t1, t2;
t1 = TREE_OPERAND (parm, 0); t1 = TREE_OPERAND (parm, 0);
t2 = TREE_OPERAND (parm, 1); t2 = TREE_OPERAND (parm, 1);
if (TREE_CODE (t1) != TEMPLATE_CONST_PARM)
return 1;
return unify (tparms, targs, ntparms, t1, return unify (tparms, targs, ntparms, t1,
fold (build (PLUS_EXPR, integer_type_node, arg, t2)), fold (build (PLUS_EXPR, integer_type_node, arg, t2)),
nsubsts); nsubsts);
...@@ -2299,6 +2318,9 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2299,6 +2318,9 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if (TREE_CODE (arg) != FUNCTION_TYPE) if (TREE_CODE (arg) != FUNCTION_TYPE)
return 1; return 1;
check_args: check_args:
if (unify (tparms, targs, ntparms, TREE_TYPE (parm),
TREE_TYPE (arg), nsubsts))
return 1;
return type_unification (tparms, targs, TYPE_ARG_TYPES (parm), return type_unification (tparms, targs, TYPE_ARG_TYPES (parm),
TYPE_ARG_TYPES (arg), nsubsts, 1); TYPE_ARG_TYPES (arg), nsubsts, 1);
......
...@@ -24,6 +24,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -24,6 +24,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "tree.h" #include "tree.h"
#include "cp-tree.h" #include "cp-tree.h"
#include "flags.h" #include "flags.h"
#include "rtl.h"
#define CEIL(x,y) (((x) + (y) - 1) / (y)) #define CEIL(x,y) (((x) + (y) - 1) / (y))
...@@ -826,6 +827,7 @@ layout_basetypes (rec, binfos) ...@@ -826,6 +827,7 @@ layout_basetypes (rec, binfos)
DECL_FIELD_CONTEXT (decl) = rec; DECL_FIELD_CONTEXT (decl) = rec;
DECL_CLASS_CONTEXT (decl) = rec; DECL_CLASS_CONTEXT (decl) = rec;
DECL_FCONTEXT (decl) = basetype; DECL_FCONTEXT (decl) = basetype;
DECL_SAVED_INSNS (decl) = NULL_RTX;
DECL_FIELD_SIZE (decl) = 0; DECL_FIELD_SIZE (decl) = 0;
DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node); DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node);
TREE_CHAIN (decl) = vbase_decls; TREE_CHAIN (decl) = vbase_decls;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment