Commit a4443a08 by Mike Stump

37th Cygnus<->FSF merge

From-SVN: r7290
parent 5dab5552
...@@ -2,6 +2,186 @@ Thu May 12 19:13:54 1994 Richard Earnshaw (rwe11@cl.cam.ac.uk) ...@@ -2,6 +2,186 @@ Thu May 12 19:13:54 1994 Richard Earnshaw (rwe11@cl.cam.ac.uk)
* g++.c: Use #ifdef for __MSDOS__, not #if. * g++.c: Use #ifdef for __MSDOS__, not #if.
Thu May 12 18:05:18 1994 Mike Stump (mrs@cygnus.com)
* decl2.c (lang_f_options): Handle -fshort-temps. -fshort-temps
gives old behavior , and destroys temporaries earlier. Default
behavior now conforms to the ANSI working paper.
Thu May 12 14:45:35 1994 Jason Merrill (jason@deneb.cygnus.com)
* typeck.c (build_modify_expr): Understand MODIFY_EXPR as an lvalue.
Use convert_force to convert the result of a recursive call when we
are dealing with a NOP_EXPR. Don't automatically wrap MODIFY_EXPRs
in COMPOUND_EXPRs any more.
(various): Lose pedantic_lvalue_warning.
(unary_complex_lvalue): Understand MODIFY_EXPR.
* cvt.c (convert_to_reference): Allow DECL to be error_mark_node if
we don't know what we're initializing.
Wed May 11 01:59:36 1994 Jason Merrill (jason@deneb.cygnus.com)
* cvt.c (convert_to_reference): Modify to use convtype parameter.
Only create temporaries when initializing a reference, not when
casting.
(cp_convert): New main function.
(convert): Call cp_convert.
* cvt.c, decl.c, typeck.c: Fix calls to convert_to_reference.
* cp-tree.h (CONV_*): New constants used by conversion code for
selecting conversions to perform.
* tree.c (lvalue_p): MODIFY_EXPRs are no longer lvalues.
* typeck.c (build_{static,reinterpret,const_cast): Stubs that just
call build_c_cast.
* parse.y: Add {static,reinterpret,const}_cast.
* gxx.gperf: Ditto.
* typeck.c (common_type): Allow methods with basetypes of different
UPTs.
(comptypes): Deal with UPTs.
(build_modify_expr): Wrap all MODIFY_EXPRs in a COMPOUND_EXPR.
* pt.c (end_template_decl): Check for multiple definitions of member
templates.
* call.c (build_method_call): Complain about calling an abstract
virtual from a constructor.
* typeck.c (pointer_int_sum): Check for the integer operand being 0
after checking the validity of the pointer operand.
* typeck2.c (digest_init): Pedwarn about string initializer being
too long.
Tue May 10 12:10:28 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (push_overloaded_decl): Only throw away a builtin if the
decl in question is the artificial one.
* parse.y (simple_stmt, switch): Use implicitly_scoped_stmt because
expand_{start,end}_case cannot happen in the middle of a block.
* cvt.c (build_type_conversion_1): Use convert again.
Tue May 10 11:52:04 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
* typeck2.c (digest_init): Make sure we check for signed and
unsigned chars as well when warning about string initializers.
* init.c (emit_base_init): Check if there's a DECL_NAME on the
member before trying to do an initialization for it.
Tue May 10 11:34:37 1994 Mike Stump (mrs@cygnus.com)
* except.c: Don't do anything useful when cross compiling.
Tue May 10 03:04:13 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (duplicate_decls): Fix up handling of builtins yet again.
(push_overloaded_decl): Ditto.
* cvt.c (convert): Don't look for void type conversion.
Mon May 9 18:05:41 1994 Jason Merrill (jason@deneb.cygnus.com)
* init.c (do_friend): Only do a pushdecl for friends, not
pushdecl_top_level.
Mon May 9 13:36:34 1994 Jim Wilson (wilson@sphagnum.cygnus.com)
* decl.c (lookup_name_current_level): Put empty statement after
the label OUT to make the code valid C.
Mon May 9 12:20:57 1994 Jason Merrill (jason@deneb.cygnus.com)
* typeck.c (build_binary_op_nodefault): Only complain about
comparing void * and a function pointer if void * is smaller.
Sun May 8 01:29:13 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (lookup_name_current_level): Move through temporary binding
levels.
* parse.y (already_scoped_stmt): Revive.
(simple_stmt): Use it again.
* decl.c (poplevel): Always call poplevel recursively if we're
dealing with a temporary binding level.
Sat May 7 10:52:28 1994 Mike Stump (mrs@cygnus.com)
* decl.c (finish_decl): Make sure we run cleanups for initial values
of decls. Cures memory leak.
* decl.c (expand_static_init): Ditto for static variables.
* decl2.c (finish_file): Ditto for globals.
Sat May 7 03:57:44 1994 Jason Merrill (jason@deneb.cygnus.com)
* typeck.c (commonparms): Don't complain about redefining default
args.
* decl.c (duplicate_decls): Don't complain twice about conflicting
function decls.
(decls_match): Don't look at default args.
(redeclaration_error_message): Complain about redefining default
args.
* call.c (build_overload_call_real): Also deal with guiding
declarations coming BEFORE the template decl.
* pt.c (unify): Allow different parms to have different
cv-qualifiers.
(unify): Allow trivial conversions on non-template parms.
Fri May 6 03:53:23 1994 Jason Merrill (jason@deneb.cygnus.com)
* pt.c (tsubst): Support OFFSET_TYPEs.
(unify): Ditto.
* decl2.c (finish_decl_parsing): Call push_nested_class with a type.
* init.c (build_offset_ref): Fix error message.
* search.c (lookup_field): Ditto.
* call.c (build_scoped_method_call): Pass binfo to
build_method_call.
* typeck.c (build_object_ref): Ditto.
* typeck2.c (binfo_or_else): Don't return a _TYPE.
* class.c (finish_struct): Don't complain about re-use of inherited
names or shadowing of type decls.
* decl.c (pushdecl_class_level): Ditto.
* decl.c (finish_enum): Set the type of all the enums.
* class.c (finish_struct): Don't get confused by access decls.
* cp-tree.h (TYPE_MAIN_DECL): New macro to get the _DECL for a
_TYPE. You can stop using TYPE_NAME for that now.
* parse.y: Lose doing_explicit (check $0 instead).
* gxx.gperf: 'template' now has a RID.
* lex.h (rid): Ditto.
* lex.c (init_lex): Set up the RID for 'template'.
* parse.y (type_specifier_seq): typed_typespecs or
nonempty_type_quals. Use it.
(handler_args): Fix bogus syntax.
(raise_identifier{,s}, optional_identifier): Lose.
* except.c (expand_start_catch_block): Use grokdeclarator to parse
the catch variable.
(init_exception_processing): The second argument to
__throw_type_match is ptr_type_node.
Fri May 6 07:18:54 1994 Chip Salzenberg (chip@fin)
[ change propagated from c-decl.c of snapshot 940429 ]
* cp/decl.c (finish_decl): Setting asmspec_tree should not
zero out the old RTL.
Fri May 6 01:25:38 1994 Mike Stump (mrs@cygnus.com) Fri May 6 01:25:38 1994 Mike Stump (mrs@cygnus.com)
Add alpha exception handling support to the compiler. Add alpha exception handling support to the compiler.
......
...@@ -2672,7 +2672,7 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -2672,7 +2672,7 @@ build_scoped_method_call (exp, scopes, name, parms)
} }
/* Call to a method. */ /* Call to a method. */
return build_method_call (decl, name, parms, NULL_TREE, return build_method_call (decl, name, parms, binfo,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
} }
return error_mark_node; return error_mark_node;
...@@ -3597,6 +3597,13 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -3597,6 +3597,13 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* From here on down, BASETYPE is the type that INSTANCE_PTR's /* From here on down, BASETYPE is the type that INSTANCE_PTR's
type (if it exists) is a pointer to. */ type (if it exists) is a pointer to. */
if (DECL_ABSTRACT_VIRTUAL_P (function)
&& instance == C_C_D
&& DECL_CONSTRUCTOR_P (current_function_decl)
&& ! (flags & LOOKUP_NONVIRTUAL)
&& value_member (function, get_abstract_virtuals (basetype)))
cp_error ("abstract virtual `%#D' called from constructor", function);
if (IS_SIGNATURE (basetype) && static_call_context) if (IS_SIGNATURE (basetype) && static_call_context)
{ {
cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference", cp_error ("cannot call signature member function `%T::%D' without signature pointer/reference",
...@@ -4046,22 +4053,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx) ...@@ -4046,22 +4053,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
TYPE_ARG_TYPES (TREE_TYPE (function)), TYPE_ARG_TYPES (TREE_TYPE (function)),
parms, &template_cost, 0); parms, &template_cost, 0);
if (i == 0) if (i == 0)
{ function = instantiate_template (function, targs);
struct candidate *cp2;
function = instantiate_template (function, targs);
/* Now check that the template instantiated for this is not
the same as a function that's in the list due to some
previous instantiation. */
cp2 = candidates;
while (cp2 != cp)
if (cp2->function == function)
break;
else
cp2 += 1;
if (cp2->function == function)
continue;
}
} }
if (TREE_CODE (function) == TEMPLATE_DECL) if (TREE_CODE (function) == TEMPLATE_DECL)
...@@ -4076,6 +4068,19 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx) ...@@ -4076,6 +4068,19 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
} }
else else
{ {
struct candidate *cp2;
/* Check that this decl is not the same as a function that's in
the list due to some template instantiation. */
cp2 = candidates;
while (cp2 != cp)
if (cp2->function == function)
break;
else
cp2 += 1;
if (cp2->function == function)
continue;
function = DECL_MAIN_VARIANT (function); function = DECL_MAIN_VARIANT (function);
/* Can't use alloca here, since result might be /* Can't use alloca here, since result might be
......
...@@ -2734,10 +2734,22 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -2734,10 +2734,22 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL) if (TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
{ {
tree name = DECL_NAME (x); tree name = DECL_NAME (x);
tree icv = name ? IDENTIFIER_CLASS_VALUE (name) : NULL_TREE; tree icv;
/* Don't complain about constructors. */ /* Don't get confused by access decls. */
if (icv && name != constructor_name (current_class_type)) if (name && TREE_CODE (name) == IDENTIFIER_NODE)
icv = IDENTIFIER_CLASS_VALUE (name);
else
icv = NULL_TREE;
if (icv
/* Don't complain about constructors. */
&& name != constructor_name (current_class_type)
/* Or inherited names. */
&& id_in_current_class (name)
/* Or shadowed tags. */
&& !(TREE_CODE (icv) == TYPE_DECL
&& DECL_CONTEXT (icv) == t))
{ {
cp_error_at ("declaration of identifier `%D' as `%+#D'", cp_error_at ("declaration of identifier `%D' as `%+#D'",
name, x); name, x);
......
...@@ -321,6 +321,9 @@ enum languages { lang_c, lang_cplusplus }; ...@@ -321,6 +321,9 @@ enum languages { lang_c, lang_cplusplus };
#define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) #define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
/* The _DECL for this _TYPE. */
#define TYPE_MAIN_DECL(NODE) (TYPE_NAME (NODE))
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t)) #define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE) #define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \ #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
...@@ -1723,6 +1726,24 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ ...@@ -1723,6 +1726,24 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
#define LOOKUP_NO_CONVERSION (512) #define LOOKUP_NO_CONVERSION (512)
#define LOOKUP_DESTRUCTOR (512) #define LOOKUP_DESTRUCTOR (512)
/* These flags are used by the conversion code.
CONV_IMPLICIT : Perform implicit conversions (standard and user-defined).
CONV_STATIC : Perform the explicit conversions for static_cast.
CONV_CONST : Perform the explicit conversions for const_cast.
CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast.
CONV_PRIVATE : Perform upcasts to private bases. */
#define CONV_IMPLICIT 1
#define CONV_STATIC 2
#define CONV_CONST 4
#define CONV_REINTERPRET 8
#define CONV_PRIVATE 16
#define CONV_STATIC_CAST (CONV_IMPLICIT | CONV_STATIC)
#define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
| CONV_REINTERPRET)
#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \
| CONV_REINTERPRET | CONV_PRIVATE)
/* Anatomy of a DECL_FRIENDLIST (which is a TREE_LIST): /* Anatomy of a DECL_FRIENDLIST (which is a TREE_LIST):
purpose = friend name (IDENTIFIER_NODE); purpose = friend name (IDENTIFIER_NODE);
value = TREE_LIST of FUNCTION_DECLS; value = TREE_LIST of FUNCTION_DECLS;
...@@ -1790,7 +1811,7 @@ extern void print_class_statistics PROTO((void)); ...@@ -1790,7 +1811,7 @@ extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void)); extern void maybe_push_cache_obstack PROTO((void));
/* in cvt.c */ /* in cvt.c */
extern tree convert_to_reference PROTO((tree, tree, tree, tree, int, char *, int, int)); extern tree convert_to_reference PROTO((tree, tree, int, int, tree));
extern tree convert_from_reference PROTO((tree)); extern tree convert_from_reference PROTO((tree));
extern tree convert_to_aggr PROTO((tree, tree, char **, int)); extern tree convert_to_aggr PROTO((tree, tree, char **, int));
extern tree convert_pointer_to PROTO((tree, tree)); extern tree convert_pointer_to PROTO((tree, tree));
......
...@@ -47,6 +47,8 @@ extern struct obstack permanent_obstack; ...@@ -47,6 +47,8 @@ extern struct obstack permanent_obstack;
extern int current_class_depth; extern int current_class_depth;
extern tree cleanups_this_call;
/* Stack of places to restore the search obstack back to. */ /* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like /* Obstack used for remembering local class declarations (like
...@@ -1077,7 +1079,7 @@ poplevel (keep, reverse, functionbody) ...@@ -1077,7 +1079,7 @@ poplevel (keep, reverse, functionbody)
} }
/* Take care of compiler's internal binding structures. */ /* Take care of compiler's internal binding structures. */
if (tmp == 2 && class_binding_level) if (tmp == 2)
{ {
#if 0 #if 0
/* We did not call push_momentary for this /* We did not call push_momentary for this
...@@ -1976,7 +1978,7 @@ decls_match (newdecl, olddecl) ...@@ -1976,7 +1978,7 @@ decls_match (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl); TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
} }
else else
types_match = compparms (p1, p2, 1); types_match = compparms (p1, p2, 3);
} }
else else
types_match = 0; types_match = 0;
...@@ -2114,31 +2116,44 @@ duplicate_decls (newdecl, olddecl) ...@@ -2114,31 +2116,44 @@ duplicate_decls (newdecl, olddecl)
after implicit decl. */ after implicit decl. */
; ;
else if (TREE_CODE (olddecl) == FUNCTION_DECL else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)) && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
&& DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl))
/* Redeclaring a builtin as another function is handled in
push_overloaded_decl. */
{ {
/* If you declare a built-in or predefined function name as static, /* If you declare a built-in or predefined function name as static,
the old definition is overridden, the old definition is overridden, but optionally warn this was a
but optionally warn this was a bad choice of name. */ bad choice of name. Ditto for overloads. */
if (! TREE_PUBLIC (newdecl)) if (! TREE_PUBLIC (newdecl)
if (warn_shadow) || (TREE_CODE (newdecl) == FUNCTION_DECL
cp_warning ("shadowing %s function `%#D'", && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
DECL_BUILT_IN (olddecl) ? "built-in" : "library", {
newdecl); if (warn_shadow)
/* Likewise, if the built-in is not ansi, then programs can override cp_warning ("shadowing %s function `%#D'",
it even globally without an error. */ DECL_BUILT_IN (olddecl) ? "built-in" : "library",
else if (! DECL_BUILT_IN (olddecl)) olddecl);
cp_warning ("library function `%#D' redeclared as non-function `%#D'", /* Discard the old built-in function. */
olddecl, newdecl); return 0;
else }
else if (! types_match)
{ {
if (TREE_CODE (newdecl) != FUNCTION_DECL)
{
/* If the built-in is not ansi, then programs can override
it even globally without an error. */
if (! DECL_BUILT_IN (olddecl))
cp_warning ("library function `%#D' redeclared as non-function `%#D'",
olddecl, newdecl);
else
{
cp_error ("declaration of `%#D'", newdecl);
cp_error ("conflicts with built-in declaration `%#D'",
olddecl);
}
return 0;
}
cp_warning ("declaration of `%#D'", newdecl); cp_warning ("declaration of `%#D'", newdecl);
cp_warning ("conflicts with built-in declaration `%#D'", cp_warning ("conflicts with built-in declaration `%#D'",
olddecl); olddecl);
} }
return 0;
} }
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{ {
...@@ -2185,7 +2200,7 @@ duplicate_decls (newdecl, olddecl) ...@@ -2185,7 +2200,7 @@ duplicate_decls (newdecl, olddecl)
} }
/* Already complained about this, so don't do so again. */ /* Already complained about this, so don't do so again. */
if (current_class_type == NULL_TREE else if (current_class_type == NULL_TREE
|| IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
{ {
/* Since we're doing this before finish_struct can set the /* Since we're doing this before finish_struct can set the
...@@ -3082,7 +3097,12 @@ pushdecl_class_level (x) ...@@ -3082,7 +3097,12 @@ pushdecl_class_level (x)
members are checked in finish_struct. */ members are checked in finish_struct. */
tree icv = IDENTIFIER_CLASS_VALUE (name); tree icv = IDENTIFIER_CLASS_VALUE (name);
if (icv) if (icv
/* Don't complain about inherited names. */
&& id_in_current_class (name)
/* Or shadowed tags. */
&& !(TREE_CODE (icv) == TYPE_DECL
&& DECL_CONTEXT (icv) == current_class_type))
{ {
cp_error ("declaration of identifier `%D' as `%#D'", name, x); cp_error ("declaration of identifier `%D' as `%#D'", name, x);
cp_error_at ("conflicts with previous use in class as `%#D'", cp_error_at ("conflicts with previous use in class as `%#D'",
...@@ -3186,23 +3206,18 @@ push_overloaded_decl (decl, forgettable) ...@@ -3186,23 +3206,18 @@ push_overloaded_decl (decl, forgettable)
{ {
old = IDENTIFIER_GLOBAL_VALUE (orig_name); old = IDENTIFIER_GLOBAL_VALUE (orig_name);
if (old && TREE_CODE (old) == FUNCTION_DECL if (old && TREE_CODE (old) == FUNCTION_DECL
&& DECL_ARTIFICIAL (old)
&& (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
{ {
if (! decls_match (decl, old) if (duplicate_decls (decl, old))
&& (DECL_LANGUAGE (decl) == lang_c return old;
|| compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
TYPE_ARG_TYPES (TREE_TYPE (old)), 2)))
{
cp_warning ("declaration of `%#D'", decl);
cp_warning ("conflicts with built-in declaration `%#D'", old);
}
old = NULL_TREE; old = NULL_TREE;
} }
} }
else else
{ {
old = IDENTIFIER_LOCAL_VALUE (orig_name); old = IDENTIFIER_LOCAL_VALUE (orig_name);
if (! purpose_member (orig_name, current_binding_level->shadowed)) if (! purpose_member (orig_name, current_binding_level->shadowed))
{ {
current_binding_level->shadowed current_binding_level->shadowed
...@@ -3355,6 +3370,18 @@ redeclaration_error_message (newdecl, olddecl) ...@@ -3355,6 +3370,18 @@ redeclaration_error_message (newdecl, olddecl)
else else
return "redefinition of `%#D'"; return "redefinition of `%#D'";
} }
{
tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
for (; t1; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
return "duplicate default arguments given for `%#D'";
}
return 0; return 0;
} }
else if (TREE_CODE (newdecl) == TEMPLATE_DECL) else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
...@@ -3990,9 +4017,19 @@ lookup_name_current_level (name) ...@@ -3990,9 +4017,19 @@ lookup_name_current_level (name)
} }
else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE) else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE)
{ {
for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) struct binding_level *b = current_binding_level;
if (DECL_NAME (t) == name) while (1)
break; {
for (t = b->names; t; t = TREE_CHAIN (t))
if (DECL_NAME (t) == name)
goto out;
if (b->keep == 2)
b = b->level_chain;
else
break;
}
out:
;
} }
return t; return t;
...@@ -5559,25 +5596,14 @@ grok_reference_init (decl, type, init, cleanupp) ...@@ -5559,25 +5596,14 @@ grok_reference_init (decl, type, init, cleanupp)
} }
/* OK, can we generate a reference then? */ /* OK, can we generate a reference then? */
else if ((actual_init = convert_to_reference else if ((actual_init = convert_to_reference
(decl, type, init, 0, 0, "initialization", 0, (type, init, CONV_IMPLICIT,
LOOKUP_SPECULATIVELY|LOOKUP_NORMAL))) LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
{ {
if (actual_init == error_mark_node) if (actual_init == error_mark_node)
goto fail; goto fail;
init = actual_init; init = actual_init;
is_reference = 1; is_reference = 1;
}
/* OK, try going through a temporary. */
else if ((actual_init = convert_to_reference
(error_mark_node, type, init, 0, 0, "initialization",
0, LOOKUP_NORMAL)))
{
if (actual_init == error_mark_node)
goto fail;
init = actual_init;
is_reference = 1;
if (TREE_CODE (init) == WITH_CLEANUP_EXPR) if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
{ {
...@@ -5705,12 +5731,9 @@ finish_decl (decl, init, asmspec_tree, need_pop) ...@@ -5705,12 +5731,9 @@ finish_decl (decl, init, asmspec_tree, need_pop)
return; return;
} }
/* If a name was specified, get the string. */
if (asmspec_tree) if (asmspec_tree)
{
asmspec = TREE_STRING_POINTER (asmspec_tree); asmspec = TREE_STRING_POINTER (asmspec_tree);
/* Zero out old RTL, since we will rewrite it. */
DECL_RTL (decl) = NULL_RTX;
}
/* If the type of the thing we are declaring either has /* If the type of the thing we are declaring either has
a constructor, or has a virtual function table pointer, a constructor, or has a virtual function table pointer,
...@@ -6276,6 +6299,7 @@ finish_decl (decl, init, asmspec_tree, need_pop) ...@@ -6276,6 +6299,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
} }
else if (! toplev) else if (! toplev)
{ {
tree old_cleanups = cleanups_this_call;
/* This is a declared decl which must live until the /* This is a declared decl which must live until the
end of the binding contour. It may need a cleanup. */ end of the binding contour. It may need a cleanup. */
...@@ -6335,6 +6359,8 @@ finish_decl (decl, init, asmspec_tree, need_pop) ...@@ -6335,6 +6359,8 @@ finish_decl (decl, init, asmspec_tree, need_pop)
decl); decl);
} }
} }
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to (old_cleanups);
} }
finish_end0: finish_end0:
...@@ -6404,6 +6430,8 @@ expand_static_init (decl, init) ...@@ -6404,6 +6430,8 @@ expand_static_init (decl, init)
tree init; tree init;
{ {
tree oldstatic = value_member (decl, static_aggregates); tree oldstatic = value_member (decl, static_aggregates);
tree old_cleanups;
if (oldstatic) if (oldstatic)
{ {
if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
...@@ -6422,6 +6450,7 @@ expand_static_init (decl, init) ...@@ -6422,6 +6450,7 @@ expand_static_init (decl, init)
rest_of_decl_compilation (temp, NULL_PTR, 0, 0); rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
expand_start_cond (build_binary_op (EQ_EXPR, temp, expand_start_cond (build_binary_op (EQ_EXPR, temp,
integer_zero_node, 1), 0); integer_zero_node, 1), 0);
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)))
{ {
...@@ -6430,6 +6459,8 @@ expand_static_init (decl, init) ...@@ -6430,6 +6459,8 @@ expand_static_init (decl, init)
} }
else else
expand_assignment (decl, init, 0, 0); expand_assignment (decl, init, 0, 0);
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to (old_cleanups);
expand_end_cond (); expand_end_cond ();
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
{ {
...@@ -10235,6 +10266,7 @@ finish_enum (enumtype, values) ...@@ -10235,6 +10266,7 @@ finish_enum (enumtype, values)
else if (value < minvalue) else if (value < minvalue)
minvalue = value; minvalue = value;
TREE_TYPE (TREE_VALUE (pair)) = enumtype; TREE_TYPE (TREE_VALUE (pair)) = enumtype;
TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype;
} }
} }
...@@ -11968,3 +12000,10 @@ revert_static_member_fn (decl, fn, argtypes) ...@@ -11968,3 +12000,10 @@ revert_static_member_fn (decl, fn, argtypes)
if (argtypes) if (argtypes)
*argtypes = args; *argtypes = args;
} }
int
id_in_current_class (id)
tree id;
{
return !!purpose_member (id, class_binding_level->class_shadowed);
}
...@@ -37,6 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -37,6 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern tree grokdeclarator (); extern tree grokdeclarator ();
extern tree get_file_function_name (); extern tree get_file_function_name ();
extern tree cleanups_this_call;
static void grok_function_init (); static void grok_function_init ();
/* A list of virtual function tables we must make sure to write out. */ /* A list of virtual function tables we must make sure to write out. */
...@@ -362,6 +363,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = ...@@ -362,6 +363,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"huge-objects", &flag_huge_objects, 1}, {"huge-objects", &flag_huge_objects, 1},
{"conserve-space", &flag_conserve_space, 1}, {"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1}, {"vtable-thunks", &flag_vtable_thunks, 1},
{"short-temps", &flag_short_temps, 1},
}; };
/* Decode the string P as a language-specific option. /* Decode the string P as a language-specific option.
...@@ -2595,6 +2597,7 @@ finish_file () ...@@ -2595,6 +2597,7 @@ finish_file ()
{ {
tree decl = TREE_VALUE (vars); tree decl = TREE_VALUE (vars);
tree init = TREE_PURPOSE (vars); tree init = TREE_PURPOSE (vars);
tree old_cleanups = cleanups_this_call;
/* If this was a static attribute within some function's scope, /* If this was a static attribute within some function's scope,
then don't initialize it here. Also, don't bother then don't initialize it here. Also, don't bother
...@@ -2684,6 +2687,8 @@ finish_file () ...@@ -2684,6 +2687,8 @@ finish_file ()
; ;
else my_friendly_abort (22); else my_friendly_abort (22);
vars = TREE_CHAIN (vars); vars = TREE_CHAIN (vars);
/* Cleanup any temporaries needed for the initial value. */
expand_cleanups_to (old_cleanups);
} }
expand_end_bindings (getdecls(), 1, 0); expand_end_bindings (getdecls(), 1, 0);
...@@ -2936,7 +2941,7 @@ finish_decl_parsing (decl) ...@@ -2936,7 +2941,7 @@ finish_decl_parsing (decl)
TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0)); TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
return decl; return decl;
case SCOPE_REF: case SCOPE_REF:
push_nested_class (TREE_OPERAND (decl, 0), 3); push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3);
TREE_COMPLEXITY (decl) = current_class_depth; TREE_COMPLEXITY (decl) = current_class_depth;
return decl; return decl;
case ARRAY_REF: case ARRAY_REF:
......
...@@ -35,11 +35,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -35,11 +35,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
tree builtin_return_address_fndecl; tree builtin_return_address_fndecl;
/* Define at your own risk! */ /* Define at your own risk! */
#ifndef CROSS_COMPILE
#ifdef sun #ifdef sun
#ifdef sparc #ifdef sparc
#define TRY_NEW_EH #define TRY_NEW_EH
#endif #endif
#endif #endif
#endif
#ifndef TRY_NEW_EH #ifndef TRY_NEW_EH
...@@ -97,8 +99,8 @@ expand_end_all_catch () ...@@ -97,8 +99,8 @@ expand_end_all_catch ()
} }
void void
expand_start_catch_block (typename, identifier) expand_start_catch_block (declspecs, declarator)
tree typename, identifier; tree declspecs, declarator;
{ {
} }
...@@ -409,7 +411,6 @@ exception_section () ...@@ -409,7 +411,6 @@ exception_section ()
extern rtx emit_insn PROTO((rtx)); extern rtx emit_insn PROTO((rtx));
extern rtx gen_nop PROTO(()); extern rtx gen_nop PROTO(());
extern void do_unwind PROTO((rtx));
/* local globals for function calls /* local globals for function calls
====================================================================== */ ====================================================================== */
...@@ -808,7 +809,7 @@ init_exception_processing () ...@@ -808,7 +809,7 @@ init_exception_processing ()
catch_match_fndecl = catch_match_fndecl =
define_function ("__throw_type_match", define_function ("__throw_type_match",
build_function_type (integer_type_node, build_function_type (integer_type_node,
tree_cons (NULL_TREE, string_type_node, tree_cons (NULL_TREE, string_type_node, void_list_node))), tree_cons (NULL_TREE, string_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node))),
NOT_BUILT_IN, NOT_BUILT_IN,
pushdecl, pushdecl,
0); 0);
...@@ -1088,24 +1089,27 @@ expand_leftover_cleanups () ...@@ -1088,24 +1089,27 @@ expand_leftover_cleanups ()
} }
} }
/* call this to start a catch block. Typename is the typename, and identifier /* call this to start a catch block. Typename is the typename, and identifier
is the variable to place the object in or NULL if the variable doesn't is the variable to place the object in or NULL if the variable doesn't
matter. If typename is NULL, that means its a "catch (...)" or catch matter. If typename is NULL, that means its a "catch (...)" or catch
everything. In that case we don't need to do any type checking. everything. In that case we don't need to do any type checking.
(ie: it ends up as the "else" clause rather than an "else if" clause) */ (ie: it ends up as the "else" clause rather than an "else if" clause) */
void void
expand_start_catch_block (typename, identifier) expand_start_catch_block (declspecs, declarator)
tree typename, identifier; tree declspecs, declarator;
{ {
rtx false_label_rtx; rtx false_label_rtx;
tree type; tree type;
tree decl;
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
if (typename) if (declspecs)
type = groktypename (typename); {
decl = grokdeclarator (declarator, declspecs, PARM, 0, NULL_TREE);
type = TREE_TYPE (decl);
}
else else
type = NULL_TREE; type = NULL_TREE;
......
...@@ -35,6 +35,7 @@ char, TYPESPEC, RID_CHAR, ...@@ -35,6 +35,7 @@ char, TYPESPEC, RID_CHAR,
class, AGGR, RID_CLASS, class, AGGR, RID_CLASS,
classof, CLASSOF, NORID, classof, CLASSOF, NORID,
const, TYPE_QUAL, RID_CONST, const, TYPE_QUAL, RID_CONST,
const_cast, CONST_CAST, NORID,
continue, CONTINUE, NORID, continue, CONTINUE, NORID,
default, DEFAULT, NORID, default, DEFAULT, NORID,
delete, DELETE, NORID, delete, DELETE, NORID,
...@@ -61,6 +62,7 @@ private, VISSPEC, RID_PRIVATE, ...@@ -61,6 +62,7 @@ private, VISSPEC, RID_PRIVATE,
protected, VISSPEC, RID_PROTECTED, protected, VISSPEC, RID_PROTECTED,
public, VISSPEC, RID_PUBLIC, public, VISSPEC, RID_PUBLIC,
register, SCSPEC, RID_REGISTER, register, SCSPEC, RID_REGISTER,
reinterpret_cast, REINTERPRET_CAST, NORID,
return, RETURN, NORID, return, RETURN, NORID,
short, TYPESPEC, RID_SHORT, short, TYPESPEC, RID_SHORT,
signature, AGGR, RID_SIGNATURE /* Extension */, signature, AGGR, RID_SIGNATURE /* Extension */,
...@@ -68,11 +70,12 @@ signed, TYPESPEC, RID_SIGNED, ...@@ -68,11 +70,12 @@ signed, TYPESPEC, RID_SIGNED,
sigof, SIGOF, NORID /* Extension */, sigof, SIGOF, NORID /* Extension */,
sizeof, SIZEOF, NORID, sizeof, SIZEOF, NORID,
static, SCSPEC, RID_STATIC, static, SCSPEC, RID_STATIC,
static_cast, STATIC_CAST, NORID,
struct, AGGR, RID_RECORD, struct, AGGR, RID_RECORD,
switch, SWITCH, NORID, switch, SWITCH, NORID,
this, THIS, NORID, this, THIS, NORID,
throw, THROW, NORID, throw, THROW, NORID,
template, TEMPLATE, NORID, template, TEMPLATE, RID_TEMPLATE,
try, TRY, NORID, try, TRY, NORID,
typedef, SCSPEC, RID_TYPEDEF, typedef, SCSPEC, RID_TYPEDEF,
typeof, TYPEOF, NORID, typeof, TYPEOF, NORID,
......
/* C code produced by gperf version 2.5 (GNU C++ version) */ /* C code produced by gperf version 2.5 (GNU C++ version) */
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf */ /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ /deneb/blob/jason/g++/small/devo/gcc/cp/gxx.gperf */
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */
struct resword { char *name; short token; enum rid rid;}; struct resword { char *name; short token; enum rid rid;};
#define TOTAL_KEYWORDS 80 #define TOTAL_KEYWORDS 83
#define MIN_WORD_LENGTH 2 #define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 13 #define MAX_WORD_LENGTH 16
#define MIN_HASH_VALUE 4 #define MIN_HASH_VALUE 4
#define MAX_HASH_VALUE 166 #define MAX_HASH_VALUE 170
/* maximum key range = 163, duplicates = 0 */ /* maximum key range = 167, duplicates = 0 */
#ifdef __GNUC__ #ifdef __GNUC__
inline inline
...@@ -20,19 +20,19 @@ hash (str, len) ...@@ -20,19 +20,19 @@ hash (str, len)
{ {
static unsigned char asso_values[] = static unsigned char asso_values[] =
{ {
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
167, 167, 167, 167, 167, 0, 167, 36, 6, 60, 171, 171, 171, 171, 171, 0, 171, 62, 5, 65,
17, 0, 16, 5, 41, 38, 167, 11, 22, 7, 27, 0, 18, 7, 10, 48, 171, 1, 30, 7,
26, 0, 4, 167, 22, 0, 4, 44, 19, 8, 79, 0, 33, 171, 18, 0, 4, 26, 13, 0,
5, 18, 167, 167, 167, 167, 167, 167, 1, 24, 171, 171, 171, 171, 171, 171,
}; };
register int hval = len; register int hval = len;
...@@ -68,103 +68,117 @@ is_reserved_word (str, len) ...@@ -68,103 +68,117 @@ is_reserved_word (str, len)
{"",}, {"",}, {"",}, {"",},
{"__asm__", GCC_ASM_KEYWORD, NORID}, {"__asm__", GCC_ASM_KEYWORD, NORID},
{"this", THIS, NORID,}, {"this", THIS, NORID,},
{"goto", GOTO, NORID,}, {"throw", THROW, NORID,},
{"__headof__", HEADOF, NORID}, {"__headof__", HEADOF, NORID},
{"",}, {"goto", GOTO, NORID,},
{"__asm", GCC_ASM_KEYWORD, NORID}, {"__asm", GCC_ASM_KEYWORD, NORID},
{"__const__", TYPE_QUAL, RID_CONST}, {"__const__", TYPE_QUAL, RID_CONST},
{"__volatile", TYPE_QUAL, RID_VOLATILE}, {"__volatile", TYPE_QUAL, RID_VOLATILE},
{"__const", TYPE_QUAL, RID_CONST}, {"__const", TYPE_QUAL, RID_CONST},
{"__volatile__", TYPE_QUAL, RID_VOLATILE}, {"__volatile__", TYPE_QUAL, RID_VOLATILE},
{"throw", THROW, NORID,}, {"",},
{"enum", ENUM, NORID,}, {"enum", ENUM, NORID,},
{"do", DO, NORID,}, {"static_cast", STATIC_CAST, NORID,},
{"template", TEMPLATE, NORID,}, {"switch", SWITCH, NORID,},
{"",}, {"",},
{"sigof", SIGOF, NORID /* Extension */,}, {"sigof", SIGOF, NORID /* Extension */,},
{"sizeof", SIZEOF, NORID,}, {"sizeof", SIZEOF, NORID,},
{"delete", DELETE, NORID,}, {"",},
{"__headof", HEADOF, NORID}, {"__headof", HEADOF, NORID},
{"try", TRY, NORID,}, {"short", TYPESPEC, RID_SHORT,},
{"typeof", TYPEOF, NORID,}, {"typeof", TYPEOF, NORID,},
{"typeid", TYPEID, NORID,}, {"do", DO, NORID,},
{"",},
{"try", TRY, NORID,},
{"",},
{"delete", DELETE, NORID,},
{"__typeof__", TYPEOF, NORID}, {"__typeof__", TYPEOF, NORID},
{"while", WHILE, NORID,},
{"struct", AGGR, RID_RECORD,},
{"typeid", TYPEID, NORID,},
{"double", TYPESPEC, RID_DOUBLE,}, {"double", TYPESPEC, RID_DOUBLE,},
{"private", VISSPEC, RID_PRIVATE,}, {"for", FOR, NORID,},
{"short", TYPESPEC, RID_SHORT,},
{"extern", SCSPEC, RID_EXTERN,},
{"__classof__", CLASSOF, NORID},
{"",}, {"",},
{"while", WHILE, NORID,}, {"__classof__", CLASSOF, NORID},
{"",}, {"",},
{"operator", OPERATOR, NORID,},
{"",}, {"",},
{"typedef", SCSPEC, RID_TYPEDEF,},
{"long", TYPESPEC, RID_LONG,}, {"long", TYPESPEC, RID_LONG,},
{"new", NEW, NORID,}, {"template", TEMPLATE, RID_TEMPLATE,},
{"protected", VISSPEC, RID_PROTECTED,},
{"friend", SCSPEC, RID_FRIEND,},
{"auto", SCSPEC, RID_AUTO,},
{"for", FOR, NORID,},
{"__typeof", TYPEOF, NORID}, {"__typeof", TYPEOF, NORID},
{"typedef", SCSPEC, RID_TYPEDEF,}, {"friend", SCSPEC, RID_FRIEND,},
{"__extension__", EXTENSION, NORID}, {"",},
{"private", VISSPEC, RID_PRIVATE,},
{"",},
{"int", TYPESPEC, RID_INT,}, {"int", TYPESPEC, RID_INT,},
{"asm", ASM_KEYWORD, NORID,}, {"",},
{"__classof", CLASSOF, NORID}, {"__classof", CLASSOF, NORID},
{"__signed__", TYPESPEC, RID_SIGNED}, {"__signed__", TYPESPEC, RID_SIGNED},
{"signed", TYPESPEC, RID_SIGNED,}, {"",}, {"",},
{"mutable", SCSPEC, RID_MUTABLE,}, {"headof", HEADOF, NORID,},
{"switch", SWITCH, NORID,}, {"",},
{"operator", OPERATOR, NORID,},
{"__attribute", ATTRIBUTE, NORID}, {"__attribute", ATTRIBUTE, NORID},
{"struct", AGGR, RID_RECORD,}, {"",},
{"__attribute__", ATTRIBUTE, NORID}, {"__attribute__", ATTRIBUTE, NORID},
{"auto", SCSPEC, RID_AUTO,},
{"",},
{"if", IF, NORID,}, {"if", IF, NORID,},
{"void", TYPESPEC, RID_VOID,},
{"break", BREAK, NORID,},
{"__alignof__", ALIGNOF, NORID},
{"__inline", SCSPEC, RID_INLINE},
{"float", TYPESPEC, RID_FLOAT,},
{"__inline__", SCSPEC, RID_INLINE},
{"__signed", TYPESPEC, RID_SIGNED},
{"case", CASE, NORID,}, {"case", CASE, NORID,},
{"class", AGGR, RID_CLASS,}, {"class", AGGR, RID_CLASS,},
{"",}, {"void", TYPESPEC, RID_VOID,},
{"__label__", LABEL, NORID}, {"asm", ASM_KEYWORD, NORID,},
{"default", DEFAULT, NORID,}, {"break", BREAK, NORID,},
{"const", TYPE_QUAL, RID_CONST,}, {"const", TYPE_QUAL, RID_CONST,},
{"static", SCSPEC, RID_STATIC,}, {"static", SCSPEC, RID_STATIC,},
{"",}, {"",}, {"mutable", SCSPEC, RID_MUTABLE,},
{"__alignof", ALIGNOF, NORID}, {"protected", VISSPEC, RID_PROTECTED,},
{"",}, {"",}, {"",}, {"",},
{"new", NEW, NORID,},
{"__signed", TYPESPEC, RID_SIGNED},
{"virtual", SCSPEC, RID_VIRTUAL,}, {"virtual", SCSPEC, RID_VIRTUAL,},
{"union", AGGR, RID_UNION,}, {"extern", SCSPEC, RID_EXTERN,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"signature", AGGR, RID_SIGNATURE /* Extension */,}, {"float", TYPESPEC, RID_FLOAT,},
{"headof", HEADOF, NORID,}, {"",}, {"",},
{"",},
{"inline", SCSPEC, RID_INLINE,},
{"overload", OVERLOAD, NORID,},
{"",},
{"volatile", TYPE_QUAL, RID_VOLATILE,},
{"",}, {"",}, {"",}, {"",},
{"register", SCSPEC, RID_REGISTER,}, {"register", SCSPEC, RID_REGISTER,},
{"",}, {"__extension__", EXTENSION, NORID},
{"public", VISSPEC, RID_PUBLIC,},
{"",}, {"",}, {"",}, {"",},
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
{"",}, {"",}, {"",}, {"",},
{"__label__", LABEL, NORID},
{"inline", SCSPEC, RID_INLINE,},
{"continue", CONTINUE, NORID,},
{"default", DEFAULT, NORID,},
{"char", TYPESPEC, RID_CHAR,},
{"",}, {"",}, {"",}, {"",},
{"return", RETURN, NORID,},
{"classof", CLASSOF, NORID,}, {"classof", CLASSOF, NORID,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"unsigned", TYPESPEC, RID_UNSIGNED,}, {"unsigned", TYPESPEC, RID_UNSIGNED,},
{"char", TYPESPEC, RID_CHAR,}, {"union", AGGR, RID_UNION,},
{"",},
{"signed", TYPESPEC, RID_SIGNED,},
{"volatile", TYPE_QUAL, RID_VOLATILE,},
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
{"overload", OVERLOAD, NORID,},
{"",}, {"",}, {"",}, {"",},
{"__alignof__", ALIGNOF, NORID},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"return", RETURN, NORID,},
{"",}, {"",}, {"",}, {"",},
{"public", VISSPEC, RID_PUBLIC,},
{"reinterpret_cast", REINTERPRET_CAST, NORID,},
{"__alignof", ALIGNOF, NORID},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"continue", CONTINUE, NORID,}, {"const_cast", CONST_CAST, NORID,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"catch", CATCH, NORID,},
{"",}, {"",}, {"",},
{"dynamic_cast", DYNAMIC_CAST, NORID,},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",},
{"catch", CATCH, NORID,}, {"__inline", SCSPEC, RID_INLINE},
{"",},
{"__inline__", SCSPEC, RID_INLINE},
{"",},
{"dynamic_cast", DYNAMIC_CAST, NORID,},
}; };
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
......
...@@ -643,7 +643,7 @@ emit_base_init (t, immediately) ...@@ -643,7 +643,7 @@ emit_base_init (t, immediately)
/* member could be, for example, a CONST_DECL for an enumerated /* member could be, for example, a CONST_DECL for an enumerated
tag; we don't want to try to initialize that, since it already tag; we don't want to try to initialize that, since it already
has a value. */ has a value. */
if (TREE_CODE (member) != FIELD_DECL) if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
continue; continue;
name = DECL_NAME (member); name = DECL_NAME (member);
...@@ -2087,8 +2087,7 @@ build_offset_ref (cname, name) ...@@ -2087,8 +2087,7 @@ build_offset_ref (cname, name)
if (t == NULL_TREE) if (t == NULL_TREE)
{ {
cp_error ("`%D' is not a member of type `%T'", name, cp_error ("`%D' is not a member of type `%T'", name, type);
IDENTIFIER_TYPE_VALUE (cname));
return error_mark_node; return error_mark_node;
} }
...@@ -2748,7 +2747,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals) ...@@ -2748,7 +2747,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* We can call pushdecl here, because the TREE_CHAIN of this /* We can call pushdecl here, because the TREE_CHAIN of this
FUNCTION_DECL is not needed for other purposes. */ FUNCTION_DECL is not needed for other purposes. */
decl = pushdecl_top_level (decl); decl = pushdecl (decl);
make_decl_rtl (decl, NULL_PTR, 1); make_decl_rtl (decl, NULL_PTR, 1);
add_friend (current_class_type, decl); add_friend (current_class_type, decl);
......
...@@ -662,6 +662,9 @@ init_lex () ...@@ -662,6 +662,9 @@ init_lex ()
ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
/* This is for ANSI C++. */ /* This is for ANSI C++. */
ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
......
...@@ -65,6 +65,7 @@ enum rid ...@@ -65,6 +65,7 @@ enum rid
RID_RAISES, RID_RAISES,
RID_AUTO, RID_AUTO,
RID_MUTABLE, RID_MUTABLE,
RID_TEMPLATE,
RID_SIGNATURE, RID_SIGNATURE,
/* Before adding enough to get up to 64, the RIDBIT_* macros /* Before adding enough to get up to 64, the RIDBIT_* macros
will have to be changed a little. */ will have to be changed a little. */
......
...@@ -80,8 +80,6 @@ void yyerror (); ...@@ -80,8 +80,6 @@ void yyerror ();
error message if the user supplies an empty conditional expression. */ error message if the user supplies an empty conditional expression. */
static char *cond_stmt_keyword; static char *cond_stmt_keyword;
static int doing_explicit;
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */ /* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec; int have_extern_spec;
int used_extern_spec; int used_extern_spec;
...@@ -153,7 +151,7 @@ empty_parms () ...@@ -153,7 +151,7 @@ empty_parms ()
%token <itype> VISSPEC %token <itype> VISSPEC
%token DELETE NEW OVERLOAD THIS OPERATOR %token DELETE NEW OVERLOAD THIS OPERATOR
%token LEFT_RIGHT TEMPLATE %token LEFT_RIGHT TEMPLATE
%token TYPEID DYNAMIC_CAST %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
%token <itype> SCOPE %token <itype> SCOPE
/* Define the operator tokens and their precedences. /* Define the operator tokens and their precedences.
...@@ -197,7 +195,7 @@ empty_parms () ...@@ -197,7 +195,7 @@ empty_parms ()
%type <code> unop %type <code> unop
%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
%type <ttype> optional_identifier paren_expr_or_null nontrivial_exprlist %type <ttype> paren_expr_or_null nontrivial_exprlist
%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
%type <ttype> typed_declspecs reserved_declspecs %type <ttype> typed_declspecs reserved_declspecs
%type <ttype> typed_typespecs reserved_typespecquals %type <ttype> typed_typespecs reserved_typespecquals
...@@ -242,7 +240,7 @@ empty_parms () ...@@ -242,7 +240,7 @@ empty_parms ()
%type <ttype> class_head base_class_list %type <ttype> class_head base_class_list
%type <itype> base_class_access_list %type <itype> base_class_access_list
%type <ttype> base_class maybe_base_class_list base_class.1 %type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers %type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers
%type <ttype> component_declarator0 %type <ttype> component_declarator0
%type <ttype> forhead.1 operator_name %type <ttype> forhead.1 operator_name
%type <ttype> object aggr %type <ttype> object aggr
...@@ -261,7 +259,7 @@ empty_parms () ...@@ -261,7 +259,7 @@ empty_parms ()
%type <ttype> qualified_type_name complete_type_name notype_identifier %type <ttype> qualified_type_name complete_type_name notype_identifier
%type <ttype> complex_type_name nested_name_specifier_1 %type <ttype> complex_type_name nested_name_specifier_1
%type <itype> nomods_initdecls nomods_initdcl0 %type <itype> nomods_initdecls nomods_initdcl0
%type <ttype> new_initializer new_placement specialization %type <ttype> new_initializer new_placement specialization type_specifier_seq
/* in order to recognize aggr tags as defining and thus shadowing. */ /* in order to recognize aggr tags as defining and thus shadowing. */
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
...@@ -538,7 +536,6 @@ datadef: ...@@ -538,7 +536,6 @@ datadef:
| declmods ';' | declmods ';'
{ pedwarn ("empty declaration"); } { pedwarn ("empty declaration"); }
| explicit_instantiation ';' | explicit_instantiation ';'
{ doing_explicit = 0; }
| typed_declspecs ';' | typed_declspecs ';'
{ {
tree t = $<ttype>$; tree t = $<ttype>$;
...@@ -775,16 +772,11 @@ identifier_defn: ...@@ -775,16 +772,11 @@ identifier_defn:
| PTYPENAME_DEFN | PTYPENAME_DEFN
; ;
do_explicit: TEMPLATE %prec EMPTY
{ doing_explicit = 1; }
;
explicit_instantiation: explicit_instantiation:
do_explicit specialization template_instantiation TEMPLATE specialization template_instantiation
{ do_type_instantiation ($3 ? $3 : $2); } { do_type_instantiation ($3 ? $3 : $2); }
| do_explicit typed_declspecs declarator | TEMPLATE typed_declspecs declarator
{ do_function_instantiation ($2, $3); } { do_function_instantiation ($2, $3); }
| do_explicit error
; ;
template_type: template_type:
...@@ -925,7 +917,7 @@ xcond: ...@@ -925,7 +917,7 @@ xcond:
; ;
condition: condition:
typed_typespecs declarator maybe_raises maybeasm maybe_attribute '=' type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '='
{ { { {
tree d; tree d;
for (d = getdecls (); d; d = TREE_CHAIN (d)) for (d = getdecls (); d; d = TREE_CHAIN (d))
...@@ -953,6 +945,17 @@ condition: ...@@ -953,6 +945,17 @@ condition:
| expr | expr
; ;
already_scoped_stmt:
'{' '}'
{ finish_stmt (); }
| '{' maybe_label_decls stmts '}'
{ finish_stmt (); }
| '{' maybe_label_decls error '}'
{ finish_stmt (); }
| simple_stmt
;
nontrivial_exprlist: nontrivial_exprlist:
expr_no_commas ',' expr_no_commas expr_no_commas ',' expr_no_commas
{ $$ = tree_cons (NULL_TREE, $$, { $$ = tree_cons (NULL_TREE, $$,
...@@ -1414,10 +1417,18 @@ primary: ...@@ -1414,10 +1417,18 @@ primary:
} }
} }
| functional_cast | functional_cast
/* Stroustrup RTTI */
| DYNAMIC_CAST '<' type_id '>' '(' expr ')' | DYNAMIC_CAST '<' type_id '>' '(' expr ')'
{ tree type = groktypename ($3); { tree type = groktypename ($3);
$$ = build_dynamic_cast (type, $6); } $$ = build_dynamic_cast (type, $6); }
| STATIC_CAST '<' type_id '>' '(' expr ')'
{ tree type = groktypename ($3);
$$ = build_static_cast (type, $6); }
| REINTERPRET_CAST '<' type_id '>' '(' expr ')'
{ tree type = groktypename ($3);
$$ = build_reinterpret_cast (type, $6); }
| CONST_CAST '<' type_id '>' '(' expr ')'
{ tree type = groktypename ($3);
$$ = build_const_cast (type, $6); }
| TYPEID '(' expr ')' | TYPEID '(' expr ')'
{ $$ = build_typeid ($3); } { $$ = build_typeid ($3); }
| TYPEID '(' type_id ')' | TYPEID '(' type_id ')'
...@@ -2168,8 +2179,8 @@ specialization: ...@@ -2168,8 +2179,8 @@ specialization:
aggr template_type_name ';' aggr template_type_name ';'
{ {
yyungetc (';', 1); current_aggr = $$; $$ = $2; yyungetc (';', 1); current_aggr = $$; $$ = $2;
if (doing_explicit) if ($<ttype>0 == ridpointers[(int) RID_TEMPLATE])
instantiate_class_template ($$, 1); instantiate_class_template ($$, 2);
} }
; ;
...@@ -2644,13 +2655,9 @@ enumerator: ...@@ -2644,13 +2655,9 @@ enumerator:
/* ANSI new-type-id (5.3.4) */ /* ANSI new-type-id (5.3.4) */
new_type_id: new_type_id:
typed_typespecs new_declarator type_specifier_seq new_declarator
{ $$ = build_decl_list ($$, $2); }
| nonempty_type_quals new_declarator
{ $$ = build_decl_list ($$, $2); } { $$ = build_decl_list ($$, $2); }
| typed_typespecs %prec EMPTY | type_specifier_seq %prec EMPTY
{ $$ = build_decl_list ($$, NULL_TREE); }
| nonempty_type_quals %prec EMPTY
{ $$ = build_decl_list ($$, NULL_TREE); } { $$ = build_decl_list ($$, NULL_TREE); }
/* GNU extension to allow arrays of arbitrary types with /* GNU extension to allow arrays of arbitrary types with
non-constant dimension. */ non-constant dimension. */
...@@ -3100,7 +3107,7 @@ simple_stmt: ...@@ -3100,7 +3107,7 @@ simple_stmt:
cond_stmt_keyword = "while"; } cond_stmt_keyword = "while"; }
.pushlevel paren_cond_or_null .pushlevel paren_cond_or_null
{ expand_exit_loop_if_false (0, truthvalue_conversion ($4)); } { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
implicitly_scoped_stmt already_scoped_stmt
{ expand_end_bindings (getdecls (), kept_level_p (), 1); { expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
pop_momentary (); pop_momentary ();
...@@ -3131,14 +3138,14 @@ simple_stmt: ...@@ -3131,14 +3138,14 @@ simple_stmt:
/* Don't let the tree nodes for $7 be discarded /* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */ by clear_momentary during the parsing of the next stmt. */
{ push_momentary (); } { push_momentary (); }
implicitly_scoped_stmt already_scoped_stmt
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
expand_loop_continue_here ();
if ($7) cplus_expand_expr_stmt ($7);
pop_momentary ();
expand_end_bindings (getdecls (), kept_level_p (), 1); expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
pop_momentary (); pop_momentary ();
expand_loop_continue_here ();
if ($7) cplus_expand_expr_stmt ($7);
pop_momentary ();
expand_end_loop (); expand_end_loop ();
finish_stmt (); } finish_stmt (); }
| forhead.2 | forhead.2
...@@ -3153,14 +3160,14 @@ simple_stmt: ...@@ -3153,14 +3160,14 @@ simple_stmt:
by clear_momentary during the parsing of the next stmt. */ by clear_momentary during the parsing of the next stmt. */
{ push_momentary (); { push_momentary ();
$<itype>8 = lineno; } $<itype>8 = lineno; }
implicitly_scoped_stmt already_scoped_stmt
{ emit_line_note (input_filename, (int) $<itype>8); { emit_line_note (input_filename, (int) $<itype>8);
expand_loop_continue_here ();
if ($7) cplus_expand_expr_stmt ($7);
pop_momentary ();
expand_end_bindings (getdecls (), kept_level_p (), 1); expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
pop_momentary (); pop_momentary ();
expand_loop_continue_here ();
if ($7) cplus_expand_expr_stmt ($7);
pop_momentary ();
expand_end_loop (); expand_end_loop ();
finish_stmt (); finish_stmt ();
} }
...@@ -3422,11 +3429,6 @@ ansi_try_stmts: ...@@ -3422,11 +3429,6 @@ ansi_try_stmts:
} }
; ;
optional_identifier:
/* empty */
{ $$ = NULL_TREE; }
| identifier ;
handler_seq: handler_seq:
/* empty */ /* empty */
| handler_seq CATCH | handler_seq CATCH
...@@ -3435,10 +3437,21 @@ handler_seq: ...@@ -3435,10 +3437,21 @@ handler_seq:
{ expand_end_catch_block (); } { expand_end_catch_block (); }
; ;
type_specifier_seq:
typed_typespecs %prec EMPTY
| nonempty_type_quals %prec EMPTY
;
handler_args: handler_args:
'(' ELLIPSIS ')' '(' ELLIPSIS ')'
{ expand_start_catch_block (NULL_TREE, NULL_TREE); } { expand_start_catch_block (NULL_TREE, NULL_TREE); }
| '(' type_id optional_identifier ')' | '(' type_specifier_seq absdcl ')'
{ expand_start_catch_block ($2, $3); }
| '(' type_specifier_seq ')'
{ expand_start_catch_block ($2, NULL_TREE); }
| '(' type_specifier_seq notype_declarator ')'
{ expand_start_catch_block ($2, $3); }
| '(' typed_typespecs after_type_declarator ')'
{ expand_start_catch_block ($2, $3); } { expand_start_catch_block ($2, $3); }
; ;
...@@ -3704,33 +3717,11 @@ maybe_raises: ...@@ -3704,33 +3717,11 @@ maybe_raises:
{ $$ = $3; } { $$ = $3; }
; ;
raise_identifier:
/* ALL
{ $$ = void_list_node; } */
IDENTIFIER
{ $$ = build_decl_list (NULL_TREE, $$); }
| TYPENAME
{ $$ = build_decl_list (NULL_TREE, $$); }
| global_scope IDENTIFIER
{ $$ = build_decl_list (NULL_TREE, $2); }
| global_scope TYPENAME
{ $$ = build_decl_list (NULL_TREE, $2); }
;
ansi_raise_identifier: ansi_raise_identifier:
type_id type_id
{ $$ = build_decl_list (NULL_TREE, $$); } { $$ = build_decl_list (NULL_TREE, $$); }
; ;
raise_identifiers:
raise_identifier
| raise_identifiers ',' raise_identifier
{
TREE_CHAIN ($3) = $$;
$$ = $3;
}
;
ansi_raise_identifiers: ansi_raise_identifiers:
ansi_raise_identifier ansi_raise_identifier
| ansi_raise_identifiers ',' ansi_raise_identifier | ansi_raise_identifiers ',' ansi_raise_identifier
...@@ -3825,7 +3816,7 @@ operator_name: ...@@ -3825,7 +3816,7 @@ operator_name:
| operator DELETE '[' ']' | operator DELETE '[' ']'
{ $$ = ansi_opname[VEC_DELETE_EXPR]; } { $$ = ansi_opname[VEC_DELETE_EXPR]; }
/* Names here should be looked up in class scope ALSO. */ /* Names here should be looked up in class scope ALSO. */
| operator typed_typespecs conversion_declarator | operator type_specifier_seq conversion_declarator
{ $$ = grokoptypename ($2, $3); } { $$ = grokoptypename ($2, $3); }
| operator error | operator error
{ $$ = ansi_opname[ERROR_MARK]; } { $$ = ansi_opname[ERROR_MARK]; }
......
...@@ -265,12 +265,16 @@ end_template_decl (d1, d2, is_class, defn) ...@@ -265,12 +265,16 @@ end_template_decl (d1, d2, is_class, defn)
&& DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE) && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
{ {
tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)); tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl));
tree tmpl; tree tmpl, t;
my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266); my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266);
tmpl = UPT_TEMPLATE (ctx); tmpl = UPT_TEMPLATE (ctx);
for (t = DECL_TEMPLATE_MEMBERS (tmpl); t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t) == DECL_NAME (decl)
&& duplicate_decls (decl, TREE_VALUE (t)))
goto already_there;
DECL_TEMPLATE_MEMBERS (tmpl) = DECL_TEMPLATE_MEMBERS (tmpl) =
perm_tree_cons (DECL_NAME (decl), decl, perm_tree_cons (DECL_NAME (decl), decl, DECL_TEMPLATE_MEMBERS (tmpl));
DECL_TEMPLATE_MEMBERS (tmpl)); already_there:
poplevel (0, 0, 0); poplevel (0, 0, 0);
poplevel (0, 0, 0); poplevel (0, 0, 0);
} }
...@@ -1459,6 +1463,9 @@ tsubst (t, args, nargs, in_decl) ...@@ -1459,6 +1463,9 @@ tsubst (t, args, nargs, in_decl)
layout_type (r); layout_type (r);
return r; return r;
} }
case OFFSET_TYPE:
return build_offset_type
(tsubst (TYPE_OFFSET_BASETYPE (t), args, nargs, in_decl), type);
case FUNCTION_TYPE: case FUNCTION_TYPE:
case METHOD_TYPE: case METHOD_TYPE:
{ {
...@@ -2008,10 +2015,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2008,10 +2015,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if (targs[idx] == arg) if (targs[idx] == arg)
return 0; return 0;
else if (targs[idx]) else if (targs[idx])
return 1; {
if (TYPE_MAIN_VARIANT (targs[idx]) == TYPE_MAIN_VARIANT (arg))
/* allow different parms to have different cv-qualifiers */;
else
return 1;
}
/* Check for mixed types and values. */ /* Check for mixed types and values. */
if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE) if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
return 1; return 1;
/* Allow trivial conversions. */
if (TYPE_READONLY (parm) < TYPE_READONLY (arg)
|| TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
return 1;
targs[idx] = arg; targs[idx] = arg;
return 0; return 0;
case TEMPLATE_CONST_PARM: case TEMPLATE_CONST_PARM:
...@@ -2136,8 +2152,12 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2136,8 +2152,12 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm), return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, nsubsts); arg, nsubsts);
/* Unification of something that is not a template fails. (mrs) */ /* Allow trivial conversions. */
return 1; if (TYPE_MAIN_VARIANT (parm) != TYPE_MAIN_VARIANT (arg)
|| TYPE_READONLY (parm) < TYPE_READONLY (arg)
|| TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
return 1;
return 0;
case METHOD_TYPE: case METHOD_TYPE:
if (TREE_CODE (arg) != METHOD_TYPE) if (TREE_CODE (arg) != METHOD_TYPE)
...@@ -2150,7 +2170,16 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2150,7 +2170,16 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
check_args: check_args:
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);
case OFFSET_TYPE:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, ntparms, TYPE_OFFSET_BASETYPE (parm),
TYPE_OFFSET_BASETYPE (arg), nsubsts))
return 1;
return unify (tparms, targs, ntparms, TREE_TYPE (parm),
TREE_TYPE (arg), nsubsts);
default: default:
sorry ("use of `%s' in template type unification", sorry ("use of `%s' in template type unification",
tree_code_name [(int) TREE_CODE (parm)]); tree_code_name [(int) TREE_CODE (parm)]);
......
...@@ -1134,7 +1134,7 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1134,7 +1134,7 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr && protect) if (errstr && protect)
{ {
error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type)); cp_error (errstr, name, type);
return error_mark_node; return error_mark_node;
} }
return rval; return rval;
......
...@@ -94,9 +94,6 @@ lvalue_p (ref) ...@@ -94,9 +94,6 @@ lvalue_p (ref)
return (lvalue_p (TREE_OPERAND (ref, 1)) return (lvalue_p (TREE_OPERAND (ref, 1))
&& lvalue_p (TREE_OPERAND (ref, 2))); && lvalue_p (TREE_OPERAND (ref, 2)));
case MODIFY_EXPR:
return 1;
case COMPOUND_EXPR: case COMPOUND_EXPR:
return lvalue_p (TREE_OPERAND (ref, 1)); return lvalue_p (TREE_OPERAND (ref, 1));
} }
......
...@@ -47,7 +47,6 @@ static tree pointer_int_sum (); ...@@ -47,7 +47,6 @@ static tree pointer_int_sum ();
static tree pointer_diff (); static tree pointer_diff ();
static tree convert_sequence (); static tree convert_sequence ();
/* static */ tree unary_complex_lvalue (); /* static */ tree unary_complex_lvalue ();
static void pedantic_lvalue_warning ();
tree truthvalue_conversion (); tree truthvalue_conversion ();
extern rtx original_result_rtx; extern rtx original_result_rtx;
...@@ -223,10 +222,7 @@ commonparms (p1, p2) ...@@ -223,10 +222,7 @@ commonparms (p1, p2)
if (cmp < 0) if (cmp < 0)
my_friendly_abort (111); my_friendly_abort (111);
if (cmp == 0) if (cmp == 0)
{ any_change = 1;
error ("redeclaration of default argument %d", i+1);
any_change = 1;
}
TREE_PURPOSE (n) = TREE_PURPOSE (p2); TREE_PURPOSE (n) = TREE_PURPOSE (p2);
} }
if (TREE_VALUE (p1) != TREE_VALUE (p2)) if (TREE_VALUE (p1) != TREE_VALUE (p2))
...@@ -411,7 +407,7 @@ common_type (t1, t2) ...@@ -411,7 +407,7 @@ common_type (t1, t2)
return t1; return t1;
case METHOD_TYPE: case METHOD_TYPE:
if (TYPE_METHOD_BASETYPE (t1) == TYPE_METHOD_BASETYPE (t2) if (comptypes (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2), 1)
&& TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))) && TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))
{ {
/* Get this value the long way, since TYPE_METHOD_BASETYPE /* Get this value the long way, since TYPE_METHOD_BASETYPE
...@@ -642,6 +638,9 @@ comptypes (type1, type2, strict) ...@@ -642,6 +638,9 @@ comptypes (type1, type2, strict)
case TEMPLATE_TYPE_PARM: case TEMPLATE_TYPE_PARM:
return 1; return 1;
case UNINSTANTIATED_P_TYPE:
return UPT_TEMPLATE (t1) == UPT_TEMPLATE (t2);
} }
return 0; return 0;
} }
...@@ -1340,9 +1339,10 @@ build_object_ref (datum, basetype, field) ...@@ -1340,9 +1339,10 @@ build_object_ref (datum, basetype, field)
else if (is_aggr_typedef (basetype, 1)) else if (is_aggr_typedef (basetype, 1))
{ {
tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype); tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype);
if (binfo_or_else (real_basetype, TREE_TYPE (datum))) tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));
if (binfo)
return build_component_ref (build_scoped_ref (datum, basetype), return build_component_ref (build_scoped_ref (datum, basetype),
field, NULL_TREE, 1); field, binfo, 1);
} }
return error_mark_node; return error_mark_node;
} }
...@@ -3006,12 +3006,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3006,12 +3006,14 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
; ;
else if (tt0 == void_type_node) else if (tt0 == void_type_node)
{ {
if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE) if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE
&& tree_int_cst_lt (TYPE_SIZE (type0), TYPE_SIZE (type1)))
pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer"); pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
} }
else if (tt1 == void_type_node) else if (tt1 == void_type_node)
{ {
if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE) if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE
&& tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0)))
pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer"); pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
} }
else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0)) else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
...@@ -3457,13 +3459,6 @@ pointer_int_sum (resultcode, ptrop, intop) ...@@ -3457,13 +3459,6 @@ pointer_int_sum (resultcode, ptrop, intop)
register tree result_type = TREE_TYPE (ptrop); register tree result_type = TREE_TYPE (ptrop);
/* Needed to make OOPS V2R3 work. */
intop = folded;
if (TREE_CODE (intop) == INTEGER_CST
&& TREE_INT_CST_LOW (intop) == 0
&& TREE_INT_CST_HIGH (intop) == 0)
return ptrop;
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{ {
if (pedantic || warn_pointer_arith) if (pedantic || warn_pointer_arith)
...@@ -3491,6 +3486,13 @@ pointer_int_sum (resultcode, ptrop, intop) ...@@ -3491,6 +3486,13 @@ pointer_int_sum (resultcode, ptrop, intop)
else else
size_exp = size_in_bytes (TREE_TYPE (result_type)); size_exp = size_in_bytes (TREE_TYPE (result_type));
/* Needed to make OOPS V2R3 work. */
intop = folded;
if (TREE_CODE (intop) == INTEGER_CST
&& TREE_INT_CST_LOW (intop) == 0
&& TREE_INT_CST_HIGH (intop) == 0)
return ptrop;
/* If what we are about to multiply by the size of the elements /* If what we are about to multiply by the size of the elements
contains a constant term, apply distributive law contains a constant term, apply distributive law
and multiply that constant term separately. and multiply that constant term separately.
...@@ -3882,7 +3884,6 @@ build_unary_op (code, xarg, noconvert) ...@@ -3882,7 +3884,6 @@ build_unary_op (code, xarg, noconvert)
case FIX_CEIL_EXPR: case FIX_CEIL_EXPR:
{ {
tree incremented, modify, value; tree incremented, modify, value;
pedantic_lvalue_warning (CONVERT_EXPR);
arg = stabilize_reference (arg); arg = stabilize_reference (arg);
if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
value = arg; value = arg;
...@@ -4158,17 +4159,18 @@ unary_complex_lvalue (code, arg) ...@@ -4158,17 +4159,18 @@ unary_complex_lvalue (code, arg)
if (TREE_CODE (arg) == COMPOUND_EXPR) if (TREE_CODE (arg) == COMPOUND_EXPR)
{ {
tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
pedantic_lvalue_warning (COMPOUND_EXPR);
return build (COMPOUND_EXPR, TREE_TYPE (real_result), return build (COMPOUND_EXPR, TREE_TYPE (real_result),
TREE_OPERAND (arg, 0), real_result); TREE_OPERAND (arg, 0), real_result);
} }
/* Handle (a ? b : c) used as an "lvalue". */ /* Handle (a ? b : c) used as an "lvalue". */
if (TREE_CODE (arg) == COND_EXPR) if (TREE_CODE (arg) == COND_EXPR)
{ return rationalize_conditional_expr (code, arg);
pedantic_lvalue_warning (COND_EXPR);
return rationalize_conditional_expr (code, arg); if (TREE_CODE (arg) == MODIFY_EXPR)
} return unary_complex_lvalue
(code, build (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (arg, 0)),
arg, TREE_OPERAND (arg, 0)));
if (code != ADDR_EXPR) if (code != ADDR_EXPR)
return 0; return 0;
...@@ -4295,19 +4297,6 @@ unary_complex_lvalue (code, arg) ...@@ -4295,19 +4297,6 @@ unary_complex_lvalue (code, arg)
/* Don't let anything else be handled specially. */ /* Don't let anything else be handled specially. */
return 0; return 0;
} }
/* If pedantic, warn about improper lvalue. CODE is either COND_EXPR
COMPOUND_EXPR, or CONVERT_EXPR (for casts). */
static void
pedantic_lvalue_warning (code)
enum tree_code code;
{
if (pedantic)
pedwarn ("ANSI C++ forbids use of %s expressions as lvalues",
code == COND_EXPR ? "conditional"
: code == COMPOUND_EXPR ? "compound" : "cast");
}
/* Mark EXP saying that we need to be able to take the /* Mark EXP saying that we need to be able to take the
address of it; it should not be allocated in a register. address of it; it should not be allocated in a register.
...@@ -4785,6 +4774,24 @@ build_compound_expr (list) ...@@ -4785,6 +4774,24 @@ build_compound_expr (list)
break_out_cleanups (TREE_VALUE (list)), rest); break_out_cleanups (TREE_VALUE (list)), rest);
} }
tree build_static_cast (type, expr)
tree type, expr;
{
return build_c_cast (type, expr);
}
tree build_reinterpret_cast (type, expr)
tree type, expr;
{
return build_c_cast (type, expr);
}
tree build_const_cast (type, expr)
tree type, expr;
{
return build_c_cast (type, expr);
}
/* Build an expression representing a cast to type TYPE of expression EXPR. */ /* Build an expression representing a cast to type TYPE of expression EXPR. */
tree tree
...@@ -5294,7 +5301,6 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -5294,7 +5301,6 @@ build_modify_expr (lhs, modifycode, rhs)
/* Handle (a, b) used as an "lvalue". */ /* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR: case COMPOUND_EXPR:
pedantic_lvalue_warning (COMPOUND_EXPR);
newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
modifycode, rhs); modifycode, rhs);
if (TREE_CODE (newrhs) == ERROR_MARK) if (TREE_CODE (newrhs) == ERROR_MARK)
...@@ -5302,9 +5308,14 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -5302,9 +5308,14 @@ build_modify_expr (lhs, modifycode, rhs)
return build (COMPOUND_EXPR, lhstype, return build (COMPOUND_EXPR, lhstype,
TREE_OPERAND (lhs, 0), newrhs); TREE_OPERAND (lhs, 0), newrhs);
case MODIFY_EXPR:
newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
/* Handle (a ? b : c) used as an "lvalue". */ /* Handle (a ? b : c) used as an "lvalue". */
case COND_EXPR: case COND_EXPR:
pedantic_lvalue_warning (COND_EXPR);
rhs = save_expr (rhs); rhs = save_expr (rhs);
{ {
/* Produce (a ? (b = rhs) : (c = rhs)) /* Produce (a ? (b = rhs) : (c = rhs))
...@@ -5450,7 +5461,7 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -5450,7 +5461,7 @@ build_modify_expr (lhs, modifycode, rhs)
convert (lhstype, newrhs))); convert (lhstype, newrhs)));
if (TREE_CODE (result) == ERROR_MARK) if (TREE_CODE (result) == ERROR_MARK)
return result; return result;
return convert (TREE_TYPE (lhs), result); return convert_force (TREE_TYPE (lhs), result);
} }
} }
...@@ -6559,9 +6570,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) ...@@ -6559,9 +6570,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
return here before checking if RHS is of complete type. */ return here before checking if RHS is of complete type. */
if (codel == REFERENCE_TYPE) if (codel == REFERENCE_TYPE)
return convert_to_reference ((exp ? exp : error_mark_node), return convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
type, rhs, fndecl, parmnum, errtype, exp ? exp : error_mark_node);
0, flags);
rhs = require_complete_type (rhs); rhs = require_complete_type (rhs);
if (rhs == error_mark_node) if (rhs == error_mark_node)
......
...@@ -59,7 +59,7 @@ binfo_or_else (parent_or_type, type) ...@@ -59,7 +59,7 @@ binfo_or_else (parent_or_type, type)
{ {
tree binfo; tree binfo;
if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type)) if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type))
return parent_or_type; return TYPE_BINFO (parent_or_type);
if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0))) if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0)))
{ {
if (binfo == error_mark_node) if (binfo == error_mark_node)
...@@ -738,7 +738,10 @@ digest_init (type, init, tail) ...@@ -738,7 +738,10 @@ digest_init (type, init, tail)
return error_mark_node; return error_mark_node;
} }
if (pedantic && typ1 != char_type_node) if (pedantic
&& typ1 != char_type_node
&& typ1 != signed_char_type_node
&& typ1 != unsigned_char_type_node)
pedwarn ("ANSI C++ forbids string initializer except for `char' elements"); pedwarn ("ANSI C++ forbids string initializer except for `char' elements");
TREE_TYPE (string) = type; TREE_TYPE (string) = type;
if (TYPE_DOMAIN (type) != 0 if (TYPE_DOMAIN (type) != 0
...@@ -752,7 +755,7 @@ digest_init (type, init, tail) ...@@ -752,7 +755,7 @@ digest_init (type, init, tail)
counted in the length of the constant, but in C++ this would counted in the length of the constant, but in C++ this would
be invalid. */ be invalid. */
if (size < TREE_STRING_LENGTH (string)) if (size < TREE_STRING_LENGTH (string))
warning ("initializer-string for array of chars is too long"); pedwarn ("initializer-string for array of chars is too long");
} }
return string; return string;
} }
......
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