86th Cygnus<->FSF merge

From-SVN: r11654
This commit is contained in:
Mike Stump 1996-04-02 21:44:27 +00:00
parent dd07092ebe
commit c91a56d266
9 changed files with 427 additions and 89 deletions

View File

@ -1,10 +1,134 @@
Fri Mar 29 09:41:02 1996 Jeffrey A. Law <law@cygnus.com
Mon Apr 1 09:03:13 1996 Bob Manson <manson@charmed.cygnus.com>
* class.c (finish_struct_1): Propagate the TYPE_PACKED
flag for the type to the type's fields.
Sat Mar 30 12:14:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* parse.y (complex_parmlist, ELLIPSES): Take out ARM-based warning.
Fri Mar 29 15:51:36 1996 Bob Manson <manson@charmed.cygnus.com>
* class.c (base_info, finish_base_struct): Replace
needs_virtual_dtor with base_has_virtual.
(finish_struct_1): Remove the old code that tried to make default
destructors virtual. Use base_has_virtual when checking if we need
to add a vtable entry for the rtti code.
Fri Mar 29 14:02:36 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (push_template_decl): Complain about template decl with
inappropriate declaration.
Fri Mar 29 12:15:35 1996 Bob Manson <manson@charmed.cygnus.com>
* typeck.c (build_x_unary_op): Remove bogus check for taking
the address of a member function.
Fri Mar 29 11:56:02 1996 Jason Merrill <jason@yorick.cygnus.com>
* parse.y (constructor_declarator): Only push the class if
we are not already in the class.
Fri Mar 29 09:41:02 1996 Jeffrey A. Law <law@cygnus.com>
* method.c (emit_thunk): Remove current_call_is_indirect nonsense.
Add additional argument to INIT_CUMULATIVE_ARGS.
Thu Mar 28 16:41:39 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (shadow_tag): Fix error about anon union with methods.
* parse.y (self_reference): Only generate a self-reference if this
is a non-template class.
(opt.component_decl_list): Only use it if it was generated.
* parse.y (component_decl_1): Use constructor_declarator.
(fn.def2): Ditto.
(notype_component_declarator0): Ditto.
Thu Mar 28 15:11:35 1996 Bob Manson <manson@charmed.cygnus.com>
* typeck.c (build_x_unary_op): Add checks for taking the address
of a TARGET_EXPR or of a member function, and give appropriate
warnings.
Thu Mar 28 14:49:26 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (process_template_parm): Allow template type parms to be
used as types for template const parms.
Wed Mar 27 15:51:19 1996 Mike Stump <mrs@cygnus.com>
* init.c (expand_vec_init): Ensure the eh cleanups are on the
function_obstack.
Wed Mar 27 10:14:30 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (lookup_name_real): Be even more picky about the
ambiguous lookup warning.
(grokdeclarator): Tweak SCOPE_REF constructor declarators here.
* parse.y (constructor_declarator): Rather than here.
* parse.y (constructor_declarator): New nonterminal.
(fn.def1): Use it.
(explicit_instantiation): Ditto.
Tue Mar 26 13:41:33 1996 Jason Merrill <jason@yorick.cygnus.com>
Add implicit declaration of class name at class scope.
* decl.c (lookup_name_real): Restrict pedwarn about ambiguous lookup.
* parse.y (self_reference): New nonterminal.
(opt.component_decl_list): Use it.
(fn.def1): Add nested_name_specifier type_name cases.
* class.c (build_self_reference): New function.
(finish_struct): Handle access_default later, move self-reference
decl to the end.
* pt.c (lookup_template_class): Handle getting a TYPE_DECL.
* cp-tree.h: Adjust.
* pt.c (do_function_instantiation): Separate handling of member
functions and non-member functions properly.
Mon Mar 25 14:23:22 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (process_template_parm): Improve error for 'volatile class K'.
* class.c (finish_struct_1): Check the right slot for destructors.
* decl.c (start_enum): Complain about enum templates.
Mon Mar 25 13:25:31 1996 Mike Stump <mrs@cygnus.com>
* init.c (resolve_offset_ref): Offset pointers to member data by one.
* typeck.c (unary_complex_lvalue): Ditto.
Mon Mar 25 13:30:42 1996 Bob Manson <manson@charmed.cygnus.com>
* typeck.c (c_expand_return): Check for a returned local
array name, similar to the check for an ADDR_EXPR.
Mon Mar 25 13:07:19 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (cp_finish_decl): Don't build cleanups for static
variables here.
Fri Mar 22 17:57:55 1996 Mike Stump <mrs@cygnus.com>
* typeck.c (build_modify_expr): Fix error messages to be more
accurate.
* cp-tree.h (assop_as_string): Parallel to op_as_string, but for
assignment operators.
* error.c (assop_as_string): Ditto. Add support for `%Q' for
assignment operators.
Fri Mar 22 13:48:29 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Call bad_specifiers for typedefs. Also
give an error if initialized. Pedwarn about nested type with the
same name as its enclosing class.
* pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT.
* typeck.c (require_complete_type): Be sure to instantiate the

View File

@ -1384,7 +1384,7 @@ struct base_info
char cant_synth_copy_ctor;
char cant_synth_asn_ref;
char no_const_asn_ref;
char needs_virtual_dtor;
char base_has_virtual;
};
/* Record information about type T derived from its base classes.
@ -1520,9 +1520,8 @@ finish_base_struct (t, b, t_binfo)
if (TYPE_VIRTUAL_P (basetype))
{
/* If there's going to be a destructor needed, make
sure it will be virtual. */
b->needs_virtual_dtor = 1;
/* Remember that the baseclass has virtual members. */
b->base_has_virtual = 1;
/* Don't borrow virtuals from virtual baseclasses. */
if (TREE_VIA_VIRTUAL (base_binfo))
@ -2973,7 +2972,7 @@ finish_struct_1 (t, attributes, warn_anon)
tree fields = TYPE_FIELDS (t);
tree fn_fields = TYPE_METHODS (t);
tree x, last_x, method_vec;
int needs_virtual_dtor;
int base_has_virtual;
int all_virtual;
int has_virtual;
int max_has_virtual;
@ -3083,7 +3082,7 @@ finish_struct_1 (t, attributes, warn_anon)
cant_synth_copy_ctor = base_info.cant_synth_copy_ctor;
cant_synth_asn_ref = base_info.cant_synth_asn_ref;
no_const_asn_ref = base_info.no_const_asn_ref;
needs_virtual_dtor = base_info.needs_virtual_dtor;
base_has_virtual = base_info.base_has_virtual;
n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
aggregate = 0;
}
@ -3100,7 +3099,7 @@ finish_struct_1 (t, attributes, warn_anon)
cant_synth_copy_ctor = 0;
cant_synth_asn_ref = 0;
no_const_asn_ref = 0;
needs_virtual_dtor = 0;
base_has_virtual = 0;
}
#if 0
@ -3172,6 +3171,9 @@ finish_struct_1 (t, attributes, warn_anon)
{
GNU_xref_member (current_class_name, x);
if (TREE_CODE (x) == FIELD_DECL)
DECL_PACKED (x) |= TYPE_PACKED (t);
/* Handle access declarations. */
if (TREE_CODE (x) == USING_DECL)
{
@ -3537,7 +3539,7 @@ finish_struct_1 (t, attributes, warn_anon)
&& !IS_SIGNATURE (t))
{
/* Here we must cons up a destructor on the fly. */
tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
tree dtor = cons_up_default_function (t, name, 0);
check_for_override (dtor, t);
/* If we couldn't make it work, then pretend we didn't need it. */
@ -3550,11 +3552,6 @@ finish_struct_1 (t, attributes, warn_anon)
TREE_CHAIN (dtor) = fn_fields;
fn_fields = dtor;
if (DECL_VINDEX (dtor) == NULL_TREE
&& (needs_virtual_dtor
|| pending_virtuals != NULL_TREE
|| pending_hard_virtuals != NULL_TREE))
DECL_VINDEX (dtor) = error_mark_node;
if (DECL_VINDEX (dtor))
pending_virtuals = add_virtual_function (pending_virtuals,
&has_virtual, dtor, t);
@ -3563,7 +3560,7 @@ finish_struct_1 (t, attributes, warn_anon)
}
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
if (flag_rtti && (max_has_virtual > 0 || needs_virtual_dtor) &&
if (flag_rtti && (max_has_virtual > 0 || base_has_virtual) &&
has_virtual == 0)
has_virtual = 1;
@ -4132,7 +4129,7 @@ finish_struct_1 (t, attributes, warn_anon)
TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield);
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t)
&& DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE)
&& DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE)
cp_warning ("`%#T' has virtual functions but non-virtual destructor",
t);
}
@ -4212,6 +4209,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
tree name = TYPE_NAME (t);
tree x, last_x = NULL_TREE;
tree access;
tree dummy = NULL_TREE;
if (TREE_CODE (name) == TYPE_DECL)
{
@ -4233,25 +4231,33 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
if (IS_SIGNATURE (t))
append_signature_fields (list_of_fieldlists);
/* Move our self-reference declaration to the end of the field list so
any real field with the same name takes precedence. */
if (list_of_fieldlists
&& TREE_VALUE (list_of_fieldlists)
&& DECL_ARTIFICIAL (TREE_VALUE (list_of_fieldlists)))
{
dummy = TREE_VALUE (list_of_fieldlists);
list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
}
if (last_x && list_of_fieldlists)
TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
/* For signatures, we made all methods `public' in the parser and
reported an error if a access specifier was used. */
if (CLASSTYPE_DECLARED_CLASS (t) == 0)
{
if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = access_public_node;
}
else if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = access_private_node;
while (list_of_fieldlists)
{
access = TREE_PURPOSE (list_of_fieldlists);
/* For signatures, we made all methods `public' in the parser and
reported an error if a access specifier was used. */
if (access == access_default_node)
{
if (CLASSTYPE_DECLARED_CLASS (t) == 0)
access = access_public_node;
else
access = access_private_node;
}
for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
{
TREE_PRIVATE (x) = access == access_private_node;
@ -4298,16 +4304,6 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
continue;
}
#if 0
/* Handle access declarations. */
if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
{
tree n = DECL_NAME (x);
x = build_decl
(USING_DECL, DECL_NAME (TREE_OPERAND (n, 1)), TREE_TYPE (x));
DECL_RESULT (x) = n;
}
#endif
if (TREE_CODE (x) != TYPE_DECL)
DECL_FIELD_CONTEXT (x) = t;
@ -4330,7 +4326,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
/* Now add the tags, if any, to the list of TYPE_DECLs
defined for this type. */
if (CLASSTYPE_TAGS (t))
if (CLASSTYPE_TAGS (t) || dummy)
{
x = CLASSTYPE_TAGS (t);
while (x)
@ -4350,6 +4346,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
x = TREE_CHAIN (x);
last_x = chainon (last_x, tag);
}
if (dummy)
last_x = chainon (last_x, dummy);
if (fields == NULL_TREE)
fields = last_x;
CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
@ -5298,6 +5296,7 @@ print_class_statistics ()
decls that may be cached in the previous_class_values list. For now, let's
use the permanent obstack, later we may create a dedicated obstack just
for this purpose. The effect is undone by pop_obstacks. */
void
maybe_push_cache_obstack ()
{
@ -5305,3 +5304,24 @@ maybe_push_cache_obstack ()
if (current_class_depth == 1)
current_obstack = &permanent_obstack;
}
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
according to [class]:
The class-name is also inserted
into the scope of the class itself. For purposes of access checking,
the inserted class name is treated as if it were a public member name. */
tree
build_self_reference ()
{
tree name = constructor_name (current_class_type);
tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
DECL_NONLOCAL (value) = 1;
DECL_CONTEXT (value) = current_class_type;
DECL_CLASS_CONTEXT (value) = current_class_type;
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
DECL_ARTIFICIAL (value) = 1;
pushdecl_class_level (value);
return value;
}

View File

@ -1967,6 +1967,7 @@ extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *));
extern tree build_self_reference PROTO((void));
/* in cvt.c */
extern tree convert_to_reference PROTO((tree, tree, int, int, tree));
@ -2254,6 +2255,7 @@ extern char *code_as_string PROTO((enum tree_code, int));
extern char *language_as_string PROTO((enum languages, int));
extern char *parm_as_string PROTO((int, int));
extern char *op_as_string PROTO((enum tree_code, int));
extern char *assop_as_string PROTO((enum tree_code, int));
extern char *cv_as_string PROTO((tree, int));
/* in method.c */
@ -2290,7 +2292,6 @@ extern tree lookup_template_class PROTO((tree, tree, tree));
extern int uses_template_parms PROTO((tree));
extern tree instantiate_class_template PROTO((tree));
extern tree instantiate_template PROTO((tree, tree *));
extern void overload_template_name PROTO((tree));
extern int type_unification PROTO((tree, tree *, tree, tree, int *, int));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));

View File

@ -4501,12 +4501,18 @@ lookup_name_real (name, prefer_type, nonclass)
done:
if (val)
{
/* This should only warn about types used in qualified-ids. */
if (from_obj && from_obj != val)
{
cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%D')",
name, got_object, from_obj);
cp_pedwarn (" does not match lookup in the current scope (`%D')",
val);
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
&& TREE_CODE (val) == TYPE_DECL
&& TREE_TYPE (from_obj) != TREE_TYPE (val))
{
cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
name, got_object, TREE_TYPE (from_obj));
cp_pedwarn (" does not match lookup in the current scope (`%#T')",
TREE_TYPE (val));
}
}
if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template)
@ -5700,14 +5706,15 @@ shadow_tag (declspecs)
{
/* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have
function members. */
if (TYPE_METHODS (t))
error ("an anonymous union cannot have function members");
if (TYPE_FIELDS (t))
{
tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,
NULL_TREE, NULL_TREE);
finish_anon_union (decl);
}
else
error ("anonymous union cannot have a function member");
}
else
{
@ -6525,7 +6532,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
cp_error ("storage size of `%D' isn't constant", decl);
}
if (!DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type))
if (! DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type)
/* Cleanups for static variables are handled by `finish_file'. */
&& ! TREE_STATIC (decl))
{
int yes = suspend_momentary ();
cleanup = maybe_build_cleanup (decl);
@ -7676,8 +7685,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
ctype = cname;
}
if (ctype
&& TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
&& ((DECL_NAME (TREE_OPERAND (decl, 1))
== constructor_name_full (ctype))
|| (DECL_NAME (TREE_OPERAND (decl, 1))
== constructor_name (ctype))))
TREE_OPERAND (decl, 1) = constructor_name (ctype);
next = &TREE_OPERAND (decl, 1);
decl = *next;
@ -9030,6 +9042,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
if (decl_context == FIELD)
{
if (declarator == current_class_name)
cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",
declarator);
decl = build_lang_decl (TYPE_DECL, declarator, type);
if (IS_SIGNATURE (current_class_type) && opaque_typedef)
SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
@ -9064,6 +9079,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
error ("non-object member `%s' cannot be declared mutable", name);
}
bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
if (initialized)
error ("typedef declaration includes an initializer");
return decl;
}
@ -10597,15 +10618,19 @@ start_enum (name)
enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1);
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
cp_error ("multiple definition of enum `%T'", enumtype);
cp_error ("multiple definition of `%#T'", enumtype);
else
{
enumtype = make_node (ENUMERAL_TYPE);
pushtag (name, enumtype, 0);
}
if (b->pseudo_global)
cp_error ("template declaration of `%#T'", enumtype);
if (current_class_type)
TREE_ADDRESSABLE (b->tags) = 1;
current_local_enum = NULL_TREE;
/* We copy this value because enumerated type constants

View File

@ -34,6 +34,7 @@ typedef char* cp_printer ();
#define L language_as_string
#define O op_as_string
#define P parm_as_string
#define Q assop_as_string
#define T type_as_string
#define V cv_as_string
@ -46,7 +47,7 @@ cp_printer * cp_printers[256] =
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */
_, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */
P, _, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
P, Q, _, _, T, _, V, _, _, _, _, _, _, _, _, _, /* 0x50 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */
};
@ -56,6 +57,7 @@ cp_printer * cp_printers[256] =
#undef L
#undef O
#undef P
#undef Q
#undef T
#undef V
#undef _
@ -1503,6 +1505,20 @@ op_as_string (p, v)
return buf;
}
char *
assop_as_string (p, v)
enum tree_code p;
int v;
{
static char buf[] = "operator ";
if (p == 0)
return "{unknown}";
strcpy (buf + 9, assignop_tab [p]);
return buf;
}
char *
args_as_string (p, v)
tree p;

View File

@ -2071,6 +2071,14 @@ resolve_offset_ref (exp)
addr = convert_pointer_to (basetype, addr);
member = convert (ptrdiff_type_node,
build_unary_op (ADDR_EXPR, member, 0));
/* Pointer to data mebers are offset by one, so that a null
pointer with a real value of 0 is distinguishable from an
offset of the first member of a structure. */
member = build_binary_op (MINUS_EXPR, member,
convert (ptrdiff_type_node, integer_one_node),
0);
return build1 (INDIRECT_REF, type,
build (PLUS_EXPR, build_pointer_type (type),
addr, member));
@ -3399,13 +3407,31 @@ expand_vec_init (decl, base, maxindex, init, from_array)
use_variable (DECL_RTL (base2));
}
expand_end_loop ();
if (TYPE_NEEDS_DESTRUCTOR (type))
end_protect (build_array_eh_cleanup (rval,
build_binary_op (MINUS_EXPR,
maxindex,
iterator,
1),
type));
if (TYPE_NEEDS_DESTRUCTOR (type) && flag_handle_exceptions)
{
/* We have to ensure that this can live to the cleanup
expansion time, since we know it is only ever needed
once, generate code now. */
push_obstacks_nochange ();
resume_temporary_allocation ();
{
tree e1, e2 = make_node (RTL_EXPR);
TREE_TYPE (e2) = void_type_node;
RTL_EXPR_RTL (e2) = const0_rtx;
TREE_SIDE_EFFECTS (e2) = 1;
start_sequence_for_rtl_expr (e2);
e1 = build_array_eh_cleanup
(rval,
build_binary_op (MINUS_EXPR, maxindex, iterator, 1),
type);
expand_expr (e1, const0_rtx, VOIDmode, 0);
RTL_EXPR_SEQUENCE (e2) = get_insns ();
end_sequence ();
end_protect (e2);
}
pop_obstacks ();
}
expand_end_cond ();
if (obey_regdecls)
use_variable (DECL_RTL (iterator));

View File

@ -210,7 +210,7 @@ empty_parms ()
%type <ttype> structsp opt.component_decl_list component_decl_list
%type <ttype> component_decl component_decl_1 components notype_components
%type <ttype> component_declarator component_declarator0
%type <ttype> component_declarator component_declarator0 self_reference
%type <ttype> notype_component_declarator notype_component_declarator0
%type <ttype> after_type_component_declarator after_type_component_declarator0
%type <ttype> enumlist enumerator
@ -231,7 +231,7 @@ empty_parms ()
%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL
%type <ttype> fn.def1 /* Not really! */
%type <ttype> fn.def2 return_id fn.defpen
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
%type <itype> ctor_initializer_opt
%type <ttype> named_class_head named_class_head_sans_basetype
%type <ttype> named_complex_class_head_sans_basetype
@ -551,6 +551,51 @@ fndef:
{}
;
constructor_declarator:
nested_name_specifier type_name '('
{
$$ = build_parse_node (SCOPE_REF, $1, $2);
if ($1 != current_class_type)
{
push_nested_class ($1, 3);
TREE_COMPLEXITY ($$) = current_class_depth;
}
}
parmlist ')' type_quals
{ $$ = build_parse_node (CALL_EXPR, $<ttype>4, $5, $7); }
| nested_name_specifier type_name LEFT_RIGHT type_quals
{
$$ = build_parse_node (SCOPE_REF, $1, $2);
if ($1 != current_class_type)
{
push_nested_class ($1, 3);
TREE_COMPLEXITY ($$) = current_class_depth;
}
$$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $4);
}
| global_scope nested_name_specifier type_name '('
{
$$ = build_parse_node (SCOPE_REF, $2, $3);
if ($2 != current_class_type)
{
push_nested_class ($2, 3);
TREE_COMPLEXITY ($$) = current_class_depth;
}
}
parmlist ')' type_quals
{ $$ = build_parse_node (CALL_EXPR, $<ttype>5, $6, $8); }
| global_scope nested_name_specifier type_name LEFT_RIGHT type_quals
{
$$ = build_parse_node (SCOPE_REF, $2, $3);
if ($2 != current_class_type)
{
push_nested_class ($2, 3);
TREE_COMPLEXITY ($$) = current_class_depth;
}
$$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $5);
}
;
fn.def1:
typed_declspecs declarator exception_specification_opt
{ tree specs, attrs;
@ -571,6 +616,18 @@ fn.def1:
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| declmods constructor_declarator exception_specification_opt
{ tree specs, attrs;
split_specs_attrs ($1, &specs, &attrs);
if (! start_function (specs, $2, $3, attrs, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
| constructor_declarator exception_specification_opt
{ if (! start_function (NULL_TREE, $$, $2, NULL_TREE, 0))
YYERROR1;
reinit_parse_for_function ();
$$ = NULL_TREE; }
;
/* more C++ complexity. See component_decl for a comment on the
@ -578,13 +635,6 @@ fn.def1:
fn.def2:
typed_declspecs '(' parmlist ')' type_quals exception_specification_opt
{ tree specs = strip_attrs ($1);
if (TREE_VALUE (specs) == current_class_type)
{
if (TREE_CHAIN (specs) == NULL_TREE)
specs = get_decl_list (current_class_name);
else
TREE_VALUE (specs) = current_class_name;
}
$$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), $3, $5);
$$ = start_method (TREE_CHAIN (specs), $$, $6);
rest_of_mdef:
@ -608,6 +658,11 @@ fn.def2:
$$ = start_method (specs, $2, $3); goto rest_of_mdef; }
| notype_declarator exception_specification_opt
{ $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
| declmods constructor_declarator exception_specification_opt
{ tree specs = strip_attrs ($1);
$$ = start_method (specs, $2, $3); goto rest_of_mdef; }
| constructor_declarator exception_specification_opt
{ $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
;
return_id: RETURN IDENTIFIER
@ -726,6 +781,8 @@ explicit_instantiation:
do_function_instantiation (specs, $3, NULL_TREE); }
| TEMPLATE notype_declarator
{ do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
| TEMPLATE constructor_declarator
{ do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
| SCSPEC TEMPLATE aggr template_type
{ do_type_instantiation ($4, $1); }
| SCSPEC TEMPLATE typed_declspecs declarator
@ -733,6 +790,8 @@ explicit_instantiation:
do_function_instantiation (specs, $4, $1); }
| SCSPEC TEMPLATE notype_declarator
{ do_function_instantiation (NULL_TREE, $3, $1); }
| SCSPEC TEMPLATE constructor_declarator
{ do_function_instantiation (NULL_TREE, $3, $1); }
;
/* The TYPENAME expansions are to deal with use of a template class name as
@ -2408,15 +2467,26 @@ left_curly: '{'
}
;
self_reference:
/* empty */
{
if (CLASSTYPE_TEMPLATE_INFO (current_class_type))
$$ = NULL_TREE;
else
$$ = build_self_reference ();
}
;
opt.component_decl_list:
/* empty */
{ $$ = NULL_TREE; }
| component_decl_list
self_reference
{ if ($$) $$ = build_tree_list (access_public_node, $$); }
| self_reference component_decl_list
{
if (current_aggr == signature_type_node)
$$ = build_tree_list (access_public_node, $$);
$$ = build_tree_list (access_public_node, $2);
else
$$ = build_tree_list (access_default_node, $$);
$$ = build_tree_list (access_default_node, $2);
if ($1) $$ = tree_cons (access_public_node, $1, $$);
}
| opt.component_decl_list VISSPEC ':' component_decl_list
{
@ -2488,6 +2558,9 @@ component_decl_1:
| notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, NULL_TREE, $2, $5, $3,
build_tree_list ($4, NULL_TREE)); }
| constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, NULL_TREE, $2, $5, $3,
build_tree_list ($4, NULL_TREE)); }
| ':' expr_no_commas
{ $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
| error
@ -2597,6 +2670,12 @@ notype_component_declarator0:
$<ttype>0 = current_declspecs;
$$ = grokfield ($$, current_declspecs, $2, $5, $3,
build_tree_list ($4, prefix_attributes)); }
| constructor_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ split_specs_attrs ($<ttype>0, &current_declspecs,
&prefix_attributes);
$<ttype>0 = current_declspecs;
$$ = grokfield ($$, current_declspecs, $2, $5, $3,
build_tree_list ($4, prefix_attributes)); }
| IDENTIFIER ':' expr_no_commas maybe_attribute
{ split_specs_attrs ($<ttype>0, &current_declspecs,
&prefix_attributes);
@ -2781,7 +2860,7 @@ direct_after_type_declarator:
| '(' after_type_declarator ')'
{ $$ = $2; }
| nested_name_specifier type_name %prec EMPTY
{ push_nested_class (TREE_TYPE ($$), 3);
{ push_nested_class ($1, 3);
$$ = build_parse_node (SCOPE_REF, $$, $2);
TREE_COMPLEXITY ($$) = current_class_depth; }
| type_name %prec EMPTY
@ -3694,9 +3773,6 @@ complex_parmlist:
}
| ELLIPSIS
{
/* ARM $8.2.5 has this as a boxed-off comment. */
if (pedantic)
warning ("use of `...' without a first argument is non-portable");
$$ = NULL_TREE;
}
| TYPENAME_ELLIPSIS

View File

@ -114,9 +114,13 @@ process_template_parm (list, next)
PARM, 0, NULL_TREE, NULL_TREE);
/* A template parameter is not modifiable. */
TREE_READONLY (parm) = 1;
if (IS_AGGR_TYPE (TREE_TYPE (parm)))
if (IS_AGGR_TYPE (TREE_TYPE (parm))
&& TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM)
{
sorry ("aggregate template parameter types");
cp_error ("`%#T' is not a valid type for a template constant parameter",
TREE_TYPE (parm));
if (DECL_NAME (parm) == NULL_TREE)
error (" a template type parameter must begin with `class' or `typename'");
TREE_TYPE (parm) = void_type_node;
}
tinfo = make_node (TEMPLATE_CONST_PARM);
@ -235,8 +239,10 @@ 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;
{
cp_error ("template definition of non-template `%#D'", decl);
return;
}
else
tmpl = DECL_TI_TEMPLATE (decl);
}
@ -609,6 +615,11 @@ lookup_template_class (d1, arglist, in_decl)
if (! template)
template = IDENTIFIER_CLASS_VALUE (d1);
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
{
template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d1));
d1 = DECL_NAME (template);
}
else if (TREE_CODE_CLASS (TREE_CODE (d1)) == 't' && IS_AGGR_TYPE (d1))
{
template = CLASSTYPE_TI_TEMPLATE (d1);
@ -2728,12 +2739,15 @@ do_function_instantiation (declspecs, declarator, storage)
}
/* If we've already seen this template instance, use it. */
if (name = DECL_ASSEMBLER_NAME (decl),
fn = IDENTIFIER_GLOBAL_VALUE (name),
fn && DECL_TEMPLATE_INSTANTIATION (fn))
result = fn;
else if (fn && DECL_CONTEXT (fn))
;
if (DECL_FUNCTION_MEMBER_P (decl))
{
if (DECL_TEMPLATE_INSTANTIATION (decl))
result = decl;
else if (name = DECL_ASSEMBLER_NAME (decl),
fn = IDENTIFIER_GLOBAL_VALUE (name),
fn && DECL_TEMPLATE_INSTANTIATION (fn))
result = fn;
}
else if (name = DECL_NAME (decl), fn = IDENTIFIER_GLOBAL_VALUE (name), fn)
{
for (fn = get_first_fn (fn); fn; fn = DECL_CHAIN (fn))
@ -2779,10 +2793,10 @@ do_function_instantiation (declspecs, declarator, storage)
cp_error ("storage class `%D' applied to template instantiation",
storage);
if (! extern_p)
instantiate_decl (result);
mark_decl_instantiated (result, extern_p);
repo_template_instantiated (result, extern_p);
if (! extern_p)
instantiate_decl (result);
}
void

View File

@ -3999,6 +3999,13 @@ build_x_unary_op (code, xarg)
return build_opfncall (code, LOOKUP_NORMAL, xarg,
NULL_TREE, NULL_TREE);
}
if (code == ADDR_EXPR)
{
if (TREE_CODE (xarg) == TARGET_EXPR)
warning ("taking address of temporary");
}
return build_unary_op (code, xarg, 0);
}
@ -4499,17 +4506,30 @@ unary_complex_lvalue (code, arg)
return error_mark_node;
}
/* Add in the offset to the right subobject. */
offset = get_delta_difference (DECL_FIELD_CONTEXT (t),
TREE_TYPE (TREE_OPERAND (arg, 0)),
0);
/* Add in the offset to the field. */
offset = size_binop (PLUS_EXPR, offset,
size_binop (EASY_DIV_EXPR,
DECL_FIELD_BITPOS (t),
size_int (BITS_PER_UNIT)));
/* We offset all pointer to data memebers by 1 so that we can
distinguish between a null pointer to data member and the first
data member of a structure. */
offset = size_binop (PLUS_EXPR, offset, size_int (1));
return convert (build_pointer_type (TREE_TYPE (arg)), offset);
}
}
#if 0
/* This seems to be obsolete now (and posssibly wrong, compare with
resolve_offset_ref). */
if (TREE_CODE (arg) == OFFSET_REF)
{
tree left = TREE_OPERAND (arg, 0), left_addr;
@ -4530,6 +4550,7 @@ unary_complex_lvalue (code, arg)
build1 (NOP_EXPR, integer_type_node, left_addr),
build1 (NOP_EXPR, integer_type_node, right_addr));
}
#endif
/* We permit compiler to make function calls returning
objects of aggregate type look like lvalues. */
@ -5558,7 +5579,7 @@ build_modify_expr (lhs, modifycode, rhs)
}
else
{
cp_error ("no match for `%O(%#T, %#T)'", modifycode,
cp_error ("no match for `%Q(%#T, %#T)'", modifycode,
TREE_TYPE (lhs), TREE_TYPE (rhs));
return error_mark_node;
}
@ -5567,6 +5588,12 @@ build_modify_expr (lhs, modifycode, rhs)
{
lhs = stabilize_reference (lhs);
newrhs = build_binary_op (modifycode, lhs, rhs, 1);
if (newrhs == error_mark_node)
{
cp_error (" in evaluation of `%Q(%#T, %#T)'", modifycode,
TREE_TYPE (lhs), TREE_TYPE (rhs));
return error_mark_node;
}
}
/* Handle a cast used as an "lvalue".
@ -6977,6 +7004,15 @@ c_expand_return (retval)
&& !TREE_PUBLIC (whats_returned))
cp_warning_at ("address of local variable `%D' returned", whats_returned);
}
else if (TREE_CODE (retval) == VAR_DECL)
{
if (TREE_CODE (TREE_TYPE (retval)) == ARRAY_TYPE
&& DECL_NAME (retval)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (retval))
&& !TREE_STATIC (retval)
&& !TREE_PUBLIC (retval))
cp_warning_at ("address of local array `%D' returned", retval);
}
/* Now deal with possible C++ hair:
(1) Compute the return value.